Chrome 上 JavaScript 中的音频录制,始终将 video/ogg 发送到服务器

Audio recording in JavaScript on Chrome, always sends video/ogg to the server

我一直在尝试在 Chrome 上以 OGG 格式录制音频并将其发送回服务器,但它总是以 video/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!

您需要设置 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 none 个。

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

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

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

您需要从 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>

并且由于 Whosebug 的空源 iframe 不允许安全下载 links,here is a fiddle 下载 link。