0

Using pretty standard code from around stackoverflow and the web, I have a simple audio recorder which has an append facility. I need to be able to append as well as pause/resume, for when a previous recording has been loaded and needs to be added to.

Oddly, immediately after an append the following code plays the complete concatenated audio once only, but subsequently on clicking the play button of the audio element, it plays only the most recent chunk/blob that was recorded. Why is this behaviour happening?

Edit: I've just found a similar question here relating to video, where the behaviour of the media player seems to be the same. But in any case (I think) the data I persist to the database needs to be a single audio file rather than a series of concatenated blobs with headers, in order to allow subsequent appends.

Note that if the record button is clicked rather than the append button, the code intentionally resets the audioChunks array to empty, ie overwriting anything recorded previously.

let sampleRate = 16000;
var audioChunks = [];
var audioBlob;

function initRecorder(stream) {
    recorder = new MediaRecorder(stream, { audioBitsPerSecond: sampleRate });
    recorder.ondataavailable = function (e) {
        audioChunks.push(e.data);
    }
    recorder.onstop = (e) => {
        //if (recorder.state == "inactive") {
        audioBlob = new Blob(audioChunks, { type: 'audio/webm;codecs=opus' });
        let recordedAudio = document.getElementById("recordedAudio");
        recordedAudio.src = URL.createObjectURL(audioBlob);
        recordedAudio.controls = true;
        recorder.stream.getTracks() // Stop all tracks from the MediaStream
            .forEach(track => { track.stop(); });
    };
}

async function startRecording(stream) {
    action.innerHTML = "Recording";
    initRecorder(stream);
    await initVolumeMeter(stream); // Also does metering
    recorder.start();
    speechRecog.start(); // Also does speech recognition
}

function appendBtnClicked() {
    updateUi(true, true, false, false, true, true, false, "Initialising recorder - please wait ....");
    navigator.mediaDevices.getUserMedia({ audio: { sampleRate: sampleRate }, video: false })
        .then(async stream => { startRecording(stream) });
}

function startBtnClicked() {
    transcription.value = "";
    audioChunks = [];
    isNewTranscript = true;
    updateUi(true, true, false, false, true, true, false, "Initialising recorder - please wait ....");
    navigator.mediaDevices.getUserMedia({ audio: { sampleRate: sampleRate } , video: false })
        .then(async stream => { startRecording(stream) });
}

function stopBtnClicked() {
    speechRecog.stop();
    recorder.stop();
    updateUi(false, false, true, true, true, false, true, "Stopped");
}
lukep
  • 111
  • 10

0 Answers0