WebRTC pause and resume stream
Asked Answered
M

3

25

I am trying to use WebRTC to build a web application that needs to pause/resume the video/audio stream when some events trigger. I have tried the getTracks()[0].stop() but I am not sure how to resume the stream. Are there any advice on that? thanks

Marchioness answered 8/3, 2016 at 2:0 Comment(0)
E
41

getTracks()[0].stop() is permanent.

Use getTracks()[0].enabled = false instead. To unpause getTracks()[0].enabled = true.

This will replace your video with black, and your audio with silence.

Try it (use https fiddle for Chrome):

var pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();

navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then(stream => pc1.addStream(video1.srcObject = stream))
  .catch(log);

var mute = () => video1.srcObject.getTracks().forEach(t => t.enabled = !t.enabled);

var add = (pc, can) => can && pc.addIceCandidate(can).catch(log);
pc1.onicecandidate = e => add(pc2, e.candidate);
pc2.onicecandidate = e => add(pc1, e.candidate);

pc2.onaddstream = e => video2.srcObject = e.stream;
pc1.onnegotiationneeded = e =>
  pc1.createOffer().then(d => pc1.setLocalDescription(d))
  .then(() => pc2.setRemoteDescription(pc1.localDescription))
  .then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
  .then(() => pc1.setRemoteDescription(pc2.localDescription))
  .catch(log);

var log = msg => div.innerHTML += "<br>" + msg;
<video id="video1" height="120" width="160" autoplay muted></video>
<video id="video2" height="120" width="160" autoplay></video><br>
<input type="checkbox" onclick="mute()">mute</input><div id="div"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

PeerConnections basically stop sending packets in this muted state, so it is highly efficient.

Engedi answered 8/3, 2016 at 16:5 Comment(7)
The last sentence is unclear. Will "black video" and "silence" still use similar resources as before disabled (decoding/rendering, data transmission, etc)?Daybook
@Daybook I've updated the answer to clarify that it hardly uses any resources. I confirmed it using stats in this fiddle (requires Firefox for spec-stats atm). Thanks for catching that it was unclear.Engedi
Can you explain what happens to bandwidth?Medick
I think i still receive track, but how can pause a particular transreceiver.sender(Audio/Video) from remote side with negotiation and without it ?Medick
I changed direction attr from receiver side to 'inactive' and On the receiver side, the bandwidth decreased, do you think it's true way for pause audio/video ?Medick
@J4v4d Right, to pause from the remote end is a different question, and changing direction is one way to go there. See my blog post for the myriad ways to control a track remotely.Engedi
is there any way out for just pausing the steaming simply instead of receiving blank frames , because I am sending those frames to the backend for processingLanita
B
2

You should try using renegotiation, I believe the difference still exists how it is done in chrome and firefox:

  • In chrome, you just call addStream or removeStream on the PeerConnection object to add/ remove the stream, then create and exchange sdp.

  • In firefox, there is no direct removeStream, you need to use RTCRtpSender and addTrack and removeTrack methods, you can take a look at this question

Buoyage answered 8/3, 2016 at 2:43 Comment(1)
in my case, idk how addTrack didnt work, but rtcRtpSender.replaceTrack(track); worked. \ see: java - can we remove and add audio stream dynamically in webRTC video call without renegotiation - Stack OverflowFanelli
M
0

Below code can work perfect under Mac and Windows Chrome after version 117.

At each condition including tab(with or without audio), window or full screen(with or without audio).

Freeze at the last screen and resume fast.

const pc = new RTCPeerConnection(servers);

...

const pause=()=>{
    pc.getSenders().forEach(sender=>{
        console.log(sender.track.kind+' pause');//audio(if it exists) and video
        const parameters=sender.getParameters();
        parameters.encodings[0].active=false;
        sender.setParameters(parameters);
    });
};

const resume=()=>{
    pc.getSenders().forEach(sender=>{
        console.log(sender.track.kind+' resume');
        const parameters=sender.getParameters();
        parameters.encodings[0].active=true;
        sender.setParameters(parameters);
    });
};
Moynihan answered 26/10, 2023 at 6:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.