From 2fb5fb1abb3f04a5064740be4cfa7cbe1af9a84d Mon Sep 17 00:00:00 2001 From: Hampus Date: Fri, 2 Oct 2026 14:08:41 +0200 Subject: [PATCH] fix(voice): allow av1 and vp9 screen shares in firefox (#3108) --- fluxer_app/pkgs/livekit-client/src/index.ts | 2 ++ .../src/room/participant/LocalParticipant.ts | 11 ++++++- .../pkgs/livekit-client/src/room/utils.ts | 9 +++--- .../voice_screen_share_manager/shared.ts | 2 ++ .../voice/utils/CodecCapabilityDetector.ts | 29 ++++--------------- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/fluxer_app/pkgs/livekit-client/src/index.ts b/fluxer_app/pkgs/livekit-client/src/index.ts index 7502be326..06866a392 100644 --- a/fluxer_app/pkgs/livekit-client/src/index.ts +++ b/fluxer_app/pkgs/livekit-client/src/index.ts @@ -54,6 +54,7 @@ import { supportsAV1, supportsDynacast, supportsH265, + supportsScalabilityMode, supportsVideoCodec, supportsVP9, } from './room/utils.ts'; @@ -176,6 +177,7 @@ export { supportsAV1, supportsDynacast, supportsH265, + supportsScalabilityMode, supportsVideoCodec, supportsVP9, TrackPublication, diff --git a/fluxer_app/pkgs/livekit-client/src/room/participant/LocalParticipant.ts b/fluxer_app/pkgs/livekit-client/src/room/participant/LocalParticipant.ts index 84eee12b7..7b121a7ae 100644 --- a/fluxer_app/pkgs/livekit-client/src/room/participant/LocalParticipant.ts +++ b/fluxer_app/pkgs/livekit-client/src/room/participant/LocalParticipant.ts @@ -110,6 +110,7 @@ import { selectPreferredVideoCodec, sleep, stopTransceiversForSender, + supportsScalabilityMode, supportsVideoCodec, usesLegacySVCEncodings, } from '../utils.ts'; @@ -978,6 +979,9 @@ export default class LocalParticipant extends Participant { } const videoCodec = opts.videoCodec; + if (!supportsScalabilityMode()) { + delete opts.scalabilityMode; + } track.on(TrackEvent.Muted, this.onTrackMuted); track.on(TrackEvent.Unmuted, this.onTrackUnmuted); @@ -1055,7 +1059,12 @@ export default class LocalParticipant extends Participant { } const svcSimulcast = isSVCSimulcast(videoCodec, opts); - if (isSVCCodec(videoCodec) && !svcSimulcast && track.source !== Track.Source.ScreenShare) { + if ( + isSVCCodec(videoCodec) && + !svcSimulcast && + track.source !== Track.Source.ScreenShare && + supportsScalabilityMode() + ) { opts.scalabilityMode = opts.scalabilityMode ?? 'L3T3_KEY'; } diff --git a/fluxer_app/pkgs/livekit-client/src/room/utils.ts b/fluxer_app/pkgs/livekit-client/src/room/utils.ts index 2f56ef0bd..884d6e534 100644 --- a/fluxer_app/pkgs/livekit-client/src/room/utils.ts +++ b/fluxer_app/pkgs/livekit-client/src/room/utils.ts @@ -66,7 +66,7 @@ export function supportsDynacast() { } export function supportsAV1(): boolean { - if (isSafari() || isFireFox()) { + if (isSafari()) { return false; } return hasSenderMimeType('video/av1') || hasSenderMimeType('video/av1x'); @@ -80,9 +80,6 @@ export function supportsH265(): boolean { } export function supportsVP9(): boolean { - if (isFireFox()) { - return false; - } if (isSafari()) { const browser = getBrowser(); if (browser?.version && compareVersions(browser.version, '16') < 0) { @@ -133,6 +130,10 @@ function hasSenderMimeType(mimeType: string): boolean { return capabilities.codecs.some((codec) => codec.mimeType.toLowerCase() === lower); } +export function supportsScalabilityMode(): boolean { + return !isFireFox(); +} + export function isSVCCodec(codec?: string): boolean { return codec === 'av1' || codec === 'vp9'; } diff --git a/fluxer_app/src/features/voice/engine/voice_screen_share_manager/shared.ts b/fluxer_app/src/features/voice/engine/voice_screen_share_manager/shared.ts index ac0dc6a10..c512a67b4 100644 --- a/fluxer_app/src/features/voice/engine/voice_screen_share_manager/shared.ts +++ b/fluxer_app/src/features/voice/engine/voice_screen_share_manager/shared.ts @@ -37,6 +37,7 @@ import { type LocalTrackPublication, type LocalVideoTrack, type ScreenShareCaptureOptions, + supportsScalabilityMode, Track, type TrackPublishOptions, type VideoCodec, @@ -265,6 +266,7 @@ function resolveScreenShareEncoding(target: ScreenShareTarget, publishOptions?: } function getScreenShareLayeringForCodec(codec: VideoCodec | undefined): ScreenShareLayering { + if (!supportsScalabilityMode()) return {simulcast: false, scalabilityMode: undefined}; return resolveScreenShareLayering({ codec, svcSetting: VoiceSettings.getScreenShareScalabilityModeOverride(), diff --git a/fluxer_app/src/features/voice/utils/CodecCapabilityDetector.ts b/fluxer_app/src/features/voice/utils/CodecCapabilityDetector.ts index 356f76396..0846c54b4 100644 --- a/fluxer_app/src/features/voice/utils/CodecCapabilityDetector.ts +++ b/fluxer_app/src/features/voice/utils/CodecCapabilityDetector.ts @@ -182,29 +182,12 @@ function getScreenShareCodecPolicyUnsupported( 'H.265 (HEVC) screen sharing is off by default because it may cause compatibility issues for viewers. We’re working on improving this. Turn on H.265 screen sharing in Advanced settings to use it.', }; } - if (context.firefox) { - switch (codec) { - case 'av1': - return { - supported: false, - reason: 'unsupported-browser', - detail: 'Firefox doesn\u2019t support AV1 encoding for WebRTC yet.', - }; - case 'vp9': - return { - supported: false, - reason: 'unsupported-browser', - detail: 'Firefox\u2019s WebRTC stack doesn\u2019t expose VP9 as a publishable codec.', - }; - case 'h265': - return { - supported: false, - reason: 'unsupported-browser', - detail: 'Firefox doesn\u2019t support H.265 encoding for WebRTC.', - }; - default: - break; - } + if (context.firefox && codec === 'h265') { + return { + supported: false, + reason: 'unsupported-browser', + detail: 'Firefox doesn\u2019t support H.265 encoding for WebRTC.', + }; } return null; }