RecordRTC
RecordRTC copied to clipboard
StereoAudioRecorder audio garbled on Safari
I'm trying to use a StereoAudioRecorder to record audio. Its working on all other browsers, but on Safari the audio is coming out garbled (very scratchy and crackly, and lacking in detail, as if only some audio frequencies are coming through, or something like that).
Here's the function that prepares the recorder:
function prepareRTC(callback) {
if (!window.microphone) {
captureMicrophone( micCallback );
return;
} else {
console.log('mic already captured!');
}
var options = {
mimeType: 'audio/wav',
fileExtension: 'wav',
numberOfAudioChannels: 1,
bufferSize: 16384,
checkForInactiveTracks: true,
recorderType: StereoAudioRecorder,
desiredSampRate: 22050,
};
if(window.browser == 'safari') {
options.type = 'audio';
delete options.desiredSampRate;
options.sampleRate = 44100;
options.bufferSize = 4096;
options.numberOfAudioChannels = 2;
}
if (window.audioRecorderPH || window.audioRecorder) {
window.audioRecorder.destroy();
window.audioRecorder = null;
}
window.audioRecorderPH = new RecordRTCPromisesHandler(window.microphone, options);
window.audioRecorder = window.audioRecorderPH.recordRTC;
callback();
return;
}
I use the options you suggest in your example. Instead of using an <audio> element, I use an AudioContext to play the audio, and I thought the problem might be related to that, but the audio is coming out messed up before it even gets to there (like if I try to play the blob using window.audioRecorder.toURL()
). Here is a short recording of me, if you listen carefully you can hear I said "Recording on, on Safari."
Have you seen this kind of behavior before? Do you have any idea what might be causing it? Thank you for any help. And please let me know if any more details would be helpful.
@jonahjonah have you found out what was wrong?
Having this same issue using the following options
mimeType: 'audio/wav',
type: 'audio',
recorderType: RecordRTC.StereoAudioRecorder,
bufferSize: 4096,
numberOfAudioChannels: 2,
sampleRate: 44100,
I am also having this issue using these options.
Strangely, the example referenced does work properly in Safari.
I am having troubles determining what is different.
In my situation, the audio garbling appears to be caused by additional code using the AudioContext API. I used this to calculate the audio level for user visualization.
For the moment, I disabled this code in Safari and the audio recording is not garbled.
Perhaps it puts too much stress on the recording process in Safari.
@ccchapman I also create AudioContext, for sound/silence detection, and sound garbles, but if I remove line desiredSampRate: 44100, all works, seems problem lies somewhere here, not sure if this is couse of high rate or AudioContext with desiredSampRate safari issues, on chrome all works
or maybe safari using 48000 rate ? anyone knows StereoAudioRecorder sample rate by default?
@DevJhns I think the default is 16000
, per the README.
Your audio is not garbled when you remove desiredSampRate
from your options? Mine still is.
@ccchapman seems so, I don't define buffersize
and no desiredSampRate
also no sampleRate
all I set:
type: 'audio', mimeType: 'audio/wav', recorderType: StereoAudioRecorder, numberOfAudioChannels: 1
@ccchapman actually example above works on mac safari(works with sampleRate: 48000
),
on ios safari it is still garble/distortion sound I found this old safari bug https://github.com/Jam3/ios-safe-audio-context and this https://stackoverflow.com/questions/26336040/how-to-fix-changing-sample-rate-bug
in few words this happens couse of another apple fuc... mess up, as always.... sigh
for some reason audiocontext may take wrong value, and it changes sample rate few times (if we have video or audio around, like in our case webrtc stream video/audio), so this couse distortion, I added audio: { sampleRate: 48000 }
in navigator.mediaDevices
and sampleRate: 48000
for RecordRTC
now I can at least hear my voice, with distortion, kind robotic, but understandable at least, if I change sampleRate to 44100 in RecordRTC, hear no sound at all, strange...
Per @ccchapman's comment, I too use the the AudioContext API to calculate the audio level for a visualization (example below).
I've tried all the possible combinations and still get the garbled/distorted sound. Using @DevJhns's recommendation to specify sampleRate
in getUserMedia
got me the closest, but recording still has some garbling/distortion.
navigator.mediaDevices
.getUserMedia({audio: {sampleRate: 48000}})
.then(mediaStream => handleStreamSuccess(mediaStream))
handleStreamSuccess(mediaStream) {
const mediaRecorder = RecordRTC(mediaStream, {
disableLogs: isProduction,
mimeType: 'audio/wav',
numberOfAudioChannels: 2,
type: 'audio',
checkForInactiveTracks: true,
recorderType: RecordRTC.StereoAudioRecorder,
bufferSize: 4096,
sampleRate: 48000
});
}
FYI I also tried using https://github.com/Jam3/ios-safe-audio-context to create the Audio Context but it still resulted in garbled/distorted audio.
@jonsadka your audio garbles/distortes only in ios? What about audio from macbook safari ?
@DevJhns was happing on Macbook Safari, didnt test on iOS. Were you able to use ios-safe-audio-context
sucessfully?
@jonsadka I haven't used it yet, wanna fix bug without other libs,
my friend who have mac, said sound was ok, but this was before I added
{audio: {sampleRate: 48000}}
just with audio: true
and sampleRate: 48000
in recordrtc all worked there, but not on ios
@jonsadka @ccchapman
Actually I found solution,
remove sampleRate: 48000 from audio, just set it to true or your settings,
and pass stream.clone()
to your function with audiocontext
createMediaStreamSource(stream)
caused all troubles
now I get clear sound on ios, sure it will be good on mac too, but....
now record work only once... any ideas, guys? can someone check how mac behaves?
@jonsadka @ccchapman Actually I found solution, remove sampleRate: 48000 from audio, just set it to true or your settings, and pass
stream.clone()
to your function with audiocontextcreateMediaStreamSource(stream)
caused all troublesnow I get clear sound on ios, sure it will be good on mac too, but....
now record work only once... any ideas, guys? can someone check how mac behaves?
I'll try when I get a chance, but if you clone the stream I'd imagine you'd have to make sure you update all your previous references of the stream to the new clone (or try creating a new media stream every time you want to re-record, which is less ideal)
@jonsadka aslo passing stream.clone() to RecordRTC fix this oh yeah, at last =)
@DevJhns nice! This workaround seems to work on the Apple devices tested below: ✅ MacBook Pro Safari 13.0.2 ✅ iPhone X iOS 13.2 ✅ iPhone 7 iOS 12.3.1 ✅ iPhone 5 iOS 12.4.2
What a neat little hack. I do wonder what some of the performance implications are of cloning a stream (will try to dig into this a little deeper)
@jonsadka much better, than more external libs, huh?
Now it would be excellent if apple add mediarecorder support out of the box in at least 50 years (now it is in beta functions)
couse when I record with stereoaudiorecorder getting ~500-700 kb wav file 2-3 seconds vs ~8-12 kb webm... both 48000 rate, 60+ times difference
Hi Guys I don't have same luck than you with passing stream.clone to RecordRTC I still have cracks when I am speaking with a peer and recording my voice at the same time
@numerized show your recordrtc settings and what you do with stream except recording (libs, api, etc) do you set settings in audio (constraints)?
@numerized your issues coused by rate misssetings, hard to say where problem is without knowing your api/libs stack and settings
sorry guys I was travelling, so I don't get it, I'll try more soon, but I have the same crackling noises when using whereby.com on my IOS and no problem when I compile an actual cordova app and it's our new requirement, no IOS on Safari web so I'm good thanks all.
@DevJhns nice! This workaround seems to work on the Apple devices tested below: ✅ MacBook Pro Safari 13.0.2 ✅ iPhone X iOS 13.2 ✅ iPhone 7 iOS 12.3.1 ✅ iPhone 5 iOS 12.4.2
What a neat little hack. I do wonder what some of the performance implications are of cloning a stream (will try to dig into this a little deeper)
I read your discussion carefully, unfortunately, I don’t know how to implement stream cloning.
@jonsadka aslo passing stream.clone() to RecordRTC fix this oh yeah, at last =)
When the sampling rate is set to 16khz, the audio noise played back or saved is particularly large and severely distorted
Hi, guys, I'm stuck in this also...I tried stream.clone, but doesn't work, still have a bad recording, it's full of glitchs and shorter than it should be. Which are the right rate settings for Safari??
@Pmartbur @luckyxue this is the code I am using with the configuration. Is this still creating issues?
const mediaRecorder = RecordRTC(mediaStream.clone(), {
checkForInactiveTracks: true,
mimeType: 'audio/wav',
numberOfAudioChannels: 2,
recorderType: RecordRTC.StereoAudioRecorder,
type: 'audio',
});
For people still encountering this issue: do you have another audio/video element on the page (or did you ever have one) prior to the recording? In my usage, it appears that as soon as another audio/video element is played on the page, any subsequent audio context is tainted/corrupted and produces distorted results.
Try reproducing the issue without any other audio/video elements present. In my case, eliminating a video that is displayed before the recording seems to address the issue. Furthermore, I can put the video I want to display inside of an iframe and as long as that iframe is removed from the page before recording, the audio seems ok.
The RecordRTC(mediaStream.clone(),
fixed my issue but it does feel like a dirty hack. Does anyone know why that can make it work or what distorts it?
Also if we do the .clone()
do I need to close the original one?
adding .clone()
worked also for me
Thank you guys so much! I saw this thread and changed my implementation from
recorder = new RecordRTC(stream, options);
to
recorder = new RecordRTC(stream.clone(), options);
and it solved all issues!