在 Chrome、Safari 中从 blob 获取音频持续时间时出现问题

问题描述 投票:0回答:1

我尝试使用Promise中的loadedmetadata事件来录制音频并从blub获取音频的持续时间。它在 Firefox 中运行良好。但 Chrome 返回的持续时间为 Infinity。 iPhone 甚至无法从 blob 加载音频元数据。问题是什么。如果我尝试获取从本地设备选择的文件的音频持续时间,而不是从媒体记录器中获取 blob 文件,这些代码可以在 Chrome 和 iPhone Safari 中使用。问题是什么?如何从 blob 文件获取音频持续时间?

这是jsfiddle中的代码:
https://jsfiddle.net/c7a8bqvp/4/

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script>

<button id="startAudioRecord" onClick="startAudioRecording()">Start Audio recording </button>

<button id="endAudioRecorder" onClick="endAudioRecording()">End Recording</button>

 <div id="audioRec_div"><br>Here is the audio:<br><audio id="audioRec" ></audio></div>


<script> 

var sc_audioStream ,  sc_audioRec ;
var url ; 
// var url = "https://www.w3schools.com/tags/horse.mp3";

async function getAudioUrlDuration(src) {
    var audio = new Audio();
    audio.src = src;
    return new Promise((resolve) => {
        $(audio).on("loadedmetadata", function(){
            resolve(audio.duration);
        });
            
        $(audio).on("error", function(e) {
           alert("Failed to load audio metadata="+JSON.stringify(e)); 
        });
    });
}


function getUserMedia_audio(){ 
    navigator.mediaDevices.getUserMedia({
        audio: true
      })
    .then(stream => {
         sc_audioStream = stream ;    
         sc_audioRec = new MediaRecorder(stream);   
         sc_audioRec.ondataavailable = e => {   
           var audioRec_arr = [] ;
               audioRec_arr.push(e.data);         
               if( sc_audioRec.state == "inactive") {
                 alert(666);
                    let blob = new Blob(audioRec_arr, { 
                           type: 'audio/mp3'
                    });
                    processBlob(blob) ; 
               }
        }
    })
    .catch((e) => {
       console_log(e);
    });
}


function startAudioRecording() {
  sc_audioStream = null ; sc_audioRec = null ; 
  getUserMedia_audio() ; 
  setTimeout(function(){  
              sc_audioRec.start();
        alert('speak now to record, click end button to stop recording');
   },1500);  // use at least 1500 
}


function endAudioRecording() {
  if( sc_audioStream != null ){ 
      //sc_audioRecord.stop(); This works for audio too 
      sc_audioStream.getAudioTracks().forEach(function(track) {
            // alert('track.readyState='+track.readyState);
            if (track.readyState == 'live') {
                track.stop();
            }
      });
  }
}


async function processBlob(blob){ 
    // load audio to hmtl 
     var audio_recorded =  $('#audioRec') ;
    alert(888); alert(URL.createObjectURL(blob));
    audio_recorded.attr("src", URL.createObjectURL(blob));
    audio_recorded.prop("controls", true);
    //
     var audioDuration = await getAudioUrlDuration( URL.createObjectURL(blob) ) ;
     alert('audioDuration='+audioDuration) ;
}

</script>
blob metadata html5-audio audio-streaming
1个回答
0
投票

使用事件监听器尝试一次

© www.soinside.com 2019 - 2024. All rights reserved.