【问题标题】:Audio recording in JavaScript on Chrome, always sends video/ogg to the server在 Chrome 上用 JavaScript 录制音频,总是将视频/ogg 发送到服务器
【发布时间】:2021-04-03 07:33:28
【问题描述】:

我一直在尝试在 Chrome 上以 OGG 格式录制音频并将其发送回服务器,但它总是以视频/ogg 格式获取它们。这是我所拥有的:

捕获音频:

let chunks = [];
let recording = null;

let mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();

mediaRecorder.onstop = function() {
    recording = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
}

mediaRecorder.ondataavailable = function(e){
    chunks.push(e.data);
}

发送到服务器:

let data = new FormData();
data.append('audio', recording);

jQuery.ajax(...);

blob 到达后端,但总是在 video/ogg 中!

【问题讨论】:

  • 看来您正在使用 jQuery.ajax()。那么你的 jquery 有问题吗?请将该电话的详细信息添加到问题中。
  • 另外,您是否考虑过使用本机 javascript,如解释 here
  • 作为第三条评论,为什么重要? ogg 只是一个容器,所以无论如何它都是同一个 ogg 文件。
  • @eis 我认为 ajax 代码无关紧要,无论是 jQuery 还是其他东西,它是发送的 FormData 对象,jQuery 不会改变文件的 mime 类型......或者我相信。
  • 问题只是发送的 mime 类型还是内容也有问题?你怎么看它是视频/ogg 而不是音频/ogg?

标签: javascript html5-audio web-mediarecorder


【解决方案1】:

我最终使用了kbumsik/opus-media-recorder,为我解决了这个问题。 MediaRecorder 的直接替代品。

【讨论】:

    【解决方案2】:

    您需要从 MediaStream 中删除 VideoTrack:

    const input = document.querySelector("video");
    const stop_btn = document.querySelector("button");
    input.onplaying = (evt) => {
      input.onplaying = null;
      console.clear();
      const stream = input.captureStream ? input.captureStream() : input.mozCaptureStream();
      // get all video tracks (usually a single one)
      stream.getVideoTracks().forEach( (track) => {
        track.stop(); // stop that track, so the browser doesn't feed it for nothing
        stream.removeTrack( track ); // remove it from the MediaStream
      } );
      const data = [];
      const recorder = new MediaRecorder( stream, { mimeType: "audio/webm" } );
      recorder.ondataavailable = (evt) => data.push( evt.data );
      recorder.onstop = (evt) => exportFile( new Blob( data ) );
      
      stop_btn.onclick = (evt) => recorder.stop();
      stop_btn.disabled = false;
      recorder.start();  
    };
    console.log( "play the video to start recording" );
    
    
    function exportFile( blob ) {
      stop_btn.remove();
      input.src = URL.createObjectURL( blob );
      console.log( "video element now playing recoded file" );
    }
    video { max-height: 150px; }
    <video src="https://upload.wikimedia.org/wikipedia/commons/2/22/Volcano_Lava_Sample.webm" controls crossorigin></video>
    <button disabled>stop recording</button>

    而且由于 StackOverflow 的 null 来源 iframe 不允许安全下载链接,here is a fiddle 带有下载链接。

    【讨论】:

      【解决方案3】:

      您需要设置MediaRecordermimeType。否则浏览器会选择它最喜欢的任何格式来对媒体进行编码。

      let mediaRecorder = new MediaRecorder(stream, { mimeType: 'my/mimetype' });
      

      为了确保浏览器实际上可以编码您想要的格式,您可以使用isTypeSupported()

      console.log(MediaRecorder.isTypeSupported('my/mimetype'));
      

      例如,Chrome 不支持"audio/ogg; codecs=opus",但支持"audio/webm; codecs=opus"。 Firefox 两者都支持。 Safari 没有。

      配置MediaRecorder 后,您可以在创建blob 时使用它的mimeType

      recording = new Blob(chunks, { 'type' : mediaRecorder.mimeType });
      

      【讨论】:

      • 太好了,我会试一试。但是无论如何可以从 chrome 中获取音频/ogg 吗?!我使用的第 3 方服务需要 OGG
      • 我不知道。但是应该可以编写一些代码来解开 webm 容器以提取作品音频。
      • 仍然以“video/webm”的形式发送出去!这很奇怪!
      • 悲伤但真实:MediaRecorder 生成的 MIME 类型来自一个小列表。 Chrome 只做 webm。 Safari 只播放 mp4。这是一场真正的电子政治混乱。
      猜你喜欢
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-07
      相关资源
      最近更新 更多