From 8c883d5481bda458412dec743fe2e3d77df70ddc Mon Sep 17 00:00:00 2001 From: Opti1337 Date: Sat, 25 Jul 2026 16:58:02 +0600 Subject: [PATCH] =?UTF-8?q?=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B4=D0=B5=D0=BC=D0=BE=D0=BD=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/app/app.vue | 1 + client/app/components.d.ts | 2 + client/app/components/ShareScreenDialog.vue | 139 ++++++++++++++++++++ client/app/composables/use-app.ts | 24 +++- client/app/composables/use-devices.ts | 5 +- client/app/composables/use-mediasoup.ts | 39 ++---- client/app/composables/use-preferences.ts | 3 - client/app/pages/preferences.vue | 26 ---- 8 files changed, 175 insertions(+), 64 deletions(-) create mode 100644 client/app/components/ShareScreenDialog.vue diff --git a/client/app/app.vue b/client/app/app.vue index 0bc76cc..4fed445 100644 --- a/client/app/app.vue +++ b/client/app/app.vue @@ -4,6 +4,7 @@ + + + diff --git a/client/app/composables/use-app.ts b/client/app/composables/use-app.ts index 27ae756..48b0c77 100644 --- a/client/app/composables/use-app.ts +++ b/client/app/composables/use-app.ts @@ -1,3 +1,5 @@ +import type { ShareSettings } from '~/components/ShareScreenDialog.vue' +import { ShareScreenDialog } from '#components' import { getVersion } from '@tauri-apps/api/app' import { openUrl as tauriOpenUrl } from '@tauri-apps/plugin-opener' import { computedAsync, createGlobalState } from '@vueuse/core' @@ -8,6 +10,7 @@ export const useApp = createGlobalState(() => { const mediasoup = useMediasoup() const signaling = useSignaling() const { emit } = useEventBus() + const dialog = useDialog() const ready = ref(false) const isTauri = computed(() => '__TAURI_INTERNALS__' in window) @@ -125,8 +128,25 @@ export const useApp = createGlobalState(() => { async function toggleShare() { if (!mediasoup.shareProducer.value) { - await mediasoup.enableShare() - emit('share:enabled') + const { close } = dialog.open(ShareScreenDialog, { + props: { + header: 'Share settings', + modal: true, + draggable: false, + closable: false, + dismissableMask: true, + style: { + width: '440px', + }, + }, + emits: { + onShare: async (settings: ShareSettings) => { + await mediasoup.enableShare(settings) + emit('share:enabled') + close() + }, + }, + }) } else { await mediasoup.disableProducer(mediasoup.shareProducer.value) diff --git a/client/app/composables/use-devices.ts b/client/app/composables/use-devices.ts index 878f10b..86b98e3 100644 --- a/client/app/composables/use-devices.ts +++ b/client/app/composables/use-devices.ts @@ -9,12 +9,11 @@ export const useDevices = createGlobalState(() => { audioOutputs, } = useDevicesList() - async function getShareStream(fps = 30) { + async function getShareStream(fps = 30, resolution = 1080) { return navigator.mediaDevices.getDisplayMedia({ audio: false, video: { - width: { max: 1920 }, - height: { max: 1080 }, + height: { max: resolution }, displaySurface: 'monitor', frameRate: { ideal: fps, max: fps }, }, diff --git a/client/app/composables/use-mediasoup.ts b/client/app/composables/use-mediasoup.ts index 1eaa293..955d792 100644 --- a/client/app/composables/use-mediasoup.ts +++ b/client/app/composables/use-mediasoup.ts @@ -1,5 +1,6 @@ import type { ChadClient, Consumer, Producer } from '#shared/types' import type { MediaKind, ProducerOptions } from 'mediasoup-client/types' +import type { ShareSettings } from '~/components/ShareScreenDialog.vue' import { createSharedComposable } from '@vueuse/core' import * as mediasoupClient from 'mediasoup-client' import { shallowRef } from 'vue' @@ -85,12 +86,11 @@ export const useMediasoup = createSharedComposable(() => { return device.value = new mediasoupClient.Device() - rtpCapabilities.value = await signaling.socket.value.emitWithAck('getRtpCapabilities') + const routerRtpCapabilities = await signaling.socket.value.emitWithAck('getRtpCapabilities') - await device.value.load({ routerRtpCapabilities: rtpCapabilities.value! }) + await device.value.load({ routerRtpCapabilities }) - console.log('SERVER RTP CAPABILITIES', rtpCapabilities.value) - console.log('СОГЛАСОВАННЫЕ', device.value.rtpCapabilities) + rtpCapabilities.value = device.value.rtpCapabilities // Send transport { @@ -450,51 +450,30 @@ export const useMediasoup = createSharedComposable(() => { }) } - async function enableShare() { + async function enableShare(settings: ShareSettings) { if (shareProducer.value) return if (!device.value) return - const stream = await getShareStream(preferences.shareFps.value) + const stream = await getShareStream(settings.fps) const track = stream.getVideoTracks()[0] if (!track) return - console.log('settings', track.getSettings()) track.contentHint = 'motion' await createProducer({ track, streamId: 'share', - codec: device.value.rtpCapabilities.codecs?.find( - c => c.mimeType.toLowerCase() === 'video/h264', - ), - // c => c.mimeType.toLowerCase() === 'video/h264' && c.parameters['profile-level-id'] === '42e01f', - // codec: device.value.rtpCapabilities.codecs?.find( - // c => c.mimeType.toLowerCase() === 'video/av1', - // ), - // codec: device.value.rtpCapabilities.codecs?.find( - // c => c.mimeType.toLowerCase() === 'video/vp9', - // ), - // codec: { - // kind: 'video', - // mimeType: 'video/AV1', - // clockRate: 90000, - // parameters: { - // 'level-idx': 13, // Level 4.1 — 1080p60 - // 'profile': 0, // Main Profile - // 'tier': 0, // Main tier (0) vs High tier (1) - // 'x-google-start-bitrate': 8000, - // }, - // }, + codec: settings.codec, encodings: [ { - maxBitrate: 120_000_000, - maxFramerate: 60, + // maxBitrate: 120_000_000, + maxFramerate: settings.fps, scalabilityMode: 'L1T1', networkPriority: 'high', }, diff --git a/client/app/composables/use-preferences.ts b/client/app/composables/use-preferences.ts index f8d7c51..39b7b8d 100644 --- a/client/app/composables/use-preferences.ts +++ b/client/app/composables/use-preferences.ts @@ -20,8 +20,6 @@ export const usePreferences = createGlobalState(() => { const noiseSuppression = useLocalStorage('NOISE_SUPPRESSION', true) const echoCancellation = useLocalStorage('ECHO_CANCELLATION', true) - const shareFps = useLocalStorage('SHARE_FPS', 30) - const toggleInputHotkey = ref('') const toggleOutputHotkey = ref('') @@ -65,7 +63,6 @@ export const usePreferences = createGlobalState(() => { autoGainControl, noiseSuppression, echoCancellation, - shareFps, toggleInputHotkey, toggleOutputHotkey, inputDeviceExist, diff --git a/client/app/pages/preferences.vue b/client/app/pages/preferences.vue index 1305e97..91ba509 100644 --- a/client/app/pages/preferences.vue +++ b/client/app/pages/preferences.vue @@ -66,24 +66,6 @@ - - Screen sharing - - -
-

- FPS -

- -
-