简体   繁体   中英

Audio recorded from Chrome doesn't play on Safari

I'm building an app using React Js where it can record audio from users, upload the file or blob to cloud storage, and play the recorded audio from the file URL.

The issue is when the audio is recorded from Chrome, it only plays on Chrome but doesn't play in Safari. On other hand, if the audio is recorded from Safari, it plays just fine on both browsers.

Tested on

  • 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)

Here is the implementation.

Recording part:

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());

Playback part;

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();
};

These were the requests Safari made to get the audio recorded from Chrome

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

When I tried to play with audio.play() , I've got this error message in console.

在此处输入图像描述

When I tried to play with <audio /> element, there was no error message in console but instead stall event was fired.

在此处输入图像描述

I've also created mp3 file using File contructor and downloaded to macbook. The mp3 file recorded from Safari was playable, where as the one recorded from Chrome was not.

在此处输入图像描述 在此处输入图像描述

You are not setting the content type headers correctly - audio-mpeg is not correct. Safari is very picky about the Content-Type headers. If they do not match the actual content type of the audio file, it will not play.

This is what I am using for my mp3 files. Be aware that Wav and Ogg formats require different headers.

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

It's not because you define your blob as "audio/mpeg" that it will actually be encoded as mp3. I struggle with the same problem... The problem is safari is not actually using the same codec.

Had the same problem and after trying around for quite a while I finally solved it:

When uploading to storage (in my case Firebase), type AND... file ending have to be webm...

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

UPDATE: this only fixed the issue on Safari for desktop, still not working on iOS

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM