feat(embedded-mpv): add Windows frame-copy support (#1175)

Port the embedded mpv frame-copy pipeline to Windows with WGL rendering and named shared memory. Includes packaging validation, platform gates, tests, and architecture documentation.
This commit is contained in:
4gray authored and GitHub committed 2026-07-15 21:27:56 +02:00
1 parent 7d75d989e8
commit 59e08fd2d6
41 files changed
+1284 -157

No files matched your search

@@ -184,7 +184,9 @@
</div>
}
@if (supportsExternalPlayerPathSettings() && form().value.player === 'mpv') {
@if (
supportsExternalPlayerPathSettings() && form().value.player === 'mpv'
) {
<div class="setting-item">
<div class="setting-item__meta">
<h4>{{ 'SETTINGS.MPV_PLAYER_PATH_LABEL' | translate }}</h4>
@@ -256,7 +258,9 @@
</div>
}
@if (supportsExternalPlayerPathSettings() && form().value.player === 'vlc') {
@if (
supportsExternalPlayerPathSettings() && form().value.player === 'vlc'
) {
<div class="setting-item">
<div class="setting-item__meta">
<h4>{{ 'SETTINGS.VLC_PLAYER_PATH_LABEL' | translate }}</h4>
@@ -171,6 +171,30 @@ describe('SettingsPlaybackSectionComponent', () => {
).toBeNull();
});
it.each<[string, boolean, boolean, boolean, boolean]>([
['shows the available desktop engine', true, true, false, true],
['keeps a stale desktop opt-in clearable', true, false, true, true],
['hides a stale opt-in in the PWA', false, false, true, false],
])(
'%s',
(_description, isDesktop, frameCopyAvailable, stored, expected) => {
const form = createForm();
form.controls['embeddedMpvFrameCopy'].setValue(stored);
fixture.componentRef.setInput('form', form);
fixture.componentRef.setInput('isDesktop', isDesktop);
fixture.componentRef.setInput(
'frameCopyAvailable',
frameCopyAvailable
);
fixture.detectChanges();
const setting = fixture.nativeElement.querySelector(
'[data-test-id="embedded-mpv-frame-copy-setting"]'
);
expect(Boolean(setting)).toBe(expected);
}
);
it('shows the recording folder setting only in desktop builds', () => {
fixture.componentRef.setInput('isDesktop', true);
fixture.detectChanges();
@@ -364,6 +388,7 @@ function createForm(player = VideoPlayer.VideoJs): FormGroup {
streamFormat: new FormControl(StreamFormat.AutoStreamFormat),
openStreamOnDoubleClick: new FormControl(false),
showExternalPlaybackBar: new FormControl(true),
embeddedMpvFrameCopy: new FormControl(false),
mpvPlayerPath: new FormControl(''),
mpvPlayerArguments: new FormControl(''),
mpvReuseInstance: new FormControl(false),