I am working on a NextJS small app, called njs-voice-rcd, where I want to upload some voice recording made by the user to a mongo DB using GridFS. At this point I have the voice recording part already working as expected. But (after various trials) I can't figure out the correct way to upload the audio blob that I have to GridFS. Any relevant tip would by highly appreciated.
This is how I started making the app:
% npx create-next-app@latest
...
% cd njs-voice-rcd
% npm i mongoose gridfs-stream node-fetch
% npm i @types/gridfs-stream
This is the function executed when a voice recording ends:
const stopRecording = () => {
setRecordingStatus("inactive");
if (!mrRef.current) return
mrRef.current?.stop();
mrRef.current.onstop = async () => {
const audioBlob = new Blob(audioChunksRef.current, {
type: mimeType});
const audioUrl = URL.createObjectURL(audioBlob);
setAudio(audioUrl);
//TRY-THIS
const formData = new FormData();
formData.append('audio', audioBlob); // Replace with the actual blob
try {
const response = await fetch('/api/UPLA', {
method: 'POST',
body: JSON.stringify(formData),
});
const data = await response.json();
//console.log('File ID:', data.fileId);
} catch (error) {
console.error('Upload error:', error);
}
//TRY-THIS
};
}; /* End of stopRecording */
I also have an API route (UPLA) called from stopRecording (above) to perform the audio data upload. This is the file app/api/UPLA/route.ts :
import Grid from 'gridfs-stream';
import mongoose from 'mongoose';
import { Readable } from 'stream';
mongoose.connect(process.env.NEXT_PUBLIC_MDB_URI_AUDIO!);
let gfs:Grid.Grid;
mongoose.connection.once('open', () => {
// Initialize GridFS stream
gfs = Grid(mongoose.connection.db, mongoose.mongo);
gfs.collection('uploads');
});
// export default async (req, res) => {
export default async (req: { method: string; body: { audio: Iterable<any> | AsyncIterable<any>; }; }, res: { status: (arg0: number) => { (): any; new(): any; end: { (): any; new(): any; }; json: { (arg0: { message: string; }): void; new(): any; }; }; json: (arg0: { fileId: any; }) => void; }) => {
if (req.method !== 'POST') {
return res.status(405).end(); // Method Not Allowed
}
try {
if (!req.body.audio) {
return res.status(400).json({ message: 'No audio data uploaded.' });
}
// Create a writable stream to upload audio to GridFS
const writeStream = gfs.createWriteStream({
filename: 'uploaded_audio.wav', // Set the desired filename
});
// Pipe the audio data from the request to the write stream
const readableStream = Readable.from(req.body.audio);
readableStream.pipe(writeStream);
writeStream.on('close', (file) => {
const fileId = file._id;
// Handle other metadata or operations here
res.json({ fileId });
});
} catch (error) {
console.error(error);
res.status(500).json({ message: 'An error occurred during upload.' });
}
};
When running this command:
% git push heroku main
I get these errors:
remote: -----> Build
remote: Running build
remote:
remote: > njs-voice-rcd-4@0.1.0 build
remote: > next build
remote:
remote: - info Loaded env from /tmp/build_08a5c4fb/.env
remote: - warn No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
remote: Attention: Next.js now collects completely anonymous telemetry regarding usage.
remote: This information is used to shape Next.js' roadmap and prioritize features.
remote: You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
remote: https://nextjs.org/telemetry
remote:
remote: - info Creating an optimized production build...
remote: Failed to compile.
remote:
remote: node:buffer
remote: Module build failed: UnhandledSchemeError: Reading from "node:buffer" is not handled by plugins (Unhandled scheme).
remote: Webpack supports "data:" and "file:" URIs by default.
remote: You may need an additional plugin to handle "node:" URIs.
remote: at /tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:399772
remote: at Hook.eval [as callAsync] (eval at create (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:13:28867), <anonymous>:6:1)
remote: at Object.processResource (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:399697)
remote: at processResource (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/loader-runner/LoaderRunner.js:1:5308)
remote: at iteratePitchingLoaders (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/loader-runner/LoaderRunner.js:1:4667)
remote: at runLoaders (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/loader-runner/LoaderRunner.js:1:8590)
remote: at NormalModule._doBuild (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:399559)
remote: at NormalModule.build (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:401587)
remote: at /tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:81981
remote: at NormalModule.needBuild (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:405663)
remote:
remote: Import trace for requested module:
remote: node:buffer
remote: ./node_modules/node-fetch/src/index.js
remote: ./app/components/AudioRecorder.tsx
remote:
remote: node:fs
remote: Module build failed: UnhandledSchemeError: Reading from "node:fs" is not handled by plugins (Unhandled scheme).
remote: Webpack supports "data:" and "file:" URIs by default.
remote: You may need an additional plugin to handle "node:" URIs.
remote: at /tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:399772
remote: at Hook.eval [as callAsync] (eval at create (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:13:28867), <anonymous>:6:1)
remote: at Object.processResource (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:399697)
remote: at processResource (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/loader-runner/LoaderRunner.js:1:5308)
remote: at iteratePitchingLoaders (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/loader-runner/LoaderRunner.js:1:4667)
remote: at runLoaders (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/loader-runner/LoaderRunner.js:1:8590)
remote: at NormalModule._doBuild (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:399559)
remote: at NormalModule.build (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:401587)
remote: at /tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:81981
remote: at NormalModule.needBuild (/tmp/build_08a5c4fb/node_modules/next/dist/compiled/webpack/bundle5.js:28:405663)
remote:
remote: Import trace for requested module:
remote: node:fs
remote: ./node_modules/fetch-blob/from.js
remote: ./node_modules/node-fetch/src/index.js
remote: ./app/components/AudioRecorder.tsx
remote:
remote: node:https
...................
It seems like there are some conflicts. But though I spent time searching the net I haven't found any solution at this point.