Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get last timeSlice blob from a streamed wav file #752

Open
scotfang opened this issue Jun 24, 2021 · 5 comments
Open

Can't get last timeSlice blob from a streamed wav file #752

scotfang opened this issue Jun 24, 2021 · 5 comments

Comments

@scotfang
Copy link

Hi, thanks for creating and maintaining this awesome tool! I have a feature request, or maybe there is a way to do this and I just don't know how.

Per code below, I am streaming a wav file to RecordRTC, and calling ondataavailable's callback every 300ms. This all works fine, except that I'm pretty sure the very last timeSlice before the wav file ends does not trigger ondataavailable's callback, because the last timeSlice is shorter than 300ms perhaps.

As a workaround, I tried using getBlobl() inside recordRTC.stopRecording(), but that returns the entire blob, not just the last timeSlice. That doesn't help me much, because I want to measure real-time streaming metrics with my application through 300ms (or less) blobs.

Is there any way to retrieve the last timeSlice's blob of a stream when it ends? Thanks!!

    const audio = new Audio( wav_file );
    let stream = audio.captureStream();
    console.log("got stream")
    const recordRTC = RecordRTC(stream, {
      type: "audio",
      mimeType: "audio/wav",
      recorderType: RecordRTC.StereoAudioRecorder,
      bufferSize: 2048,
      desiredSampRate: 16000,
      numberOfAudioChannels: 1,
      timeSlice: 300,
      ondataavailable: this.onAudioData,
      disableLogs: true,
    })
    audio.onended = (event) => {
      console.log('audio ended');
      recordRTC.stopRecording(() => {
          let blob = recordRTC.getBlob();
          this.onAudioData(blob)
      });
    };
    audio.play().then(() => {
      recordRTC.startRecording();
    })
@sahilmcompro
Copy link

sahilmcompro commented Aug 4, 2021

Hi @scotfang, I am facing this exact problem right now (except the stream in my case is User Mic and timeslice interval is 5000, which don't matter, I hope). So I want to know if you found any solution/workaround for this?

I tried to research about it a bit but didn't find any solutions, however, on stack overflow, it is recommended to use Stop & Start.

Thanks!

@scotfang
Copy link
Author

scotfang commented Aug 4, 2021 via email

@lukemtl
Copy link

lukemtl commented Aug 11, 2021

I was able to get it by using the Blob.slice() method and tracking the total size of all the blobs that I got from ondataavailable.

Globally:

let sizeOnDataAvailable = 0;

Then in your code where you handle dataavailable events:

ondataavailable: function(blob) {      
   // your code for handling the blob chunk here, and then concatenate the size...
             
    sizeOnDataAvailable += blob.size;
}

Then, when you call stopRecording, to get the last blob you can have this callback:

recordAudio.stopRecording( () => {
      blob = recordAudio.getBlob();           //this is the entire recording

      var endBlob = blob.slice(sizeOnDataAvailable, blob.size, 'audio/wav');   
     //this is the last chunk; add code here to handle it
           
     sizeOnDataAvailable = 0; 
 });

Hope it works for people!

EDIT make sure to reset the size tracking variable if you want to repeat the process (added in the code)

@sahilmcompro
Copy link

Hi @lukemtl,

The above is a good workaround, but it doesn't work with large recordings (around half hour) on low-end mobile devices. I started the whole timeslice thing because generating the whole blob at the end was the cause of the crash.

@AlbaChloe
Copy link

I was able to get it by using the Blob.slice() method and tracking the total size of all the blobs that I got from ondataavailable.

Globally:

let sizeOnDataAvailable = 0;

Then in your code where you handle dataavailable events:

ondataavailable: function(blob) {      
   // your code for handling the blob chunk here, and then concatenate the size...
             
    sizeOnDataAvailable += blob.size;
}

Then, when you call stopRecording, to get the last blob you can have this callback:

recordAudio.stopRecording( () => {
      blob = recordAudio.getBlob();           //this is the entire recording

      var endBlob = blob.slice(sizeOnDataAvailable, blob.size, 'audio/wav');   
     //this is the last chunk; add code here to handle it
           
     sizeOnDataAvailable = 0; 
 });

Hope it works for people!

EDIT make sure to reset the size tracking variable if you want to repeat the process (added in the code)

thanks a lot! this saved me🥳🥳caz i got undefined from getArrayOfBlobs of getInternalRecorder(), probably beacause my recorderType is set to be StereoAudioRecorder, and if i use MediaStreamRecorder, getArrayOfBlobs will work well, but i need wav file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants