[英]WebRTC using VueJS: Why the remote video is not playing?
我正在制作一個示例應用程序,其中將有兩個視頻元素和一個“呼叫”按鈕。 第一個視頻元素( #localVideo
)將顯示本地媒體流的輸出。 當我按下通話按鈕時,遠程視頻元素將播放遠程媒體流。 我已經在原始JavaScript中制作了相同的應用程序,效果很好。
在VueJS中,我正在制作一個WebRTC組件來獲取用戶媒體並將流設置為本地視頻元素。 當用戶按下呼叫按鈕時,我將創建兩個RTCPeerConnection
對象,發送報價,設置本地描述,發送答案以及全部。
這是組件的模板-
<template>
<div class="webRTC">
<video id = "localVideo" playsinline autoplay muted></video>
<button id = "call" v-on:click='call'> Call </button>
<video id = "remoteVideo" playsinline autoplay controls></video>
</div>
</template>
<script src="./webRTC.js"></script>
這是該組件的腳本-
export default {
name: 'webRTC',
sockets: {
connect: function () {
console.log('Socket IO connected!')
},
TestConnection: function () {
console.log('Test connection successful!')
}
},
data: function () {
return {
localStream: null,
remoteStream: null,
pc1: null,
pc2: null
}
},
methods: {
call: function () {
this.pc1 = new RTCPeerConnection()
this.pc1.addEventListener('icecandidate', e => this.addIceCandidate(this.pc1, e))
this.pc2 = new RTCPeerConnection()
this.pc2.addEventListener('icecandidate', e => this.addIceCandidate(this.pc2, e))
this.pc2.addEventListener('track', this.gotRemoteStrem)
this.localStream.getTracks().forEach(track => {
console.log('Adding local stream')
this.pc1.addTrack(track, this.localStream)
})
this.pc1.createOffer({ offerToReceiveAudio: 1, offerToReceiveVideo: 1 }).then(this.gotDescription)
},
gotRemoteStrem: function (event) {
console.log('Got Remote stream')
let remoteVideo = document.querySelector('#remoteVideo')
this.remoteStream = event.streams[0]
remoteVideo.srcObject = event.streams[0]
},
gotDescription: function (description) {
console.log('Got description 1')
this.pc1.setLocalDescription(description)
this.pc2.setRemoteDescription(description)
this.pc2.createAnswer().then(this.gotDescription2)
},
gotDescription2: function (description) {
console.log('Got description 2')
this.pc2.setLocalDescription(description)
this.pc1.setRemoteDescription(description)
},
addIceCandidate: function (pc, event) {
this.getOtherPC(pc).addIceCandidate(event.candidate).then(this.addIceCandicateSuccess).catch(this.addIceCandicateFailure)
},
addIceCandicateSuccess: function () {
console.log('Ice candidate added successfully')
},
addIceCandicateFailure: function () {
console.log('Ice candidate failure')
},
getOtherPC: function (pc) {
if (pc === this.pc1) {
return this.pc2
}
return this.pc1
},
gotDevices: function (stream) {
let localVideo = document.querySelector('#localVideo')
this.localStream = stream
localVideo.srcObject = stream
},
handleMediaError: function (error) {
console.error('Error:' + error.name)
}
},
created: function () {
console.log('webRTC is created!')
let prom = navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(this.gotDevices).catch(this.handleMediaError)
}
}
本地視頻顯示正常。 我面臨的問題是,當我按下“ Call
按鈕時,遠程視頻沒有顯示任何內容,而是在屏幕截圖中看到了一個加載圓圈。 也沒有控制台錯誤。
我已經調試並看到了本地和遠程視頻的srcObject
,它們似乎是相同的- 誰能告訴我我做錯了什么嗎? 還有其他方法可以調試嗎?
注意:
可以從此處下載項目/源代碼,如果需要,可以下載並檢查代碼。 我將嘗試准備一個代碼筆-https://drive.google.com/open ? id = 1e7C0ojZ0jT7EXFNtCKcWpJBpKd_mWi_s
使用沒有async
/ await
promise需要手動傳播錯誤並進行檢查。
添加一個catch
例如在這里查看錯誤:
this.pc1.createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
.then(this.gotDescription)
.catch(e => console.log(e)); // <-- here
...並且您應該看到在gotDescription()
中this
是undefined
。 那是因為您要將成員函數作為回調傳遞給then
函數,而最終沒有使用this
調用它。 使用this.gotDescription.bind(this)
或(nicer)箭頭功能。 例如:
this.pc1.createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
.then(offer => this.gotDescription(offer)) // arrow function invoking on this
.catch(e => console.log(e));
此外,除非您返回所有的Promise ,否則它們不會形成捕獲所有錯誤的單一鏈。
所有這些調用都會返回promise,您將忽略它們:
/* const unusedPromise1 = */ this.pc1.setLocalDescription(description)
/* const unusedPromise2 = */ this.pc2.setRemoteDescription(description)
/* const unusedPromise3 = */ this.pc2.createAnswer().then(this.gotDescription2)
幸運的是(可能令人困惑), RTCPeerConnection自動將在其上進行的操作排隊,因此,如果沒有錯誤(可能會被瀏覽器吞沒),這可以實際起作用。
相反,要捕獲錯誤,請執行以下操作:
this.pc1.setLocalDescription(description)
.then(() => this.pc2.setRemoteDescription(description))
.then(() => this.pc2.createAnswer())
.then(answer => this.gotDescription2(answer))
.catch(e => console.log(e))
或使用更好的async
/ await
語法正確傳播錯誤:
gotDescription: async function (description) {
console.log('Got description 1')
await this.pc1.setLocalDescription(description)
await this.pc2.setRemoteDescription(description)
await this.gotDescription2(await this.pc2.createAnswer());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.