I found two ways to solve this issue.
First and easier way is to loop your video, either add "loop" in your video element in HTML file, or through JavaScript.
If for some reason you don't want to loop your video (e.g. not a wanted behavior), you can do something like this:
video.addEventListener('play', (event) => {
// check if your media stream is active
// (user can pause/unpause so we need to do a check)
if (!mediaStream.active) {
// user clicked play on a video that finished playing
// we want to get a new stream and replace a videoTrack in the existing and established RTCPeerConnection
const newstream = video.captureStream();
const sender = pc.getSenders().find((s) => s.track.kind === "video");
sender.replaceTrack(newstream.getVideoTracks()[0]);
}
});
Edit 1:
I made a github repo to demo the solution: https://github.com/mluketin/webrtc-video-to-pc
Edit 2: I fixed 'leftVideo' variable that should have been named 'video'
Edit 3:
Another way to avoid using loop
is to pause()
the video on ending. You cannot wait until vid.currentTime == vid.duration
as that closes the stream. However currentTime
does fire at every frame so it can never precisely stop at last frame (workarounds include using video's own FPS or vid.requestVideoFrameCallback()
to know how many more frames (milliseconds) to advance forward by, but this per-frame advancing is beyond the scope of this question).
Here is a starting example code:
note: The number 0.225
should be actually 0.333
but it seems not precise enough to avoid triggering an onEnded
event. The 0.333
would be from (1000 / FPS) / 100
for example (1000/30FPS) / 100) = 0.333
.
<!DOCTYPE html>
<html>
<body>
<div>
<video id="vid_sender" width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
</video>
<b> Sender... </b>
</div>
<div>
<video id="vid_getter" width="320" height="240" >
<source src="" type="video/mp4">
</video>
<b> Receiver... </b>
</div>
</body>
<script>
var vid_sender = document.getElementById("vid_sender");
var vid_getter = document.getElementById("vid_getter");
var vid_FPS = 30; //# use actual video FPS here
const stream = vid_sender.captureStream( vid_FPS );
//# un-comment this line to see problem as solved
//# solution is to pause the video before it ends
vid_sender.ontimeupdate = (evt) => myFunction (evt);
vid_getter.srcObject = stream;
vid_getter.load(); vid_getter.play();
function myFunction (input)
{
if( input.target.currentTime >= (input.target.duration - 0.250) )
{
input.target.pause();
alert("time stop: " + input.target.currentTime + " of duration: " + input.target.duration);
}
}
</script>
</html>