Record multi audio tracks available in a stream with MediaRecorder

2.8k views Asked by At

I'm building a screen recorder plugin for chrome store. I'm adding microphone's audio track to the media stream that contains (Screen's video track + System audio track). So final stream contain 2 audio tracks one of microphone and other one of system audio.

When I'm passing this stream to MediaRecorder(stream), than in final video I can able listen only single audio which is at 0 index in stream.getAudioTracks(), i.e., MediaRecorder is recording only single audio track.

So how to record a stream containing multi audio tracks using MediaRecorder?

2

There are 2 answers

3
Pradhyumn On

You can have a look at Muaz Khan's Library for multi stream mixing. Or you can go about it something like this:

const screenStream;
const micStream;
const remoteStream;
// merge audio from remote stream and micStream

const audioCtx = new AudioContext();
const source1 = audioCtx.createMediaStreamSource(micStream);
const source2 = audioCtx.createMediaStreamSource(remoteStream);
const destination = audioCtx.createMediaStreamDestination();

//connect sources to destination 
// you can add gain nodes if you want 
source1.connect(destination);
source2.connect(destination);

const outputStream= new MediaStream();
outputStream.addTrack(screenStream.getVideoTracks()[0]);
outputStream.addTrack(destination.stream.getAudioTracks()[0]);
0
Olexandr Lytvynenko On

Better solution for multiple audio stream in mediaRecord for WebRTC call, which I found :

const startRecording = async () => {
    try {
        const screenStream = await navigator.mediaDevices.getDisplayMedia({
            video: true,
            audio: true,
        });

        const audioCtx = new AudioContext();
        const source1 = audioCtx.createMediaStreamSource(stream.current.srcObject);
        const source2 = audioCtx.createMediaStreamSource(participantStream.current.srcObject);
        const destination = audioCtx.createMediaStreamDestination();
        source1.connect(destination);
        source2.connect(destination);

        const outputStream = new MediaStream();
        outputStream.addTrack(screenStream.getVideoTracks()[0]);
        outputStream.addTrack(destination.stream.getAudioTracks()[0]);
        mediaRecorderRef.current = new MediaRecorder(outputStream);
        mediaRecorderRef.current.ondataavailable = (event) => {
            if (event.data.size > 0) {
                recordedChunksRef.current.push(event.data);
            }
        };
        mediaRecorderRef.current.onstop = () => {
            console.log("dddd");
            setActiveOption({ index: -1 });

            const recordedBlob = new Blob(recordedChunksRef.current, {
                type: "video/mp4",
            });

            const downloadLink = document.createElement("a");
            downloadLink.href = URL.createObjectURL(recordedBlob);
            downloadLink.download = "recorded-screen.mp4";
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);

            setRecording(false);
        };

        recordedChunksRef.current = [];
        mediaRecorderRef.current.start();

        screenStream.getVideoTracks()[0].addEventListener("ended", () => {
            setIsOpenRecordingModal(true);
        });

        setRecording(true);
    } catch (error) {
        setActiveOption({ index: -1 });
        console.error("Error accessing screen:", error);
    }
};