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
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.