简体   繁体   中英

React.js - audio.duration returns NaN & How to upload blobUrl to amazon s3

I'm using the react component ReactMediaRecorder to capture audio using the following code. it returns a blobUrl which I have set in my state.

<ReactMediaRecorder  
  audio
  whenStopped={blobUrl=>this.setState({ blobUrl })}
  render={({ status, startRecording, stopRecording, mediaBlob }) => (
    <div>
      <p>{status}</p>
      <button onClick={startRecording}>Start Recording</button>  
      <button onClick={stopRecording}>Stop Recording</button>  
      <audio src={mediaBlob} controls />  
    </div>  
  )}  
/> 

My First Question is Why does audio.play() works but audio.duration returns NaN ?

let audio = new Audio(mediaBlob);
audio.play(); // this works
audio.duration //but this returns NaN

Second, I want to upload this audio to my amazon s3 storage using rest-api. Is there any other way to convert this blobUrl to audio and then upload it to s3 storage ?

My First Question is Why does audio.play() works but audio.duration returns NaN ?

You need to wait until the Audio object has loaded some of the data before you'll be able to fetch the duration.

audio.addEventListener('loadedmetadata', (e) => {
  console.log(e.target.duration);
});

Additionally, the duration may be unreliable... there are some issues with browser implementations of MediaRecorder where the length can't be reliably set if the output is streamed in chunks.

Second, I want to upload this audio to my amazon s3 storage using rest-api. Is there any other way to convert this blobUrl to audio and then upload it to s3 storage ?

Use the Blob instance itself as the request body. Don't use the blob URL. Don't forget to set your Content-Type headers.

You may try like this:

let duration, retry;
const limit = 50;
function getDuration(audio) {
  if(audio.duration > 0){
    duration = audio.duration;
    return;
  }
  if(retry > limit) { return }
  setTimeout(() => {
    retry++;
    getDuration(audio)
  }, 40);
}

props is object have music, title, .....

export const Duration = function ({props}) {
    const [duration, setDuration] = useState("00:00")
    const audio = new Audio(props.music)
    audio.onloadedmetadata = (e) => {
        if (audio.readyState > 0) {
            var minutes = "0"+parseInt(audio.duration / 60, 10);
            var seconds = "0"+parseInt(audio.duration % 60);
            setDuration(minutes + ":" + seconds.slice(-2))
        }
    }
    return duration
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM