使用uniapp播放webrtc流

1,742 阅读1分钟

uniapp播放webrtc流只能使用renderjs实现,uniapp中提供renderjs可以操作原生dom,能直接拿到真实video元素,并且给它设置srcObject,以下为代码实现:

1.template中找一个元素给它设置rtcUrl即:

<view :rtcUrl="rtcUrl" :change:rtcUrl="onChangeRtcUrl"></view>

<script>
// 这是页面默认的script实现
export default {
    data() {
        return {
            rtcUrl: '',
        }
    },
    methods: {
        trackChange(state) {
            console.log(state)
        }
    },
}
</script>

2.新增一个renderjs实现监听rtcUrl


<script module="rtc" lang="renderjs">
	import axios from 'axios'
	let rtc = null
	export default {
		data() {
			return {
				webrtcReqUrl: '',
			}
		},

		methods: {
			onChangeMuted(muted) {
				const video = document.querySelector('#pageVideoWrap video');
				if (video) {
					video.muted = muted
				}
			},
			onChangeRtcUrl(val, oldVal) {
				console.log('rtc url change: ', val)
				if (val) {
					this.webrtcReqUrl = val
					this.initRtc()
				} else {
					rtc && rtc.close()
					const video = document.querySelector('#pageVideoWrap video');
					if (video) {
						video.srcObject = null;
					}
				}
			},
			initRtc() {
				rtc = new RTCPeerConnection();
				rtc.addTransceiver('video', {
					direction: 'recvonly',
				});
				rtc.addTransceiver('audio', {
					direction: 'recvonly',
				});
				let video = document.querySelector('#pageVideoWrap video');
				if (!video) {
					video = document.createElement('video')
					video.style.width = '100%'
					document.querySelector('#pageVideoWrap').appendChild(video)
				}
				video.style.background = 'none'
				video.setAttribute('src', '');
				video.setAttribute("webkit-playsinline", "");
				video.setAttribute("playsinline", "");
				video.setAttribute("autoplay", "");
				video.onloadedmetadata = () => {
					video.play();
				};
				rtc.ontrack = (t) => {
					video.srcObject = t.streams[0]
					t.receiver.track.onmute = (event) => {
						console.log('流中断:', JSON.stringify(event));
                                                // 通知主程序
						this.$ownerInstance.callMethod('trackChange', true)
					};
					t.receiver.track.onunmute = (err) => {
						console.log('流继续:', JSON.stringify(err));
						this.$ownerInstance.callMethod('trackChange', false)
					};
				};
				rtc.createOffer().then((localDescription) => {
					rtc.setLocalDescription(localDescription).then(() => {
						axios({
							method: 'post',
							url: this.webrtcReqUrl,
							data: rtc.localDescription?.toJSON().sdp,
							header: {
								'Content-Type': "application/sdp"
							},
						}).then(res => {
							if (res.data) {
								const sessionDescriptio = new RTCSessionDescription({
									sdp: res.data,
									type: 'answer',
								});
								rtc.setRemoteDescription(sessionDescriptio);
							}
						})
					});
				});
			}
		},
		mounted() {}
	}
</script>