WebRTC 传输媒体流

作者:追风剑情 发布于:2024-2-29 15:08 分类:Unity3d

  在发送方,我们调用 addTrack() 方法加入媒体轨道,开始 ICE 协商。

  在接收方,ICE 完成协商后,连接建立,对等端触发 track 事件,我们从事件中获取对等端传输过来的媒体轨道,此时媒体流的传输通道正常建立,可以像本地媒体流一样操作远程媒体流。

  addTrack() 方法包含了一个可选参数 streams,表示媒体轨道所属的媒体流。当在发送端同时传入媒体轨道和媒体流时,媒体轨道并不一定来自该媒体流。而在接收端则会自动创建一个媒体流,并将接收到的媒体轨道加入这个媒体流。

注意   只有双方同时创建了视频流,才会收到视频画面,如果只有一方创建了视频流,并不会产生单向传输。即创建了视频流的一方不会向未创建视频流的一方发送视频流。

1.无流轨道

  如果没有指定可选参数 streams,传入的轨道即为无流轨道。对等端在 track 事件中接收到媒体轨道后,自主创建 MediaStream,并决定将媒体轨道加入哪个媒体流。对于只共享一个媒体流的简单应用来说,这是一种较为常用的做法,应用不需要关注哪个轨道属于哪个流。

  下面是发送端的示例代码,使用 getUserMedia() 方法获取音频和视频流,并调用 addTrack 将音视频轨道加入连接,这里没有为轨道指定媒体流。

//无流轨道发送端
async openCall(pc) {
	const gumStream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
	for (const track of gumStream.getTracks()) {
		pc.addTrack(track);
	}
}  

  下面是对应的接收端代码,在 track 事件处理函数中创建一个新的 MediaStream,将所有媒体轨道加入到这个媒体流中。

//无流轨道接收端
let inboundStream = null;
pc.ontrack = ev => {
	if (!inboundStream) {
		inboundStream = new MediaStream();
		videoElem.srcObject = inboundStream;
	}
	inboundStream.addTrack(ev.track);
}  

也可以为每个轨道都创建一个新的媒体流。

//无流轨道接收端
pc.ontrack = ev => {
	let inboundStream = new MediaStream(ev.track);
	videoElem.srcObject = inboundStream;
}  

2.有流轨道

  如果指定了 streams 参数,传入的轨道即为有流轨道,此时 WebRTC 将在接收端自动创建媒体流,并管理媒体轨道与媒体流的所属关系。

下面代码调用 addTrack 将音视频轨道加入连接,并为轨道指定了媒体流。

//有流轨道发送端
async openCall(pc) {
	const gumStream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
	for (const track of gumStream.getTracks()) {
		pc.addTrack(track, gumStream);
	}
}  

下面是对应的接收端示例代码,从 ev 事件中获取第一个媒体流,并将媒体流绑定到视频元素,该媒体流包含发送端加入的所有媒体轨道。

//有流轨道接收端
pc.ontrack = ev => {
	videoElem.srcObject = ev.streams[0];
}  

标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号