Skip to content

Commit

Permalink
fix: video audio
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaohaodu committed Jun 1, 2024
1 parent 8f16e6e commit 6b32ff0
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 15 deletions.
20 changes: 16 additions & 4 deletions packages/web-chat-x-vue/src/classes/PeerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class PeerManager {
public remoteUser: Ref<ChatUserInfo> | undefined;
public elDialogVisible: Ref<boolean>;
public communication: Ref<{
caller: string;
answer: string;
await: boolean;
call: boolean;
accepted: boolean;
Expand Down Expand Up @@ -97,14 +99,21 @@ export class PeerManager {
);
}

const callPreRequest = { type: "call_pre_request", video, audio };
this.communication.value.video = video;
this.communication.value.audio = audio;
this.communication.value.caller = this.nearPeerId.value;
this.communication.value.answer = this.remotePeerId.value;
const callPreRequest = {
type: "call_pre_request",
...this.communication.value,
};
// let responseReceived = false;

// 为数据通道上的响应设置侦听器
const onResponse = (event: any) => {
if (
event.type === "call_pre_response" &&
event.from === this.remotePeerId.value
event.answer === this.remotePeerId.value
) {
// responseReceived = true;
this.dataConnect.value?.removeListener("data", onResponse); // Remove the listener once response is received
Expand Down Expand Up @@ -173,7 +182,7 @@ export class PeerManager {
await this.waitForVideoReady(this.remoteVideoElement.value!);
this.elDialogVisible.value = true;
});
this.mediaConnect.value!.on("close", this.releaseMediaStream);
this.mediaConnect.value.on("close", this.releaseMediaStream);
} catch (error) {
console.error("Error setting up media after acceptance:", error);
this.releaseMediaStream();
Expand All @@ -187,6 +196,8 @@ export class PeerManager {
this.elDialogVisible.value = true;
this.communication.value.video = event.video;
this.communication.value.audio = event.audio;
this.communication.value.answer = event.answer;
this.communication.value.caller = event.caller;
// 在继续之前等待用户通过UI提示的响应
await new Promise<void>((resolve) => {
const timeIntervalStart = () => {
Expand All @@ -206,7 +217,6 @@ export class PeerManager {
// 通过数据通道发送呼叫反馈
await this.dataConnect.value?.send({
type: "call_pre_response",
from: this.nearPeerId.value,
...this.communication.value,
});
if (!this.communication.value.accepted) {
Expand Down Expand Up @@ -267,6 +277,8 @@ export class PeerManager {
}
this.communication.value.await = true;
this.communication.value.accepted = false;
this.communication.value.caller = "";
this.communication.value.answer = "";
if (this.mediaStream.value) {
const tracks = this.mediaStream.value.getTracks();
tracks.forEach((track) => track.stop());
Expand Down
17 changes: 13 additions & 4 deletions packages/web-chat-x-vue/src/components/PeerVideoComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@
class="flex flex-col items-center justify-between"
>
<template #header>
<div v-if="friend" class="flex items-center">
<div v-if="communication.caller" class="flex items-center">
<img
:src="friend?.avatar"
:src="caller?.avatar"
alt="User Avatar"
class="w-12 h-12 rounded-full mr-2"
/>
<el-tooltip
:content="`${friend?.name}@${friend?.id}`"
:content="`${caller?.name}@${caller?.id}`"
placement="top"
>
<p class="text-gray-800 break-all line-clamp-1 w-36 text-ellipsis">
{{ `${friend?.name}@${friend?.id}` }}
{{ `${caller?.name}@${caller?.id}` }}
</p>
</el-tooltip>
</div>
Expand Down Expand Up @@ -98,12 +98,21 @@ const elDialogVisible = ref(true);
const remoteVideoElement = ref() as Ref<HTMLVideoElement>;
const nearVideoElement = ref() as Ref<HTMLVideoElement>;
const communication = ref({
answer: "",
caller: "",
await: true,
call: false,
accepted: false,
video: false,
audio: false,
});
const caller = computed(() => {
return (
(communication.value.caller &&
libp2pManager.getFriend(communication.value.caller)) ||
undefined
);
});
peerManager.remoteVideoElement = remoteVideoElement;
peerManager.nearVideoElement = nearVideoElement;
peerManager.elDialogVisible = elDialogVisible;
Expand Down
30 changes: 23 additions & 7 deletions packages/web-chat-x-vue/src/components/SetAudioVideoComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,29 @@
<script lang="ts" setup>
// import useLibp2p from "@/hooks/useLibp2p";
// const { libp2pManager } = useLibp2p();
import usePeer from "@/hooks/usePeer";
const { peerManager } = usePeer();
const videoDevices = ref((await peerManager.getCameras()).slice(0, 1));
const currentVideo = ref<MediaDeviceInfo>(videoDevices.value[0]);
const microphoneDevices = ref((await peerManager.getMicrophones()).slice(0, 1));
const currentMicrophone = ref<MediaDeviceInfo>(microphoneDevices.value[0]);
const speakerDevices = ref((await peerManager.getSpeakers()).slice(0, 1));
const currentSpeaker = ref<MediaDeviceInfo>(speakerDevices.value[0]);
// 使用 Promise.all 并行获取所有设备信息
const [videoDevicesRaw, microphoneDevicesRaw, speakerDevicesRaw] =
await Promise.all([
peerManager.getCameras(),
peerManager.getMicrophones(),
peerManager.getSpeakers(),
]);
// 由于您只想取每个设备类型的前一个设备,所以我们使用 slice 方法
const videoDevices = ref(videoDevicesRaw.slice(0, 1));
const currentVideo = ref<MediaDeviceInfo>(videoDevices.value[0] ?? undefined);
const microphoneDevices = ref(microphoneDevicesRaw.slice(0, 1));
const currentMicrophone = ref<MediaDeviceInfo>(
microphoneDevices.value[0] ?? undefined
);
const speakerDevices = ref(speakerDevicesRaw.slice(0, 1));
const currentSpeaker = ref<MediaDeviceInfo>(
speakerDevices.value[0] ?? undefined
);
</script>

0 comments on commit 6b32ff0

Please sign in to comment.