0

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.

Michel
  • 10,303
  • 17
  • 82
  • 179

0 Answers0