From c12b6605943e822ace37464afed030b2a1de48ef Mon Sep 17 00:00:00 2001 From: 4gray Date: Tue, 5 May 2026 10:55:09 +0200 Subject: [PATCH] fix(embedded-mpv): do not restart the stream on every volume change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same root cause as the loading-loop fix: the session-creation effect read this.volume() while building startSession's initialVolume argument, which made volume a tracked dependency of the effect. Each volume tick re-ran the effect, the cleanup disposed the active session, and a fresh one was created — which for VOD/series meant restarting playback from the beginning. Read volume via untracked() inside the effect. The value is only needed once at session creation; subsequent volume changes flow through controller.applyVolume() and never go near the effect. Co-Authored-By: Claude Opus 4.7 (1M context) Entire-Checkpoint: f957cd9849e0 --- .../embedded-mpv-player/embedded-mpv-player.component.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libs/ui/playback/src/lib/embedded-mpv-player/embedded-mpv-player.component.ts b/libs/ui/playback/src/lib/embedded-mpv-player/embedded-mpv-player.component.ts index b04b2f501..e9001a79b 100644 --- a/libs/ui/playback/src/lib/embedded-mpv-player/embedded-mpv-player.component.ts +++ b/libs/ui/playback/src/lib/embedded-mpv-player/embedded-mpv-player.component.ts @@ -10,6 +10,7 @@ import { inject, input, signal, + untracked, viewChild, } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; @@ -271,10 +272,14 @@ export class EmbeddedMpvPlayerComponent implements OnDestroy { return; } + // volume is read untracked so adjusting it during playback does + // not re-trigger this effect (which would tear down and recreate + // the session, restarting the stream from the beginning). + // Subsequent volume changes flow through controller.applyVolume. const teardown = this.controller.startSession( viewport.nativeElement, playback, - this.volume() + untracked(() => this.volume()) ); onCleanup(teardown); });