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>