js创建audioTrack和videoTrack并绑定到stream上


最近用webRTC做P2P音视频通讯时,开始是在getUserMedia()成功调用后的回调函数中,处理pc.addTrack(track, stream),可是这样出现一个bug:A作为主持人,B作为参会者,当A没有摄像头设备,B有摄像头时,A和B成功建立通讯,可是A却看不到B的画面,研究发现:

参会方B的audioTrack和videoTrack都成功addTrack了,可是主持人方A在onTrack时却只收到了B的audioTrack,个人猜测可能是因为WebRTC的sender和receiver对应一个通道,当发送方没有videoTrack时,也无法收到接收方的videoTrack,但是反之却不影响(并不肯定)。

这是一个问题,还有一个问题就是:如果开会前没有媒体设备,而在会议中途插入媒体设备,该如何处理,双方需要重新协商吗?我并不想重新协商,因为P2P的多方重新协商太繁琐,我想尽量避免。

于是就想能否提前产生audioTrack和videoTrack,PC端用C实现也是这一原理,这样就不必等到getUserMedia()成功后addTrack,在开始addTrack,初始如果没有摄像头设备自然没有画面,等到有媒体设备后只要利用我上一篇博客替换摄像头的原理,将track替换掉就行,成功避免了上述问题,而且还加快了入会速度。

下面就简单记录一下创建audioTrack和videoTrack的几种方法:

1. 创建audioTrack

主要有两种方法:1)从video元素上获取;2)利用WebRTC的Audio API创建。

1.1 从video元素获取audioTrack/videoTrack

要注意这个方法是异步操作。要先保证video能够play,然后在oncanplay监听事件的回调中才能获取audiotrack。

	var video;
	var stream_video ;
	var stream_media ;
   	video = document.getElementById('streamVideo');
    video.play();
    video.oncanplay = await maybeCreateStream;
  
    function maybeCreateStream () {
      stream_video = video.captureStream() || video.mozCaptureStream();
      // 创建一个用于视频的空stream
      stream_media = new MediaStream();
      videoTrack_media = stream_video .getVideoTracks()[0].clone();
      audioTrack_media = stream_video .getAudioTracks()[0].clone();
      // 绑定
      stream_media.addTrack(videoTrack_media);
      stream_media.addTrack(audioTrack_media);
    }

1.2 利用WebRTC的Audio API创建audioTrack

	let audioCtx = new AudioContext();
    let dest = audioCtx.createMediaStreamDestination();
    let aStream = dest.stream;
    var audioTrack_media = aStream.getAudioTracks()[0];
    console.log(audioTrack_media); 

2. 创建videoTrack

主要有两种方法:1)从video元素上获取;2)从canvas元素上获取。

2.1 从video元素获取audioTrack/videoTrack

同1.1

2.2 从canvas元素上获取

特别注意:火狐从canvas上获取stream时的兼容性处理

还有,canvas上获取的流是MediaStream类型,但是该stream上获取的videoTrack其实并不是MediaStreamTrack类型,而是CanvasCaptureMediaStreamTrack类型,但是不影响addTrack()

	//初始化用于获取track的canvas/video的流
	var screenTrackId;
	var videoTrack_media;
    let canvas = document.getElementById('emptyCanvas')
    // Eden 21-01-29 处理兼容性,火狐浏览器必须加上
    let ctx = canvas.getContext('2d')
    let stream_canvas = canvas.captureStream() || canvas.mozCaptureStream();

    
    videoTrack_media = stream_canvas.getVideoTracks()[0].clone();

上面的方案中我推荐方案2,方案2是同步方法,可以加快入会速度。

3. 创建空的stream,并绑定track

track创建完之后,注意还要和stream绑定,所以还需要创建空的stream,分别绑定上面创建audioTrack和videoTrack。

  	var stream_media = new MediaStream(); // 提前视频流
	stream_media .addTrack(audioTrack_media);
	stream_media .addTrack(videoTrack_media);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值