cat / goq
clone

turns a linux box into a private steam streaming appliance: plug in, tap your key, play from another computer

release/portal-packaging
goq / portal / av-sync.test.mjs
av-sync.test.mjs 2.4K
1import assert from 'node:assert/strict';2import test from 'node:test';34import {5 audioMinusVideoSkewMs,6 audioOutputTimelineFromStats,7 exactMediaTimestampMicros,8 formatSignedMilliseconds,9 isCurrentAvSyncEpoch,10 nextAvSyncEpoch,11 projectAudioMediaPtsMicros,12} from './av-sync.mjs';1314test('media timestamps stay exact and reject fallback clock values', () => {15 assert.equal(exactMediaTimestampMicros(123_456), 123_456);16 assert.equal(exactMediaTimestampMicros(12.5), null);17 assert.equal(exactMediaTimestampMicros(-1), null);18 assert.equal(exactMediaTimestampMicros(Number.MAX_SAFE_INTEGER + 1), null);19});2021test('A/V epochs reject pre-reset deliveries and wrap safely', () => {22 assert.equal(nextAvSyncEpoch(0), 1);23 assert.equal(nextAvSyncEpoch(Number.MAX_SAFE_INTEGER), 0);24 assert.equal(isCurrentAvSyncEpoch(1, 1), true);25 assert.equal(isCurrentAvSyncEpoch(0, 1), false);26 assert.equal(isCurrentAvSyncEpoch(1.5, 1), false);27 assert.throws(() => nextAvSyncEpoch(-1), /invalid A\/V sync epoch/);28});2930test('audio output projection aligns worklet and performance clock snapshots', () => {31 const timeline = audioOutputTimelineFromStats({32 renderedMediaEndPtsMicros: 2_000_000,33 outputContextTimeEndSeconds: 4,34 });35 assert.deepEqual(timeline, {36 mediaEndPtsMicros: 2_000_000,37 outputContextTimeEndSeconds: 4,38 });39 const projected = projectAudioMediaPtsMicros(40 timeline,41 { contextTime: 3.9, performanceTime: 1000 },42 1025,43 );44 assert.ok(Math.abs(projected - 1_925_000) < 0.001);45});4647test('projection declines to guess without an authoritative output timestamp', () => {48 const timeline = {49 mediaEndPtsMicros: 2_000_000,50 outputContextTimeEndSeconds: 4,51 };52 assert.equal(projectAudioMediaPtsMicros(timeline, null, 1000), null);53 assert.equal(54 projectAudioMediaPtsMicros(timeline, { contextTime: 0, performanceTime: 0 }, 1000),55 null,56 );57 assert.equal(58 projectAudioMediaPtsMicros(null, { contextTime: 4, performanceTime: 1000 }, 1000),59 null,60 );61 assert.equal(audioOutputTimelineFromStats({ renderedMediaEndPtsMicros: null }), null);62});6364test('signed skew explicitly reports audio ahead and audio behind', () => {65 assert.equal(audioMinusVideoSkewMs(1_925_000, 1_900_000), 25);66 assert.equal(audioMinusVideoSkewMs(1_875_000, 1_900_000), -25);67 assert.equal(formatSignedMilliseconds(25), '+25.0');68 assert.equal(formatSignedMilliseconds(-25), '−25.0');69 assert.equal(formatSignedMilliseconds(Number.NaN), null);70});