桌面增加音频

This commit is contained in:
kura 2026-05-07 23:25:45 +08:00
parent 3ce1c07383
commit b958957ca5
2 changed files with 103 additions and 3 deletions

View File

@ -7,8 +7,15 @@
<div
v-if="isRemoteDesktopActive && !isDesktopCollapsed"
class="desktop-overlay"
@mousemove="handleOverlayMouseMove"
@mouseleave="handleOverlayMouseLeave"
>
<div class="overlay-header">
<div
class="overlay-header"
:class="{
'fullscreen-hidden': isFullscreen && !isFullscreenHeaderVisible,
}"
>
<div class="header-left">
<svg
width="18"
@ -28,6 +35,41 @@
}}</span>
</div>
<div class="header-right">
<button
v-if="desktopStream"
class="header-btn"
:class="{ 'sound-enabled': isDesktopSoundEnabled }"
@click="toggleDesktopSound"
:title="isDesktopSoundEnabled ? '静音' : '开启声音'"
>
<svg
v-if="isDesktopSoundEnabled"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
<path d="M19.07 4.93a10 10 0 0 1 0 14.14" />
<path d="M15.54 8.46a5 5 0 0 1 0 7.07" />
</svg>
<svg
v-else
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
<line x1="23" y1="9" x2="17" y2="15" />
<line x1="17" y1="9" x2="23" y2="15" />
</svg>
<span>{{ isDesktopSoundEnabled ? "出声" : "静音" }}</span>
</button>
<button
v-if="desktopStream"
class="header-btn"
@ -759,7 +801,10 @@ const isCameraActive = ref(false);
const isCameraLocalSharing = ref(false);
const isCallActive = ref(false);
const isFullscreen = ref(false);
const isFullscreenHeaderVisible = ref(false);
const isCallMuted = ref(false);
const isDesktopSoundEnabled = ref(false);
let fullscreenHeaderTimer: number | null = null;
const isDesktopCollapsed = ref(false);
const isDesktopShareCollapsed = ref(false);
const isCameraCollapsed = ref(false);
@ -851,7 +896,7 @@ const bindDesktopVideo = async () => {
if (videoRef.value.srcObject !== desktopStream.value) {
videoRef.value.srcObject = desktopStream.value;
}
videoRef.value.muted = true;
videoRef.value.muted = !isDesktopSoundEnabled.value;
videoRef.value.play().catch(() => {
message.warning("浏览器阻止了自动播放,请点击桌面画面恢复播放");
});
@ -1045,6 +1090,13 @@ const toggleCallMuted = () => {
}
};
const toggleDesktopSound = () => {
isDesktopSoundEnabled.value = !isDesktopSoundEnabled.value;
if (videoRef.value) {
videoRef.value.muted = !isDesktopSoundEnabled.value;
}
};
const toggleFullscreen = async () => {
if (!videoContainer.value) return;
try {
@ -1064,6 +1116,35 @@ const toggleFullscreen = async () => {
const handleFullscreenChange = () => {
isFullscreen.value = !!document.fullscreenElement;
isFullscreenHeaderVisible.value = false;
};
const handleOverlayMouseMove = (event: MouseEvent) => {
if (!isFullscreen.value) return;
if (event.clientY < 80) {
isFullscreenHeaderVisible.value = true;
if (fullscreenHeaderTimer !== null) {
clearTimeout(fullscreenHeaderTimer);
fullscreenHeaderTimer = null;
}
} else if (
isFullscreenHeaderVisible.value &&
fullscreenHeaderTimer === null
) {
fullscreenHeaderTimer = window.setTimeout(() => {
isFullscreenHeaderVisible.value = false;
fullscreenHeaderTimer = null;
}, 2000);
}
};
const handleOverlayMouseLeave = () => {
if (!isFullscreen.value) return;
if (fullscreenHeaderTimer !== null) {
clearTimeout(fullscreenHeaderTimer);
fullscreenHeaderTimer = null;
}
isFullscreenHeaderVisible.value = false;
};
const streamListener: EventListener = (event) => {
@ -1103,6 +1184,10 @@ onUnmounted(() => {
peer.off("call-started", callStartedListener);
peer.off("media-ended", mediaEndedListener);
document.removeEventListener("fullscreenchange", handleFullscreenChange);
if (fullscreenHeaderTimer !== null) {
clearTimeout(fullscreenHeaderTimer);
fullscreenHeaderTimer = null;
}
stopDurationTimer();
desktopStream.value?.getTracks().forEach((track) => track.stop());
cameraStream.value?.getTracks().forEach((track) => track.stop());
@ -1154,6 +1239,11 @@ onUnmounted(() => {
background: rgba(0, 0, 0, 0.9);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
flex-shrink: 0;
transition: opacity 0.3s ease;
}
.overlay-header.fullscreen-hidden {
opacity: 0;
pointer-events: none;
}
.header-left {
@ -1194,6 +1284,16 @@ onUnmounted(() => {
border-color: #f5222d;
color: #f5222d;
}
.header-btn.sound-enabled {
background: rgba(0, 180, 42, 0.15);
border-color: #00b42a;
color: #00b42a;
}
.header-btn.sound-enabled:hover {
background: rgba(0, 180, 42, 0.25);
border-color: #00b42a;
color: #00d439;
}
.duration-text {
font-size: 12px;

View File

@ -114,7 +114,7 @@ class Peer extends EventTarget {
if (type === "desktop") {
stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: false,
audio: true,
});
} else if (type === "camera") {
stream = await navigator.mediaDevices.getUserMedia({