Search code examples
javascriptcanvaswebrtcgetusermediared5pro

Replace "navigator.mediaDevices.getUserMedia" with "canvas.captureStream"


I'm using Red5pro html SDK to create a peer to peer connection between a server and a client, video and audio chat work like a charm with getUserMedia(). The problem is, I want to stream from a DOM element(Canvas), not from user's camera, using captureStream().

Red5Pro has method called "OnGetUserMedia" with the following instructions:

The onGetUserMedia method - when defined on the configuration provide to a WebRTC-based Publisher - will override the internal call to getUserMedia in the Red5 Pro HTML SDK.

You can provide your own logic on how getUserMedia is invoked and a Media Stream attained by setting the onGetUserMedia attribute to a method that conforms to the following guidelines:

No input arguments are provided to onGetUserMedia. It is expected that a Promise object is returned. A MediaStream object must be provided in the resolve of the Promise.

When I did a research and asked the Red5pro Support team, they said

Inside of the promise returned, you can derive a MediaStream from captureStream.

Ref: Red5Pro Documentation

I just don't have a clue what to do, or what to change.

here's a sample of the onGetUserMedia Method:

{
  host: "localhost",
  protocol: 8083,
  port: 8081,
  streamName: "mystream",
  iceServers: [{ urls: "stun:stun2.l.google.com:19302" }],
  onGetUserMedia: function () {
    return navigator.mediaDevices.getUserMedia({
      audio: true,
      video: {
        width: {
          max: 1920,
          ideal: 1280,
          min: 640,
        },
        width: {
          max: 1080,
          ideal: 720,
          min: 360,
        },
      },
    });
  },
};

Any Help?


Solution

  • What you have been asked to do is to set the onGetUserMedia property to a function that does return a Promise, itself resolving to a MediaStream.

    This is probably because they've built their API with the correct assumption that most MediaStreams their user will have is one coming from mediaDevices.getUserMedia method, and this method does return such a Promise that do resolve to a MediaStream.

    In order to comply with their code, you have to wrap your own MediaStream in such a Promise.
    Indeed, HTMLCanvasElement.captureStream is synchronous and returns directly the MediaStream, without a Promise wrapper.

    So to do this, you just need to create a function that will wrap your MediaStream in a Promise, and this can be done by the Promise.resolve method:

    {
      [...]
      iceServers: [{urls: 'stun:stun2.l.google.com:19302'}],
      onGetUserMedia: () => Promise.resolve(canvas.captureStream(frameRate))
    }
    

    Ps:
    () => syntax is ES6 Arrow function, widely supported by browsers that do support HTMLCanvasElement.captureStream.