@axsnull/audio-sync-engine 1.2.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,5 @@
1
- import { PlayerState, TrackMetadata, type PlayerStateSyncConfig } from "./player-state-sync";
2
- import type { ReducePlayerUpdateResult } from "./playback-state-reducer";
3
- export interface AudioSyncEngineConfig extends PlayerStateSyncConfig {
1
+ import { PlayerState, TrackMetadata } from "./player-state-sync";
2
+ export interface AudioSyncEngineConfig {
4
3
  syncIntervalMs?: number;
5
4
  bufferMinSeconds?: number;
6
5
  bufferMaxSeconds?: number;
@@ -19,7 +18,7 @@ export declare class AudioSyncEngine {
19
18
  private loadTrackFn;
20
19
  constructor(_sendPing: (timestamp: number) => Promise<number>, config?: AudioSyncEngineConfig);
21
20
  initialize(audio: HTMLAudioElement, loadTrack: (trackId: string) => Promise<TrackMetadata>): Promise<void>;
22
- handlePlayerUpdate(state: PlayerState, lastEventSeq?: number): Promise<ReducePlayerUpdateResult>;
21
+ handlePlayerUpdate(state: PlayerState): Promise<void>;
23
22
  performPeriodicSync(): Promise<void>;
24
23
  scheduleSynchronizedStart(serverStartAt: number): Promise<{
25
24
  startAt: number;
@@ -29,8 +28,6 @@ export declare class AudioSyncEngine {
29
28
  getSyncedNow(): number;
30
29
  getClockOffset(): number;
31
30
  getClockLatency(): number;
32
- getLastState(): PlayerState | null;
33
- getLastAppliedStateVersion(): number;
34
31
  stop(): void;
35
32
  private createAudioAdapter;
36
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audio-sync-engine.d.ts","sourceRoot":"","sources":["../src/audio-sync-engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,WAAW,EACX,aAAa,EACb,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAI7B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAE9C,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,WAAW,CACZ;gBAGL,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EACjD,MAAM,GAAE,qBAA0B;IA6B9B,UAAU,CACd,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC;IAQV,kBAAkB,CACtB,KAAK,EAAE,WAAW,EAClB,YAAY,GAAE,MAAU,GACvB,OAAO,CAAC,wBAAwB,CAAC;IA2B9B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBpC,yBAAyB,CAC7B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAkBxC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,YAAY,IAAI,MAAM;IAItB,cAAc,IAAI,MAAM;IAIxB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,WAAW,GAAG,IAAI;IAIlC,0BAA0B,IAAI,MAAM;IAIpC,IAAI,IAAI,IAAI;IAMZ,OAAO,CAAC,kBAAkB;CAgB3B"}
1
+ {"version":3,"file":"audio-sync-engine.d.ts","sourceRoot":"","sources":["../src/audio-sync-engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,WAAW,EACX,aAAa,EACd,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAE9C,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,WAAW,CACZ;gBAGL,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EACjD,MAAM,GAAE,qBAA0B;IAyB9B,UAAU,CACd,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC;IAQV,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BrD,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBpC,yBAAyB,CAC7B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAkBxC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,YAAY,IAAI,MAAM;IAItB,cAAc,IAAI,MAAM;IAIxB,eAAe,IAAI,MAAM;IAIzB,IAAI,IAAI,IAAI;IAMZ,OAAO,CAAC,kBAAkB;CAgB3B"}
@@ -17,11 +17,7 @@ class AudioSyncEngine {
17
17
  this.audioClock = new audio_clock_1.AudioClock();
18
18
  this.driftDetector = new drift_detector_1.DriftDetector(this.clockSync);
19
19
  this.driftCorrector = new drift_corrector_1.DriftCorrector();
20
- this.playerStateSync = new player_state_sync_1.PlayerStateSync({
21
- deviceId: config.deviceId,
22
- seekDriftThresholdSeconds: config.seekDriftThresholdSeconds,
23
- activationDriftThresholdSeconds: config.activationDriftThresholdSeconds,
24
- });
20
+ this.playerStateSync = new player_state_sync_1.PlayerStateSync();
25
21
  this.synchronizedStart = new synchronized_start_1.SynchronizedStart();
26
22
  const bufferConfig = {
27
23
  minBufferSeconds: config.bufferMinSeconds ?? 3,
@@ -41,7 +37,7 @@ class AudioSyncEngine {
41
37
  await this.clockSync.sync();
42
38
  this.periodicSync.start();
43
39
  }
44
- async handlePlayerUpdate(state, lastEventSeq = 0) {
40
+ async handlePlayerUpdate(state) {
45
41
  if (!this.currentAudio || !this.loadTrackFn) {
46
42
  throw new Error("AudioSyncEngine not initialized");
47
43
  }
@@ -57,7 +53,7 @@ class AudioSyncEngine {
57
53
  }
58
54
  },
59
55
  };
60
- return this.playerStateSync.handlePlayerUpdate(state, audioAdapter, this.loadTrackFn, lastEventSeq);
56
+ this.playerStateSync.handlePlayerUpdate(state, audioAdapter, this.loadTrackFn);
61
57
  }
62
58
  async performPeriodicSync() {
63
59
  if (!this.currentAudio) {
@@ -99,12 +95,6 @@ class AudioSyncEngine {
99
95
  getClockLatency() {
100
96
  return this.clockSync.getLatency();
101
97
  }
102
- getLastState() {
103
- return this.playerStateSync.getLastState();
104
- }
105
- getLastAppliedStateVersion() {
106
- return this.playerStateSync.getLastAppliedStateVersion();
107
- }
108
98
  stop() {
109
99
  this.periodicSync.stop();
110
100
  this.audioClock.stop();
@@ -1 +1 @@
1
- {"version":3,"file":"audio-sync-engine.js","sourceRoot":"","sources":["../src/audio-sync-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audio-sync-engine.js","sourceRoot":"","sources":["../src/audio-sync-engine.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,8 +2,7 @@ export { ClockSync, type ClockSyncResult, type PingPongMessage, } from "./clock-
2
2
  export { AudioClock } from "./audio-clock";
3
3
  export { DriftDetector, type DriftResult, type ServerState, } from "./drift-detector";
4
4
  export { DriftCorrector, type CorrectionResult, type AudioElement, } from "./drift-corrector";
5
- export { PlayerStateSync, type PlayerStateSyncAudioAdapter, type PlayerStateSyncConfig, type PlayerState, type TrackMetadata, } from "./player-state-sync";
6
- export { getPlayerStateVersion, isSamePlayerSnapshot, isPlayerStateActiveForDevice, shouldApplyActiveDeviceChange, reduceIncomingPlayerUpdate, type PlayerUpdateRejectReason, type ReducePlayerUpdateResult, } from "./playback-state-reducer";
5
+ export { PlayerStateSync, type PlayerState, type TrackMetadata, } from "./player-state-sync";
7
6
  export { PeriodicSync, type SyncConfig } from "./periodic-sync";
8
7
  export { SynchronizedStart, type StartSchedule } from "./synchronized-start";
9
8
  export { BufferManager, type BufferConfig } from "./buffer-manager";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,eAAe,EACf,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,eAAe,EACf,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AudioSyncEngine = exports.BufferManager = exports.SynchronizedStart = exports.PeriodicSync = exports.reduceIncomingPlayerUpdate = exports.shouldApplyActiveDeviceChange = exports.isPlayerStateActiveForDevice = exports.isSamePlayerSnapshot = exports.getPlayerStateVersion = exports.PlayerStateSync = exports.DriftCorrector = exports.DriftDetector = exports.AudioClock = exports.ClockSync = void 0;
3
+ exports.AudioSyncEngine = exports.BufferManager = exports.SynchronizedStart = exports.PeriodicSync = exports.PlayerStateSync = exports.DriftCorrector = exports.DriftDetector = exports.AudioClock = exports.ClockSync = void 0;
4
4
  var clock_sync_1 = require("./clock-sync");
5
5
  Object.defineProperty(exports, "ClockSync", { enumerable: true, get: function () { return clock_sync_1.ClockSync; } });
6
6
  var audio_clock_1 = require("./audio-clock");
@@ -11,12 +11,6 @@ var drift_corrector_1 = require("./drift-corrector");
11
11
  Object.defineProperty(exports, "DriftCorrector", { enumerable: true, get: function () { return drift_corrector_1.DriftCorrector; } });
12
12
  var player_state_sync_1 = require("./player-state-sync");
13
13
  Object.defineProperty(exports, "PlayerStateSync", { enumerable: true, get: function () { return player_state_sync_1.PlayerStateSync; } });
14
- var playback_state_reducer_1 = require("./playback-state-reducer");
15
- Object.defineProperty(exports, "getPlayerStateVersion", { enumerable: true, get: function () { return playback_state_reducer_1.getPlayerStateVersion; } });
16
- Object.defineProperty(exports, "isSamePlayerSnapshot", { enumerable: true, get: function () { return playback_state_reducer_1.isSamePlayerSnapshot; } });
17
- Object.defineProperty(exports, "isPlayerStateActiveForDevice", { enumerable: true, get: function () { return playback_state_reducer_1.isPlayerStateActiveForDevice; } });
18
- Object.defineProperty(exports, "shouldApplyActiveDeviceChange", { enumerable: true, get: function () { return playback_state_reducer_1.shouldApplyActiveDeviceChange; } });
19
- Object.defineProperty(exports, "reduceIncomingPlayerUpdate", { enumerable: true, get: function () { return playback_state_reducer_1.reduceIncomingPlayerUpdate; } });
20
14
  var periodic_sync_1 = require("./periodic-sync");
21
15
  Object.defineProperty(exports, "PeriodicSync", { enumerable: true, get: function () { return periodic_sync_1.PeriodicSync; } });
22
16
  var synchronized_start_1 = require("./synchronized-start");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAIsB;AAHpB,uGAAA,SAAS,OAAA;AAIX,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,mDAI0B;AAHxB,+GAAA,aAAa,OAAA;AAIf,qDAI2B;AAHzB,iHAAA,cAAc,OAAA;AAIhB,yDAM6B;AAL3B,oHAAA,eAAe,OAAA;AAMjB,mEAQkC;AAPhC,+HAAA,qBAAqB,OAAA;AACrB,8HAAA,oBAAoB,OAAA;AACpB,sIAAA,4BAA4B,OAAA;AAC5B,uIAAA,6BAA6B,OAAA;AAC7B,oIAAA,0BAA0B,OAAA;AAI5B,iDAAgE;AAAvD,6GAAA,YAAY,OAAA;AACrB,2DAA6E;AAApE,uHAAA,iBAAiB,OAAA;AAC1B,mDAAoE;AAA3D,+GAAA,aAAa,OAAA;AACtB,yDAG6B;AAF3B,oHAAA,eAAe,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAIsB;AAHpB,uGAAA,SAAS,OAAA;AAIX,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,mDAI0B;AAHxB,+GAAA,aAAa,OAAA;AAIf,qDAI2B;AAHzB,iHAAA,cAAc,OAAA;AAIhB,yDAI6B;AAH3B,oHAAA,eAAe,OAAA;AAIjB,iDAAgE;AAAvD,6GAAA,YAAY,OAAA;AACrB,2DAA6E;AAApE,uHAAA,iBAAiB,OAAA;AAC1B,mDAAoE;AAA3D,+GAAA,aAAa,OAAA;AACtB,yDAG6B;AAF3B,oHAAA,eAAe,OAAA"}
@@ -1,4 +1,3 @@
1
- import { type ReducePlayerUpdateResult } from "./playback-state-reducer";
2
1
  export interface PlayerState {
3
2
  userId: string;
4
3
  activeDeviceId: string | null;
@@ -16,35 +15,21 @@ export interface TrackMetadata {
16
15
  duration: number;
17
16
  source: "s3" | "cdn" | "proxy";
18
17
  }
19
- export interface PlayerStateSyncAudioAdapter {
20
- currentTime: number;
21
- src: string;
22
- play: () => void | Promise<void>;
23
- pause: () => void;
24
- setCurrentTime: (value: number) => void;
25
- }
26
- export interface PlayerStateSyncConfig {
27
- deviceId?: string | null;
28
- seekDriftThresholdSeconds?: number;
29
- activationDriftThresholdSeconds?: number;
30
- }
31
18
  export declare class PlayerStateSync {
32
19
  private currentTrackId;
33
20
  private currentStreamUrl;
34
21
  private lastState;
35
- private readonly deviceId;
36
- private readonly seekDriftThresholdSeconds;
37
- private readonly activationDriftThresholdSeconds;
38
- private lastAppliedStateVersion;
39
- constructor(config?: PlayerStateSyncConfig);
40
- handlePlayerUpdate(state: PlayerState, audio: PlayerStateSyncAudioAdapter, loadTrack: (trackId: string) => Promise<TrackMetadata>, lastEventSeq?: number): Promise<ReducePlayerUpdateResult>;
22
+ handlePlayerUpdate(state: PlayerState, audio: {
23
+ currentTime: number;
24
+ src: string;
25
+ play: () => void;
26
+ pause: () => void;
27
+ setCurrentTime: (value: number) => void;
28
+ }, loadTrack: (trackId: string) => Promise<TrackMetadata>): void;
41
29
  private loadNewTrack;
42
30
  private syncPosition;
43
- private pauseIfNeeded;
44
- private playIfNeeded;
45
31
  getCurrentTrackId(): string | null;
46
32
  getCurrentStreamUrl(): string | null;
47
33
  getLastState(): PlayerState | null;
48
- getLastAppliedStateVersion(): number;
49
34
  }
50
35
  //# sourceMappingURL=player-state-sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"player-state-sync.d.ts","sourceRoot":"","sources":["../src/player-state-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,+BAA+B,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAS;IACnD,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAS;IACzD,OAAO,CAAC,uBAAuB,CAAK;gBAExB,MAAM,GAAE,qBAA0B;IAOxC,kBAAkB,CACtB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,2BAA2B,EAClC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,EACtD,YAAY,GAAE,MAAU,GACvB,OAAO,CAAC,wBAAwB,CAAC;YA4EtB,YAAY;IAiB1B,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,aAAa;YAIP,YAAY;IAM1B,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAIlC,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAIpC,YAAY,IAAI,WAAW,GAAG,IAAI;IAIlC,0BAA0B,IAAI,MAAM;CAGrC"}
1
+ {"version":3,"file":"player-state-sync.d.ts","sourceRoot":"","sources":["../src/player-state-sync.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,OAAO,CAAC;CAChC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,SAAS,CAA4B;IAE7C,kBAAkB,CAChB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,IAAI,CAAC;QACjB,KAAK,EAAE,MAAM,IAAI,CAAC;QAClB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;KACzC,EACD,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,GACrD,IAAI;YAqBO,YAAY;IAgB1B,OAAO,CAAC,YAAY;IAgBpB,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAIlC,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAIpC,YAAY,IAAI,WAAW,GAAG,IAAI;CAGnC"}
@@ -1,74 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PlayerStateSync = void 0;
4
- const playback_state_reducer_1 = require("./playback-state-reducer");
5
4
  class PlayerStateSync {
6
- constructor(config = {}) {
5
+ constructor() {
7
6
  this.currentTrackId = null;
8
7
  this.currentStreamUrl = null;
9
8
  this.lastState = null;
10
- this.lastAppliedStateVersion = 0;
11
- this.deviceId = config.deviceId ?? null;
12
- this.seekDriftThresholdSeconds = config.seekDriftThresholdSeconds ?? 0.35;
13
- this.activationDriftThresholdSeconds =
14
- config.activationDriftThresholdSeconds ?? 0.2;
15
9
  }
16
- async handlePlayerUpdate(state, audio, loadTrack, lastEventSeq = 0) {
17
- console.log('[PlayerStateSync] handlePlayerUpdate:', {
18
- trackId: state.trackId,
19
- isPlaying: state.isPlaying,
20
- positionMs: state.positionMs,
21
- activeDeviceId: state.activeDeviceId,
22
- deviceId: this.deviceId,
23
- lastEventSeq,
24
- currentTrackId: this.currentTrackId
25
- });
26
- const reduceResult = (0, playback_state_reducer_1.reduceIncomingPlayerUpdate)(state, this.lastState, lastEventSeq);
27
- if (!reduceResult.shouldApply) {
28
- console.log('[PlayerStateSync] Ignoring state:', reduceResult.reason);
29
- return reduceResult;
10
+ handlePlayerUpdate(state, audio, loadTrack) {
11
+ this.lastState = state;
12
+ if (state.trackId !== this.currentTrackId && state.trackId) {
13
+ this.loadNewTrack(state.trackId, audio, loadTrack);
30
14
  }
31
- const nextState = reduceResult.state;
32
- const stateVersion = (0, playback_state_reducer_1.getPlayerStateVersion)(nextState);
33
- if (stateVersion < this.lastAppliedStateVersion) {
34
- console.log('[PlayerStateSync] Stale version:', {
35
- stateVersion,
36
- lastAppliedStateVersion: this.lastAppliedStateVersion
37
- });
38
- return {
39
- shouldApply: false,
40
- reason: "stale_version",
41
- version: stateVersion,
42
- };
43
- }
44
- this.lastAppliedStateVersion = stateVersion;
45
- this.lastState = nextState;
46
- const isActiveDevice = (0, playback_state_reducer_1.isPlayerStateActiveForDevice)(nextState, this.deviceId);
47
- if (!isActiveDevice) {
48
- console.log('[PlayerStateSync] Not active device, pausing');
49
- this.pauseIfNeeded(audio);
50
- return reduceResult;
51
- }
52
- if (nextState.trackId !== this.currentTrackId && nextState.trackId) {
53
- console.log('[PlayerStateSync] Loading new track:', nextState.trackId);
54
- await this.loadNewTrack(nextState.trackId, audio, loadTrack);
55
- }
56
- console.log('[PlayerStateSync] Syncing position:', {
57
- serverPosition: nextState.positionMs,
58
- serverUpdatedAt: nextState.updatedAt,
59
- isPlaying: nextState.isPlaying,
60
- currentAudioTime: audio.currentTime
61
- });
62
- this.syncPosition(nextState.positionMs, nextState.updatedAt, nextState.isPlaying, audio);
63
- if (nextState.isPlaying) {
64
- console.log('[PlayerStateSync] Playing');
65
- await this.playIfNeeded(audio);
15
+ if (state.isPlaying) {
16
+ audio.play();
66
17
  }
67
18
  else {
68
- console.log('[PlayerStateSync] Pausing');
69
- this.pauseIfNeeded(audio);
19
+ audio.pause();
70
20
  }
71
- return reduceResult;
21
+ this.syncPosition(state.positionMs, state.updatedAt, state.isPlaying, audio);
72
22
  }
73
23
  async loadNewTrack(trackId, audio, loadTrack) {
74
24
  try {
@@ -77,7 +27,6 @@ class PlayerStateSync {
77
27
  this.currentStreamUrl = metadata.streamUrl;
78
28
  audio.src = metadata.streamUrl;
79
29
  audio.currentTime = 0;
80
- audio.load?.();
81
30
  }
82
31
  catch (error) {
83
32
  console.error("Failed to load track:", error);
@@ -85,26 +34,12 @@ class PlayerStateSync {
85
34
  }
86
35
  syncPosition(serverPosition, serverUpdatedAt, isPlaying, audio) {
87
36
  if (!isPlaying) {
88
- const pausedSeconds = serverPosition / 1000;
89
- const pausedDrift = Math.abs(audio.currentTime - pausedSeconds);
90
- if (pausedDrift > this.activationDriftThresholdSeconds) {
91
- audio.setCurrentTime(pausedSeconds);
92
- }
37
+ audio.setCurrentTime(serverPosition / 1000);
93
38
  return;
94
39
  }
95
40
  const elapsed = Date.now() - serverUpdatedAt;
96
41
  const expectedPosition = serverPosition + elapsed;
97
- const expectedSeconds = expectedPosition / 1000;
98
- const driftSeconds = Math.abs(audio.currentTime - expectedSeconds);
99
- if (driftSeconds > this.seekDriftThresholdSeconds) {
100
- audio.setCurrentTime(expectedSeconds);
101
- }
102
- }
103
- pauseIfNeeded(audio) {
104
- audio.pause();
105
- }
106
- async playIfNeeded(audio) {
107
- await Promise.resolve(audio.play());
42
+ audio.setCurrentTime(expectedPosition / 1000);
108
43
  }
109
44
  getCurrentTrackId() {
110
45
  return this.currentTrackId;
@@ -115,9 +50,6 @@ class PlayerStateSync {
115
50
  getLastState() {
116
51
  return this.lastState;
117
52
  }
118
- getLastAppliedStateVersion() {
119
- return this.lastAppliedStateVersion;
120
- }
121
53
  }
122
54
  exports.PlayerStateSync = PlayerStateSync;
123
55
  //# sourceMappingURL=player-state-sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"player-state-sync.js","sourceRoot":"","sources":["../src/player-state-sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"player-state-sync.js","sourceRoot":"","sources":["../src/player-state-sync.ts"],"names":[],"mappings":";;;AAmBA,MAAa,eAAe;IAA5B;QACU,mBAAc,GAAkB,IAAI,CAAC;QACrC,qBAAgB,GAAkB,IAAI,CAAC;QACvC,cAAS,GAAuB,IAAI,CAAC;IA4E/C,CAAC;IA1EC,kBAAkB,CAChB,KAAkB,EAClB,KAMC,EACD,SAAsD;QAEtD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAEvB,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC3D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,YAAY,CACf,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,SAAS,EACf,KAAK,CACN,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,OAAe,EACf,KAA2C,EAC3C,SAAsD;QAEtD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;YAC9B,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,SAAS,CAAC;YAC3C,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;YAC/B,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAEO,YAAY,CAClB,cAAsB,EACtB,eAAuB,EACvB,SAAkB,EAClB,KAAuE;QAEvE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,KAAK,CAAC,cAAc,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC;QAC7C,MAAM,gBAAgB,GAAG,cAAc,GAAG,OAAO,CAAC;QAClD,KAAK,CAAC,cAAc,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AA/ED,0CA+EC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@axsnull/audio-sync-engine",
3
- "version": "1.2.2",
4
- "description": "Prod-grade client-side audio synchronization engine for distributed playback systems",
3
+ "version": "1.4.0",
4
+ "description": "Production-grade client-side audio synchronization engine for distributed playback systems",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
@@ -1,17 +0,0 @@
1
- import type { PlayerState } from "./player-state-sync";
2
- export type PlayerUpdateRejectReason = "stale_version" | "duplicate_snapshot" | "same_version_older_position";
3
- export type ReducePlayerUpdateResult = {
4
- shouldApply: true;
5
- state: PlayerState;
6
- version: number;
7
- } | {
8
- shouldApply: false;
9
- reason: PlayerUpdateRejectReason;
10
- version: number;
11
- };
12
- export declare function getPlayerStateVersion(state: PlayerState | null): number;
13
- export declare function isSamePlayerSnapshot(left: PlayerState, right: PlayerState): boolean;
14
- export declare function isPlayerStateActiveForDevice(state: PlayerState, deviceId: string | null): boolean;
15
- export declare function shouldApplyActiveDeviceChange(currentActiveDeviceId: string | null, incomingDeviceId: string): boolean;
16
- export declare function reduceIncomingPlayerUpdate(incomingState: PlayerState, currentState: PlayerState | null, lastEventSeq: number): ReducePlayerUpdateResult;
17
- //# sourceMappingURL=playback-state-reducer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"playback-state-reducer.d.ts","sourceRoot":"","sources":["../src/playback-state-reducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,MAAM,wBAAwB,GAChC,eAAe,GACf,oBAAoB,GACpB,6BAA6B,CAAC;AAElC,MAAM,MAAM,wBAAwB,GAChC;IACE,WAAW,EAAE,IAAI,CAAC;IAClB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,WAAW,EAAE,KAAK,CAAC;IACnB,MAAM,EAAE,wBAAwB,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAMvE;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,WAAW,GACjB,OAAO,CAST;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,OAAO,CAIT;AAED,wBAAgB,6BAA6B,CAC3C,qBAAqB,EAAE,MAAM,GAAG,IAAI,EACpC,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAET;AAED,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,WAAW,EAC1B,YAAY,EAAE,WAAW,GAAG,IAAI,EAChC,YAAY,EAAE,MAAM,GACnB,wBAAwB,CAwC1B"}
@@ -1,63 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPlayerStateVersion = getPlayerStateVersion;
4
- exports.isSamePlayerSnapshot = isSamePlayerSnapshot;
5
- exports.isPlayerStateActiveForDevice = isPlayerStateActiveForDevice;
6
- exports.shouldApplyActiveDeviceChange = shouldApplyActiveDeviceChange;
7
- exports.reduceIncomingPlayerUpdate = reduceIncomingPlayerUpdate;
8
- function getPlayerStateVersion(state) {
9
- if (!state) {
10
- return 0;
11
- }
12
- return Math.max(state.updatedAt ?? 0, state.lastServerSyncAt ?? 0);
13
- }
14
- function isSamePlayerSnapshot(left, right) {
15
- return (left.trackId === right.trackId &&
16
- left.isPlaying === right.isPlaying &&
17
- left.positionMs === right.positionMs &&
18
- left.activeDeviceId === right.activeDeviceId &&
19
- left.updatedAt === right.updatedAt &&
20
- left.lastServerSyncAt === right.lastServerSyncAt);
21
- }
22
- function isPlayerStateActiveForDevice(state, deviceId) {
23
- return Boolean(deviceId && state.activeDeviceId && state.activeDeviceId === deviceId);
24
- }
25
- function shouldApplyActiveDeviceChange(currentActiveDeviceId, incomingDeviceId) {
26
- return currentActiveDeviceId !== incomingDeviceId;
27
- }
28
- function reduceIncomingPlayerUpdate(incomingState, currentState, lastEventSeq) {
29
- const incomingVersion = getPlayerStateVersion(incomingState);
30
- const currentVersion = getPlayerStateVersion(currentState);
31
- if (incomingVersion < lastEventSeq || incomingVersion < currentVersion) {
32
- return {
33
- shouldApply: false,
34
- reason: "stale_version",
35
- version: incomingVersion,
36
- };
37
- }
38
- if (currentState && isSamePlayerSnapshot(incomingState, currentState)) {
39
- return {
40
- shouldApply: false,
41
- reason: "duplicate_snapshot",
42
- version: incomingVersion,
43
- };
44
- }
45
- if (currentState &&
46
- incomingVersion === currentVersion &&
47
- incomingState.trackId === currentState.trackId &&
48
- incomingState.activeDeviceId === currentState.activeDeviceId &&
49
- incomingState.isPlaying === currentState.isPlaying &&
50
- incomingState.positionMs < currentState.positionMs) {
51
- return {
52
- shouldApply: false,
53
- reason: "same_version_older_position",
54
- version: incomingVersion,
55
- };
56
- }
57
- return {
58
- shouldApply: true,
59
- state: incomingState,
60
- version: incomingVersion,
61
- };
62
- }
63
- //# sourceMappingURL=playback-state-reducer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"playback-state-reducer.js","sourceRoot":"","sources":["../src/playback-state-reducer.ts"],"names":[],"mappings":";;AAmBA,sDAMC;AAED,oDAYC;AAED,oEAOC;AAED,sEAKC;AAED,gEA4CC;AAlFD,SAAgB,qBAAqB,CAAC,KAAyB;IAC7D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,EAAE,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,SAAgB,oBAAoB,CAClC,IAAiB,EACjB,KAAkB;IAElB,OAAO,CACL,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO;QAC9B,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;QAClC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;QACpC,IAAI,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc;QAC5C,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;QAClC,IAAI,CAAC,gBAAgB,KAAK,KAAK,CAAC,gBAAgB,CACjD,CAAC;AACJ,CAAC;AAED,SAAgB,4BAA4B,CAC1C,KAAkB,EAClB,QAAuB;IAEvB,OAAO,OAAO,CACZ,QAAQ,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,KAAK,QAAQ,CACtE,CAAC;AACJ,CAAC;AAED,SAAgB,6BAA6B,CAC3C,qBAAoC,EACpC,gBAAwB;IAExB,OAAO,qBAAqB,KAAK,gBAAgB,CAAC;AACpD,CAAC;AAED,SAAgB,0BAA0B,CACxC,aAA0B,EAC1B,YAAgC,EAChC,YAAoB;IAEpB,MAAM,eAAe,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAE3D,IAAI,eAAe,GAAG,YAAY,IAAI,eAAe,GAAG,cAAc,EAAE,CAAC;QACvE,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,MAAM,EAAE,eAAe;YACvB,OAAO,EAAE,eAAe;SACzB,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,IAAI,oBAAoB,CAAC,aAAa,EAAE,YAAY,CAAC,EAAE,CAAC;QACtE,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,MAAM,EAAE,oBAAoB;YAC5B,OAAO,EAAE,eAAe;SACzB,CAAC;IACJ,CAAC;IAED,IACE,YAAY;QACZ,eAAe,KAAK,cAAc;QAClC,aAAa,CAAC,OAAO,KAAK,YAAY,CAAC,OAAO;QAC9C,aAAa,CAAC,cAAc,KAAK,YAAY,CAAC,cAAc;QAC5D,aAAa,CAAC,SAAS,KAAK,YAAY,CAAC,SAAS;QAClD,aAAa,CAAC,UAAU,GAAG,YAAY,CAAC,UAAU,EAClD,CAAC;QACD,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,MAAM,EAAE,6BAA6B;YACrC,OAAO,EAAE,eAAe;SACzB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,WAAW,EAAE,IAAI;QACjB,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,eAAe;KACzB,CAAC;AACJ,CAAC"}