Created
February 8, 2024 12:49
-
-
Save jordonmckoy/59c65046dfabd3f03c51d51c839421ac to your computer and use it in GitHub Desktop.
File upload to Google Cloud Storage (GCS) in Next.js 14 API Route
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use client" | |
export default function AudioRecorder() { | |
const [audioBlob, setAudioBlob] = useState<Blob | null>(null); | |
// ...app code omitted | |
const uploadAudio = async () => { | |
if (!audioBlob) { | |
throw new Error("No audio to upload"); | |
} | |
// Prepare FormData | |
let formData = new FormData(); | |
const timestamp = Date.now(); | |
// Append the audio blob to the FormData object. You might want to give it a filename. | |
formData.append("audio", audioBlob, `${timestamp}.webm`); | |
// Setup the fetch request options | |
const requestOptions: RequestInit = { | |
method: "POST", | |
body: formData, | |
}; | |
// Send the request to your API endpoint | |
try { | |
const response = await fetch("/api/upload", requestOptions); | |
if (!response.ok) throw new Error("Failed to upload"); | |
const data = await response.json(); | |
console.log("Upload successful:", data); | |
} catch (error) { | |
console.error("Error uploading audio:", error); | |
} | |
}; | |
return ( | |
<div className="audio-container"> | |
<form id="uploadForm"> | |
<input type="file" id="fileInput" multiple /> | |
<button type="button" onClick={uploadAudio}> | |
Upload | |
</button> | |
</form> | |
</div> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// api/upload/route.ts | |
export const POST = async (req: Request, res: Response) => { | |
try { | |
const data = await req.formData(); | |
const file = data.get("audio") as File; | |
if (!file || typeof file === "string") { | |
throw new Error("Audio file not found"); | |
} | |
const filePath = file?.name; | |
const storage = new Storage({ | |
projectId: `${GCP_PROJECT_ID}`, | |
credentials: { | |
client_email: `${GCP_SERVICE_ACCOUNT_EMAIL}`, | |
private_key: `${GCP_PRIVATE_KEY}`, | |
}, | |
}); | |
const bucket = storage.bucket(`${GCP_BUCKET_NAME}`); | |
const bytes = await file.arrayBuffer(); | |
const buffer = Buffer.from(bytes); | |
// Wrap the upload logic in a promise | |
await new Promise((resolve, reject) => { | |
const blob = bucket.file(filePath); | |
const blobStream = blob.createWriteStream({ | |
resumable: false, | |
}); | |
blobStream | |
.on("error", (err) => reject(err)) | |
.on("finish", () => resolve(true)); | |
blobStream.end(buffer); | |
}); | |
return new NextResponse(JSON.stringify({ success: true })); | |
} catch (error) { | |
return new NextResponse(JSON.stringify(error), { status: 500 }); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment