Adding watermark image to MediaStream

Viewed 392

Is it possible to add image to MediaStream object that would be over video stream from camera? But not as another layer but like embebed to stream, so if I pass the stream object to some peer it would also have that embebed image.

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

navigator.mediaDevices.getUserMedia(constraints)
  .then(function(mediaStream) {
    var video = document.querySelector('video');
    video.srcObject = mediaStream;
    video.onloadedmetadata = function(e) {
      video.play();
    };
}).catch(function(err) { console.log(err.name + ": " + err.message); });

As above I just pass mediaStream directly to video element, but can I manipulate stream to add some text or images?

1 Answers

You must manipulate your video stream using a canvas.

If your browser supports requestVideoFrameCallback, it should look like that :

navigator.mediaDevices.getUserMedia(constraints)
  .then(function(mediaStream) {
    let hiddenVideo = document.querySelector('video.hidden') // A video that is not displayed to the user 
    hiddenVideo.srcObject = mediaStream // Play the stream on the hidden video
    
    let canvas = document.querySelector('canvas'); // Get a canvas element, by creating or querying it (it may be hidden using 'display:none')
    let ctx = canvas.getContext('2d');
    let rVFC = () => {
        ctx.drawImage(hiddenVideo, 0, 0, hiddenVideo.videoWidth, hiddenVideo.videoHeight); // Draw the video image on your canvas
        // ... Manipulate your canvas here ...
        hiddenVideo.requestVideoFrameCallback(rVFC)
    }
    hiddenVideo.requestVideoFrameCallback(rVFC)
    
    var video = document.querySelector('video.shown');
    video.srcObject = canvas.captureStream(); // Display the canvas edit on the video
}).catch(function(err) { console.log(err.name + ": " + err.message); });

With an html like

<video class="hidden" style="display:none" controls autoplay></video>
<video class="shown" controls autoplay></video>
<canvas style="display:none"></canvas>

Notes:

  • If you do not need the video controls, the video element is useless, and you can use only the manipulated canvas to display the stream.
  • If your browser doesn't support requestVideoFrameCallback, use requestAnimationFrame instead. See https://web.dev/requestvideoframecallback-rvfc/ for more information about requestVideoFrameCallback

To send the edited stream to a peer, just use the MediaStream created by canvas.captureStream()

pc.addTrack(capturedStream.getVideoTracks()[0])
Related