0

I have two iframe elements loaded with each their document, both of the same origin domain.

The document loaded in the first frame obtains some media stream (using getUserMedia) and will attach the stream to a player.

The document loaded in the second frame also has a player and I want to re-use the same media stream for this player as well.

Searching for a solution I came across the RTCPeerConnection class article at Mozilla Developer Network and then some examples of using it.

But it looks really heavy for a simple use case like mine. I just want to share the stream between two frames in the same browser and on the same computer.

Is what I have found the only way to achieve this?

If so is there any way to improve the performance (less CPU usage)?

Or is there another way to achieve the above mentioned use case?

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
Anto Joy
  • 141
  • 3
  • 12

1 Answers1

0

I can't quote a relevant Web standard publication at the moment, to assert the behaviour I am about to describe is "standardised", but I have empirically verified it (playing back of a media stream in another frame) is trivial to accomplish with Google Chrome, Microsoft Edge or Mozilla Firefox, if the frames/documents share the same origin.

Being how these are the most popular user agents, especially for applications that depend on the MediaStream class, their capability should suffice for your application, I presume.

The crux of the solution is that the aforementioned user agents do not distinguish between frames of the same origin with regard to playing back a media stream.

Meaning that yes, if you can use the following code in your application, assuming player refers to some HTMLMediaElement and media_source to some MediaStream object:

player.srcObject = media_stream;

...then the code will work "from another frame" as well (provided that other frame is of the same origin, of course).

There is no special case that you have to address. To play back the same media stream in multiple documents/frames, you can (and should, methodically) be assigning the same media stream object to the srcObject property of some media element that is part of any one of the documents, as long as the documents share the same origin.

The performance should arguably be optimal, since the media stream is one and the same and is thus "shared" by all media playback elements. You are not duplicating the stream, after all.

I am certain the proposed solution becomes invalid when you attempt to play back a media stream created in context of one origin, with a media playback element that is associated with another origin. You may be able to duplicate the media stream by copying its data segments, blob by blob or source buffer by source buffer, perhaps, using message passing that assumes both frames cooperate on either end of the communication channel (through postMessage), but that will definitely not be performance optimal, I'd imagine, if at all possible.

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
  • But will this approach will not work for MediaStream right? – Anto Joy Aug 09 '21 at 14:08
  • It will work for `MediaStream` just as well, because this isn't about some property of the `MediaSource` class as such, but about how the user agent partitions the scripting domain, whereas it's free to share and reuse objects of most classes between documents of the same origin. There *may be* some exceptions -- some objects created by one document are inaccessible by another, even if both documents are of the same origin -- but `MediaStream` isn't one of them. It will work. – Armen Michaeli Aug 09 '21 at 14:20
  • I am sorry -- I originally misread `MediaStream` as `MediaSource` in your question, penning my answer. Nevertheless, the solution for sharing a media stream is pretty much the same, with the exception of how a media stream is attached for playback to a media element. I've edited the answer to reflect the change, but keep in mind that the solution still rests on the same general principle -- just attach your media stream to the player in another frame, same way as you would attach it to a player in the same document (that your script that obtained the stream, is part of). – Armen Michaeli Aug 09 '21 at 14:34
  • i'd be surprised if this works. How do you transfer the mediastream object? This kinda used to work when one could do URL.createObjectUrl on it and then used postMessage, but that no longer works for a while. – Philipp Hancke Aug 09 '21 at 15:33
  • There is no transference as such. Like I said, it works in aforementioned user agents. It's not some special case you need to address. The answer basically explains the validity of `document.querySelector("iframe").contentDocument.querySelector("video").srcObject = document.querySelector("video").srcObject = media_stream`. Which is simply addressing properties of DOM objects in two different documents, and assigning one and the same value to these properties. This isn't any different than assigning any other property of a document loaded in an `iframe`, using `contentDocument`. – Armen Michaeli Aug 09 '21 at 16:22