MediaRecorder iOS 14.6:不支持 mimeType

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

我正在通过网站录制和发送音频。为此,我使用 MediaRecorder API。

在桌面或 Android 设备上使用该网站时没有任何问题,并且根据 MediaRecorder 文档,自 2020 年 9 月发布以来,也应该支持 iOS 14。

MediaRecorder 实例化如下:

navigator.mediaDevices.getUserMedia({ audio: true, video: false })
  .then((stream) => {
    // Some validation and other processing. Omitted for brevity.

    const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });

    // Using the mediaRecorder. Omitted for brevity.
  });

在装有 iOS 14.6 的 iPhone 12 上执行此操作时,我从该实例化行收到以下错误:

NotSupportedError: mimeType is not supported

尝试其他格式时出现相同的错误(这些是我发现并尝试过的格式):

  • audio/webm
    (如上例所示)
  • video/webm
  • audio/ogg
    (桌面上也有错误)
  • audio/ogg; codecs=opus
    (桌面上也有错误)

MediaRecorder 是否有任何 mimeType 可以让我在 iOS 设备上使用音频?

我是否得到了其他完全错误的东西?

ios audio-streaming web-mediarecorder
3个回答
5
投票

我的首选解决方案是这样的:

if (MediaRecorder.isTypeSupported('video/webm; codecs=vp9')) {
    var options = {mimeType: 'video/webm; codecs=vp9'};
} else  if (MediaRecorder.isTypeSupported('video/webm')) {
    var options = {mimeType: 'video/webm'};
} else if (MediaRecorder.isTypeSupported('video/mp4')) {
    var options = {mimeType: 'video/mp4', videoBitsPerSecond : 100000};
} else {
    console.error("no suitable mimetype found for this device");
}
const mediaRecorder = new MediaRecorder(stream, options);

IOS仅允许mp4,因此运行此代码后您将自动获得该选项。
我相信这可能是比 try catch 更好的方法。


2
投票

事实证明

video/mp4
适用于 iOS。它也可以仅用于音频,即使它说的是视频。

由于其他浏览器不支持

video/mp4
,因此可以使用带有
video/mp4
的 try/catch 作为后备,这会产生以下解决方案:

let mediaRecorder;
try {
  mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });
}
catch (err1) {
  try {
    // Fallback for iOS
    mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/mp4' });
  }
  catch (err2) {
    // If fallback doesn't work either. Log / process errors.
    console.error({err1});
    console.error({err2})
  }
}

可以通过以下方式使代码更清晰、更明确:

  • 明确捕捉
    NotSupportedError
  • 查询设备/操作系统并显式使用相应的 mimeType,而不是故意遇到错误。

但目前它可以工作,这对于个人项目来说已经足够好了。


0
投票

使用可变列表长度重试的更紧凑答案

const mimeTypes = ["audio/webm", "video/mp4"];

const genericName = async (mimeIndex = 0) => {
    try {
        //Set the mimeType to the first item in the mimeTypes array

        const mimeType = mimeTypes[mimeIndex];
        MediaRecorder.isTypeSupported(mimeType);

        //create new Media recorder instance using the stream
        const media: MediaRecorder = new MediaRecorder(stream, { mimeType });


    } catch (err: any) {
        console.log("Error recording", err.message);
        
        // Retry with the next mimeType if the first mimeType fails
        const retries = mimeTypes.length;
        if (mimeIndex < retries) {
        startRecording(mimeIndex + 1);
      }
    }
  };
© www.soinside.com 2019 - 2024. All rights reserved.