mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 04:55:42 +09:00
fix(voice): keep published codecs inside the opt-in policy (#2422)
This commit is contained in:
1 parent
2426a5769d
commit
902dd60ff9
51 files changed
+1032
-313
No files matched your search
@@ -44,9 +44,14 @@ source edits in this package.
|
||||
OpenH264 software profile.
|
||||
|
||||
8. **Media publishing defaults** (`src/room/defaults.ts`, `src/room/utils.ts`, `src/room/track/options.ts`)
|
||||
Prefers AV1, then HEVC/H.265, H.264, VP9, and VP8 according to actual
|
||||
sender capabilities; pairs advanced codecs with H.264 backup simulcast; and
|
||||
Falls back to H.264, then VP9, VP8, AV1, and HEVC/H.265 according to actual
|
||||
sender capabilities, pairs advanced codecs with H.264 backup simulcast, and
|
||||
uses maintain-resolution screen-share defaults with a 4K60-ready bitrate cap.
|
||||
The order puts AV1 and HEVC last because both are opt-in in Fluxer, so a
|
||||
fallback inside `publishTrack` must not land on a codec the user did not
|
||||
enable. Fluxer picks the codec itself before publishing, so this list only
|
||||
applies when the client overrides the request, such as the reconnect
|
||||
republish that runs outside Fluxer's own flows.
|
||||
|
||||
9. **High-fidelity Opus SDP munging** (`src/room/PCTransport.ts`)
|
||||
Forces Opus RED/FEC, stereo signaling, 10 ms packet time, no DTX, and a
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
import {describe, expect, it} from 'vitest';
|
||||
import {defaultVideoCodec, publishDefaults, roomOptionDefaults} from './defaults.ts';
|
||||
import {BackupCodecPolicy} from './track/options.ts';
|
||||
import {selectPreferredVideoCodec} from './utils.ts';
|
||||
|
||||
describe('Fluxer media publish defaults', () => {
|
||||
it('defaults new video publishes to the advanced codec path with H.264 backup', () => {
|
||||
expect(defaultVideoCodec).toBe('av1');
|
||||
it('defaults new video publishes to an opt-in-safe codec with H.264 backup', () => {
|
||||
expect(defaultVideoCodec).toBe('h264');
|
||||
expect(publishDefaults).toMatchObject({
|
||||
videoCodec: 'av1',
|
||||
videoCodec: 'h264',
|
||||
backupCodec: {codec: 'h264'},
|
||||
backupCodecPolicy: BackupCodecPolicy.SIMULCAST,
|
||||
degradationPreference: 'maintain-resolution',
|
||||
@@ -18,6 +19,12 @@ describe('Fluxer media publish defaults', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('falls back away from the opt-in codecs before reaching them', () => {
|
||||
expect(selectPreferredVideoCodec()).toBe('h264');
|
||||
expect(selectPreferredVideoCodec()).not.toBe('av1');
|
||||
expect(selectPreferredVideoCodec()).not.toBe('h265');
|
||||
});
|
||||
|
||||
it('keeps original screen-share publishing at a 4K60-ready transport ceiling', () => {
|
||||
expect(publishDefaults.screenShareEncoding).toMatchObject({
|
||||
maxBitrate: 20_000_000,
|
||||
|
||||
@@ -6,7 +6,7 @@ import DefaultReconnectPolicy from './DefaultReconnectPolicy.ts';
|
||||
import type {AudioCaptureOptions, TrackPublishDefaults, VideoCaptureOptions} from './track/options.ts';
|
||||
import {AudioPresets, BackupCodecPolicy, ScreenSharePresets, VideoPresets} from './track/options.ts';
|
||||
|
||||
export const defaultVideoCodec = 'av1';
|
||||
export const defaultVideoCodec = 'h264';
|
||||
|
||||
export const publishDefaults: TrackPublishDefaults = {
|
||||
audioPreset: AudioPresets.music,
|
||||
|
||||
@@ -45,12 +45,19 @@ describe('video codec capability helpers', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('uses the advanced publish ladder from real sender capabilities', () => {
|
||||
it('keeps the opt-in codecs last even when sender capabilities offer them', () => {
|
||||
setSenderCapabilities(['video/VP8', 'video/H264', 'video/VP9', 'video/H265', 'video/AV1']);
|
||||
expect(supportsAV1()).toBe(true);
|
||||
expect(supportsH265()).toBe(true);
|
||||
expect(supportsVP9()).toBe(true);
|
||||
expect(selectPreferredVideoCodec()).toBe('av1');
|
||||
expect(selectPreferredVideoCodec()).toBe('h264');
|
||||
});
|
||||
|
||||
it('falls back to VP9 then VP8 before any opt-in codec', () => {
|
||||
setSenderCapabilities(['video/VP8', 'video/VP9', 'video/H265', 'video/AV1']);
|
||||
expect(selectPreferredVideoCodec()).toBe('vp9');
|
||||
setSenderCapabilities(['video/VP8', 'video/H265', 'video/AV1']);
|
||||
expect(selectPreferredVideoCodec()).toBe('vp8');
|
||||
});
|
||||
|
||||
it('treats legacy AV1X as AV1 and falls through to HEVC when AV1 is absent', () => {
|
||||
|
||||
@@ -32,7 +32,7 @@ import type {ChatMessage, LiveKitReactNativeInfo, TranscriptionSegment} from './
|
||||
|
||||
const separator = '|';
|
||||
export const ddExtensionURI = 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
|
||||
const preferredPublishVideoCodecs: ReadonlyArray<VideoCodec> = ['av1', 'h265', 'h264', 'vp9', 'vp8'];
|
||||
const preferredPublishVideoCodecs: ReadonlyArray<VideoCodec> = ['h264', 'vp9', 'vp8', 'av1', 'h265'];
|
||||
|
||||
export function unpackStreamId(packed: string): Array<string> {
|
||||
const parts = packed.split(separator);
|
||||
|
||||
Reference in new issue
Block a user