Search code examples
javascriptangularjswebrtcgetusermedia

RecordRTC with custom sample rate records silence


I'm trying to use RecordRTC.js to record audio from a microphone and upload it to a nancyfx server.

For testing purposes, I'm just trying to upload the audio stream and save it to a wav file. My requirement is, however, that the stream is saved in 16 bits at 22050Hz.

The problem is, when I record the file using standard configuration (without recordRtcOptions) , I can upload the file and save it. When I specify the sample rate in recordrtc the output file is just silence.

The relevant part of the code is inside an angularJS service as follows:

app.service('AudioService', ['$window', '$http', function($window, $http) {

    var recordRtcOptions = {
        'sample-rate' : 22050
    };

    navigator.getUserMedia = (
        $window.navigator.getUserMedia ||
        $window.navigator.webkitGetUserMedia ||
        $window.navigator.mozGetUserMedia ||
        $window.navigator.msGetUserMedia)

    var _recordRTC = {};
    navigator.getUserMedia({ audio: true, video: false }, function (stream) {
        console.log('starting to initialize getUserMedia');
        console.log(recordRtcOptions);

        _recordRTC = RecordRTC(stream, recordRtcOptions);    

        console.log('Finished initializing getUserMedia');
    }, function (error) {
        console.log('Error initializing media stream: ' + error);  
    });

    var instance = {};

    instance.startRecording = function() {
        console.log('starting to record...');
        console.log('sample rate: ' + _recordRTC.sampleRate);
        _recordRTC.startRecording();
    };

    instance.stopRecording = function(uploadPath) {

        console.log('sample rate: ' + _recordRTC.sampleRate);


        _recordRTC.stopRecording(function(audioVideoMURL) {
            console.log('stopped recording...');
            console.log('recordrtc stop sample rate: ' + _recordRTC.sampleRate);

            $http({
                method : 'POST',
                url : uploadPath,
                data : _recordRTC.getBlob()
            }).success(function(data) {
                console.log('POST /audio Success');

            }).error(function() {
                console.log('POST /audio error'); 
            });
        });

    };

    return instance;

}]);

Any idea on what might be the problem?


Solution

  • to understand the problem you need to look into RecordRTC.js:

    • first the function mergeProps copies the config you provided.
    • the function reformatProps converts "sample-rate" into property "sampleRate".
    • StereoRecorder is used for recording, which internally uses StereoAudioRecorder which is essentially similar as mattdiamond/Recorderjs.

    when you look into that, it does not take sampleRate as input, but determines it from these line

    var Recorder = function(source, cfg){
        ...
        this.context = source.context;
        ...
            sampleRate: this.context.sampleRate, // --> this is the right way to provide sampleRate
    

    and in RecordRTC,

    var sampleRate = typeof config.sampleRate !== 'undefined' ? config.sampleRate : context.sampleRate || 44100;
    

    long story short, if you notice, here too when sample rate is not provided, it takes context.sampleRate which is sample rate provided by the microphone, so just changing the sample rate in config is not sufficient, because all that would do is alter the samplerate value that is written on to the .wav file( can check the function mergeLeftRightBuffers for confirmation) but the data would have still been recorded on the original sample rate.

    If you really want to modify the sampleRate, you can look at Record audio on web, preset: 16000Hz 16bit