Search code examples
javascriptnode.jswebrtcgetusermediamediastream

How to get both audio and video sent over WebRTC tracks?


I'm making a WebRTC site and working on a one-to-many video connection right now. After finding that addStream() is deprecated, I switched to addTrack(). However, no matter which one I use, only the audio is being sent over, not the video. Originally I thought it was because I was on localhost without https, but even when I run it on my node server the same thing occurs. A solution would be appreciated.

Hosting code (host.js)

    document.addEventListener("DOMContentLoaded", () => {
    uuid = createUUID();

    localVideo = document.getElementById('localVideo');

    serverConnection = new WebSocket('wss://' + window.location.hostname + ':443');

    console.log("Opened WS on :443")

    serverConnection.onmessage = gotMessageFromServer;

    var constraints = {
        video: true,
        audio: true,
    };

    if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia(constraints).then(getUserMediaSuccess).catch(errorHandler);
    } else {
        alert('Your browser does not support getUserMedia API');
    }

    document.getElementById("start").addEventListener("click", (e) => {
        start(uuid)
    });
});

function getUserMediaSuccess(stream) {
    localStream = stream;
    localVideo.srcObject = stream;
}

function start(uid) {
    peerConnections[uid] = new RTCPeerConnection(peerConnectionConfig);
    peerConnections[uid].onicecandidate = gotIceCandidate;

    for (const track of localStream.getTracks()) {
        peerConnections[uid].addTrack(track, localStream);
      }
}

Viewer code (client.js)

function pageReady() {
    uuid = createUUID();

    remoteVideo = document.getElementById('remoteVideo');
    remoteVideo.srcObject = remoteStream;
    remoteVideo.play();

    serverConnection = new WebSocket('wss://' + window.location.hostname + ':443');
    serverConnection.onmessage = gotMessageFromServer;

    var constraints = {
        video: false,
        audio: true,
    };

    if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia(constraints).then(getUserMediaSuccess).catch(errorHandler);
    } else {
        alert('Your browser does not support getUserMedia API');
    }

}

function getUserMediaSuccess(stream) {
    localStream = stream;

}

function start(isCaller) {
    console.log("pressed Start")
    peerConnection = new RTCPeerConnection(peerConnectionConfig);
    console.log("new RTCconnection")
    peerConnection.onicecandidate = gotIceCandidate;
    peerConnection.ontrack = gotRemoteStream;
    peerConnection.addTrack(localStream.getTracks()[0]);
    peerConnection.createOffer().then((desc) => {
        createdDescription(desc);
    }).catch(errorHandler);
}

function gotRemoteStream(e) {
    console.log('got remote stream');
    if (e.streams && e.streams[0]) {
        remoteVideo.srcObject = e.streams[0];
      } else {
        if (!inboundStream) {
          inboundStream = new MediaStream();
          remoteVideo.srcObject = inboundStream;
        }
        inboundStream.addTrack(e.track);
      }
}

P.S. I'm only sending audio from the viewer side because it's a one-way call, but the viewer has to initiate the call. My problem is getting both audio and video from the host side onto the viewer's side.

P.P.S. You probably want more code so you can run it yourselves, so the repo is here. Open one client on /host and another on /class. Make sure you go to https://localhost or it won't work.


Solution

  • Add this line in the client.js file peerConnection.addTransceiver("video"); after addtrack call.

    function start(isCaller) {
        console.log("pressed Start")
        peerConnection = new RTCPeerConnection(peerConnectionConfig);
        console.log("new RTCconnection")
        peerConnection.onicecandidate = gotIceCandidate;
        peerConnection.ontrack = gotRemoteStream;
        peerConnection.addTrack(localStream.getTracks()[0]);
        peerConnection.addTransceiver("video"); // The line to be added
        peerConnection.createOffer().then((desc) => {
            createdDescription(desc);
        }).catch(errorHandler);
    }