feat(embedded-mpv): configurable extra libmpv options and network auto-reconnect (#1515)

Extra libmpv options (Settings > Playback) reach every embedded engine off the command line (createSession array on Windows/macOS, a 0600 --include file on Linux native-view, a stdin preamble for the frame-copy helper); the keys the embed depends on are refused, and keys libmpv rejects are reported once per session. Dropped streams reload automatically (error, or ended on live) with 2 s -> 30 s backoff, six attempts per outage and a 30 s stability reset, only for a load that already played; engine failures stay terminal, a running recording is filed as interrupted and restarted after the reload, and an external subtitle file is re-added. Settings.embeddedMpvAutoReconnect (default on) opts out; the player shows 'Reconnecting... attempt N of M'.

Started by Bpl5966 in #1515 and finished by the maintainers in the same PR.

Co-authored-by: Bpl5966 <amine.b1959@gmail.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ZoultandClaude Fable 5.1 authored and GitHub committed 2026-09-04 16:36:14 +02:00
1 parent 6cfdaf5900
commit 5a11b82eaf
66 files changed
+3740 -101

No files matched your search

@@ -1,8 +1,4 @@
<section
class="settings-group"
id="playback"
[formGroup]="form()"
>
<section class="settings-group" id="playback" [formGroup]="form()">
<header class="settings-group__header">
<div class="settings-group__header-icon">
<mat-icon>play_circle</mat-icon>
@@ -235,6 +231,101 @@
</div>
}
@if (form().value.player === 'embedded-mpv') {
<div
class="setting-item"
data-test-id="embedded-mpv-extra-options-setting"
>
<div class="setting-item__meta">
<h4>
{{ 'SETTINGS.EMBEDDED_MPV_EXTRA_OPTIONS' | translate }}
</h4>
<p>
{{
'SETTINGS.EMBEDDED_MPV_EXTRA_OPTIONS_DESCRIPTION'
| translate
}}
</p>
</div>
<div class="setting-item__control">
<mat-form-field
appearance="outline"
subscriptSizing="dynamic"
>
<mat-label for="embeddedMpvExtraOptions">{{
'SETTINGS.EMBEDDED_MPV_EXTRA_OPTIONS' | translate
}}</mat-label>
<textarea
matInput
id="embeddedMpvExtraOptions"
formControlName="embeddedMpvExtraOptions"
placeholder="hwdec=auto-safe"
rows="3"
spellcheck="false"
autocomplete="off"
></textarea>
<mat-hint>{{
'SETTINGS.EMBEDDED_MPV_EXTRA_OPTIONS_HINT'
| translate
}}</mat-hint>
@if (
form().get('embeddedMpvExtraOptions')?.errors;
as errors
) {
<mat-error
data-test-id="embedded-mpv-extra-options-error"
>
@if (errors['forbiddenKeys']) {
{{
'SETTINGS.EMBEDDED_MPV_EXTRA_OPTIONS_FORBIDDEN_KEYS'
| translate
: {
keys: errors[
'forbiddenKeys'
].join(', '),
}
}}
} @else if (errors['invalidLines']) {
{{
'SETTINGS.EMBEDDED_MPV_EXTRA_OPTIONS_INVALID_LINES'
| translate
: {
lines: errors[
'invalidLines'
].join(', '),
}
}}
}
</mat-error>
}
</mat-form-field>
</div>
</div>
<div
class="setting-item"
data-test-id="embedded-mpv-auto-reconnect-setting"
>
<div class="setting-item__meta">
<h4>
{{ 'SETTINGS.EMBEDDED_MPV_AUTO_RECONNECT' | translate }}
</h4>
<p>
{{
'SETTINGS.EMBEDDED_MPV_AUTO_RECONNECT_DESCRIPTION'
| translate
}}
</p>
</div>
<div class="setting-item__control setting-item__toggle">
<mat-checkbox
formControlName="embeddedMpvAutoReconnect"
data-test-id="embedded-mpv-auto-reconnect-toggle"
></mat-checkbox>
</div>
</div>
}
<div class="setting-item" data-test-id="recording-folder-setting">
<div class="setting-item__meta">
<h4>{{ 'SETTINGS.RECORDING_FOLDER_LABEL' | translate }}</h4>