Fix Opus duration reporting so seekbar and visualizer work
Surface the sidecar duration on the first Opus chunk instead of gating it on the first decoded buffers; C# locks UI Duration on chunk 1, and async WebCodecs decode left it at 0 — killing seek and the duration-gated visualizer.
This commit is contained in:
@@ -229,14 +229,21 @@ export class AudioPlayer {
|
||||
const decoder = this.opusDecoder!;
|
||||
const buffers = await decoder.push(chunk);
|
||||
|
||||
// Duration is known up front from the sidecar — surface it as soon as the decoder reports it,
|
||||
// NOT gated on the first decoded buffers. The C# layer locks Duration on the first chunk whose
|
||||
// result carries a value (the `Duration == null` guard), and WebCodecs decode is async, so the
|
||||
// earliest chunks can return zero buffers; gating duration on buffers means C# captures the
|
||||
// initial 0 and never overwrites it — the WAV header path sets duration on chunk 1 because its
|
||||
// header parses synchronously, which is the asymmetry this closes. Set once so a seek (which
|
||||
// reinitialises the decoder) cannot overwrite it.
|
||||
if (this.duration === 0 && decoder.totalDuration) {
|
||||
this.duration = decoder.totalDuration;
|
||||
}
|
||||
|
||||
if (buffers.length > 0) {
|
||||
for (const buffer of buffers) {
|
||||
this.scheduler.addBuffer(buffer);
|
||||
}
|
||||
// Duration is known up front from the sidecar; set once (a seek must not overwrite it).
|
||||
if (this.duration === 0 && decoder.totalDuration) {
|
||||
this.duration = decoder.totalDuration;
|
||||
}
|
||||
if (this.streamingStarted && this.isPlaying) {
|
||||
this.scheduler.scheduleNewBuffers();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user