从Chrome录制的音频无法在Safari上播放。

7

我正在使用React Js构建一个应用程序,它可以记录用户的音频,并将文件或blob上传到云存储,然后从文件URL播放记录的音频。

问题在于当Chrome录制音频时,它只能在Chrome上播放,但在Safari上无法播放。 与此相反,如果从Safari录制音频,则两个浏览器都可以正常播放。

测试环境:

  • macOS 11.5.1 Big Sur
  • Google Chrome Version 94.0.4606.81 (Official Build) (x86_64)
  • Safari Version 14.1.2 (16611.3.10.1.3)

以下是实现代码:

录制部分:

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recorder = new MediaRecorder(stream);
recorder.addEventListener('dataavailable', ({ data }) => {
  const audioBlob = new Blob([data], { type: 'audio/mpeg' });
  // or new File([audioBlob], 'name.mp3', { type: 'audio/mpeg' });
  // upload blob or file to server
});

// on start
recorder.start();

// on stop
recorder.stop();
recorder.stream.getTracks().forEach((i) => i.stop());

回放部分;

const audioInstanceRef = useRef<HTMLAudioElement | null>(null);

useEffect(() => {
  audioInstanceRef.current = new Audio();
}, []);

const play = (url: string) => {
  if (!audioInstanceRef.current) return;

  audioInstanceRef.current.src = url;
  audioInstanceRef.current.play();
};

以下是Safari获取从Chrome录制的音频所做的请求:

enter image description here enter image description here enter image description here

当我尝试使用 audio.play() 进行播放时,在控制台中出现了此错误消息。

enter image description here

当我尝试使用 <audio /> 元素进行播放时,控制台中没有错误消息,但会触发 stall 事件。

enter image description here

我还使用 File 构造函数创建并下载到 MacBook 上 MP3 文件。 从 Safari 录制的 MP3 文件可以播放,而从 Chrome 录制的则不能。

enter image description here enter image description here


1
这个回答解决了你的问题吗?MediaRecorder在Firefox和Chrome支持的所有MIME类型 - kevinSpaceyIsKeyserSöze
1
你最终找到解决方案了吗?我也卡在同样的问题上了。 - ShaiB
同样的问题在这里 :( - laurajaime
4个回答

2

你没有正确设置内容类型头 - audio-mpeg 不正确。 Safari 对 Content-Type 头非常挑剔。如果它们与音频文件的实际内容类型不匹配,它将无法播放。

这是我用于我的 MP3 文件的设置。请注意,Wav 和 Ogg 格式需要不同的头部。

audio/mpeg3;audio/x-mpeg-3;video/mpeg;video/x-mpeg;


1
这是唯一对我有效的。谢谢! - undefined

2

这些信息的可获得性不够广泛,真是令人惊讶。根据这里的帖子,没有一种音频格式可以在所有主要浏览器上既可记录又可播放。

至少根据我的实验,WebM格式的录制音频在除了Safari以外的所有浏览器上都可以工作(尽管Safari仍然可以播放某些WebM文件,但不能播放使用MediaRecorder录制的文件。这可能与编码有关,但我还没有完全确定)。

对我而言,唯一奏效的方法是放弃MediaRecorder。如此评论所述,使用其他库,例如https://github.com/closeio/mic-recorder-to-mp3可以解决问题。


1

我曾经遇到过同样的问题,试了好一阵子之后,我终于解决了:

当上传到存储中(在我的情况下是 Firebase ),类型必须为 webm 且文件扩展名也必须是 webm...

const audioBlob = new Blob(audioChunks, {type: 'audio/webm'})
const audioPath = `${filename}.webm`
const fileRef = ref(storage, audioPath)
const uploadTask = uploadBytesResumable(fileRef, audioBlob)

更新: 这只修复了桌面版Safari的问题,iOS上仍然无法正常工作。

0

你把你的 blob 定义为 "audio/mpeg" 并不意味着它实际上会被编码为 mp3。我也遇到了同样的问题... 问题在于 Safari 实际上并没有使用相同的编解码器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接