gpt4 book ai didi

javascript - 使用 VueJS 的 WebRTC : Why the remote video is not playing?

转载 作者:行者123 更新时间:2023-12-01 01:19:07 25 4
gpt4 key购买 nike

我正在制作一个示例应用程序,其中有两个视频元素和一个“调用”按钮。第一个视频元素 (#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按钮时,远程视频没有显示任何内容,而是看到一个加载圆圈,如屏幕截图所示。也没有控制台错误。

enter image description here

我已经调试并看到本地和远程视频的srcObject,它们看起来是相同的 - enter image description here谁能告诉我我是否做错了什么?还有其他方法可以调试吗?

注意:

项目/源代码可以从这里下载,如果需要的话可以下载并检查代码。我会尝试准备一个codepen - https://drive.google.com/open?id=1e7C0ojZ0jT7EXFNtCKcWpJBpKd_mWi_s

最佳答案

在没有async/await的情况下使用promise需要propagating errors manually并检查它们。

添加一个catch,例如在这里查看错误:

this.pc1.createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
.then(this.gotDescription)
.catch(e => console.log(e)); // <-- here

...您应该看到 thisgotDescription() 内是 undefined。这是因为您将成员函数作为回调传递给 then 函数,该函数最终会在没有 this 的情况下调用它。使用 this.gotDescription.bind(this) 或(更好的)箭头函数。例如:

this.pc1.createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
.then(offer => this.gotDescription(offer)) // arrow function invoking on this
.catch(e => console.log(e));

此外,除非你return all the promises ,它们不会形成一个单一的链来捕获所有错误。

所有这些调用都会返回您忽略的 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());
}

关于javascript - 使用 VueJS 的 WebRTC : Why the remote video is not playing?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54413579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com