admin管理员组

文章数量:1357232

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.

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.

Share Improve this question asked Oct 20, 2021 at 4:28 Jirachai UraijareeJirachai Uraijaree 1861 silver badge6 bronze badges 2
  • 1 Does this answer your question? All MIME types supported by MediaRecorder in Firefox and Chrome? – kevinSpaceyIsKeyserSöze Commented Oct 20, 2021 at 6:11
  • 1 Did you end up finding a solution? I'm stuck on the same problem – ShaiB Commented Feb 23, 2022 at 13:13
Add a ment  | 

4 Answers 4

Reset to default 3

It's wild that this information isn't more widely available. According to the post here, there is no audio format that is both recordable and playable on every major browser.

At least from my experimentation. WebM recorded audio works on all browsers except Safari (though, Safari will still play some webms, just not the ones recorded using MediaRecorder. It might be an encoding thing, but I haven't nailed that down).

Ditching MediaRecorder was the only thing that worked for me. As said in this ment, using a different library like https://github./closeio/mic-recorder-to-mp3 works.

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;

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

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.

本文标签: javascriptAudio recorded from Chrome doesn39t play on SafariStack Overflow