javascript - Peerjs 流重复(发送两次或更多次),有时不显示任何流
问题描述
我正在尝试使用 Express、Socket.IO、PeerJS、Vue3 和 Ionic 制作视频聊天应用程序。我在将流发送到对等方时遇到问题,因为它被发送了两次,有时更多有时它在没有发送任何流的情况下滞后,但在 peerjs cli 上显示连接。
Vue(客户端代码):
<template>
<ion-page>
<ion-header :translucent="true">
<ion-toolbar>
<ion-title>Chat</ion-title>
</ion-toolbar>
</ion-header>
<ion-content :fullscreen="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Chat</ion-title>
</ion-toolbar>
</ion-header>
<ion-grid>
<ion-row class="ion-justify-content-center">
<ion-col>
<VideoStream
v-if="webCamVideoReady && webCamStream"
:stream="webCamStream"
/>
</ion-col>
</ion-row>
<ion-row>
<ion-col v-for="(stream, i) in usersVideoStreams" :key="i">
<VideoStream :stream="stream" />
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
</ion-page>
</template>
<script>
import {
IonContent,
IonHeader,
IonList,
IonPage,
IonRefresher,
IonRefresherContent,
IonTitle,
IonToolbar,
IonGrid,
IonRow,
IonCol
} from "@ionic/vue";
import VideoStream from "@/components/VideoStream";
import io from "socket.io-client";
import Peer from "peerjs";
import { baseURL } from "../main";
import { ref, onMounted } from "vue";
export default {
name: "Chat",
components: {
IonContent,
IonHeader,
IonList,
IonPage,
IonRefresher,
IonRefresherContent,
IonTitle,
IonToolbar,
IonGrid,
IonRow,
IonCol,
VideoStream
},
props: ["roomId"],
setup({ roomId }) {
const socket = io(baseURL);
const peer = new Peer(undefined, {
host: "/",
port: 4000
});
const webCamStream = ref(null);
const webCamVideoReady = ref(false);
const usersVideoStreams = ref([]);
onMounted(() => {
navigator.mediaDevices
.getUserMedia({
video: true,
audio: true
})
.then(stream => {
webCamStream.value = stream;
webCamVideoReady.value = true;
peer.on("call", call => {
call.answer(stream);
call.on("stream", userVideoStream => {
usersVideoStreams.value.push(userVideoStream);
});
});
socket.on("user-connected", userId => {
const call = peer.call(userId, stream);
call.on("stream", userVideoStream => {
usersVideoStreams.value.push(userVideoStream);
});
// call.on("close", () => {});
});
});
});
peer.on("open", id => {
socket.emit("join-room", roomId, id);
});
return { webCamVideoReady, webCamStream, usersVideoStreams };
}
};
</script>
视频流 Vue 组件:
<template>
<video
ref="webCamVideo"
@loadedmetadata="webCamVideo.play()"
muted
oncontextmenu="return false;"
></video>
</template>
<script>
import { onMounted, ref, watch, watchEffect } from "vue";
export default {
name: "VideoStream",
props: ["stream"],
setup(props) {
const webCamVideo = ref(null);
onMounted(() => {
webCamVideo.value.srcObject = props.stream;
});
return { webCamVideo };
}
};
</script>
对等点和套接字连接:
const socket = io(baseURL);
const peer = new Peer(undefined, {
host: "/",
port: 4000
});
使用命令运行 Peerjs
peerjs --port 4000
Node.js 服务器端 Socket.IO 代码
const io = require("socket.io")();
io.on("connection", socket => {
socket.on("join-room", (roomId, userId) => {
console.log(roomId, userId);
socket.join(roomId);
socket.broadcast.to(roomId).emit("user-connected", userId);
});
});
module.exports = { io };
解决方案
推荐阅读
- flutter - 更改整个页面的状态与颤动中的一个按钮
- javascript - 为什么我已经安装了错误查找模块
- python - 在 Python 中修改列表中的值
- python - 如何在具有用户模型外键的模型中定义 __str__() 方法并获取 Django 中字段的值?
- openstreetmap - 如何使用 LineString 将 OSM 关系转换为 GeoJSON?
- excel - 将表格从 Excel 粘贴到 Word 后删除多余段落
- html - html 表格可滚动时始终显示滚动条
- mysql - 每日最大值的最早时间
- javascript - 在 Laravel 中创建一个动态创建另一个下拉列表的下拉列表
- java - 我如何在android中制作如下图所示的菜单