feat(windows): mpv plays audio on Windows, with libmpv shipped in the installer
libmpv on Windows (DR-237): - The builder image carries zhongfly's LGPL libmpv-2.dll, pinned by asset name and sha256, plus an MSVC mpv.lib generated from the DLL's own mpv_* exports (the archive ships only a MinGW .dll.a). LGPL, not the GPL builds: no x264/x265, mpv -Dgpl=false; FFmpeg is version3, so LGPL-3.0. THIRD_PARTY_NOTICES.md records it. - build-windows-cross.sh stages both files into src-tauri/windows-libs/; build.rs links mpv.lib from there and tauri.windows.conf.json bundles the DLL beside jellytau.exe from there, with the licence texts under licenses/. One directory, so the DLL shipped is the one linked. - Workflows move to builder image 2026.09.1. Windows audio: - MpvBackend replaces WebviewAudioBackend on Windows (ao=wasapi), so volume, EQ, normalization and gapless work there as on Linux. Local files are passed to mpv as native paths, not file:// URLs. Fixes found on the way: - player_play_item decided "does the backend render video" with cfg!(not(linux)), true on Windows, while get_player_status sent Windows video to the <video> element. With mpv as the backend that would decode every film's soundtrack twice. All three callers now ask video_renders_natively() (UT-273). - confine_queued_path rebuilt paths with PathBuf::push, so on Windows a queued `downloads/x` was stored as `downloads\x`, no longer the spelling the app built. It now keeps the caller's separator (UT-205, which only ever ran on Linux, failed under Windows). Verified: jellytau.exe imports libmpv-2.dll; the full unit suite cross-compiled for Windows passes under wine against the shipped DLL (943/943, including the mpv injection and TLS tests); the NSIS installer contains the DLL and licence texts. Not yet run on real Windows hardware.
This commit is contained in:
Vendored
+29
-17
@@ -7,17 +7,31 @@ job / SMTC lockscreen), but it runs and plays media.
|
||||
|
||||
## How playback works on Windows
|
||||
|
||||
- **Video** — renders through the webview HTML5 `<video>` element (hls.js) on
|
||||
*every* platform; on Windows that is WebView2 (Chromium/Edge), which plays HLS +
|
||||
h264 fine. No Windows-specific code.
|
||||
- **Audio-only (music)** — the native audio backends are libmpv (Linux) and
|
||||
ExoPlayer (Android); neither exists on Windows. Instead
|
||||
`create_player_backend()` in [../src-tauri/src/lib.rs](../../src-tauri/src/lib.rs)
|
||||
uses `WebviewAudioBackend` on non-Linux/non-Android targets: it hands the stream
|
||||
URL to a webview `<audio>` element (see
|
||||
[../src/lib/services/webviewAudio.ts](../../src/lib/services/webviewAudio.ts)),
|
||||
which reports state back through the same `player_report_*` round-trip the video
|
||||
path uses. Pure Rust + Tauri events.
|
||||
- **Video** — renders through the webview HTML5 `<video>` element (hls.js); on
|
||||
Windows that is WebView2 (Chromium/Edge), which plays HLS + h264 fine. mpv
|
||||
takes this over in DR-237's video phase; Linux already made that move.
|
||||
- **Audio** — **libmpv**, the same `MpvBackend` Linux uses, with `ao=wasapi`.
|
||||
Volume, EQ, normalization and gapless all go through mpv's filter graph as on
|
||||
Linux. `libmpv-2.dll` ships beside `jellytau.exe` in the installer.
|
||||
|
||||
### libmpv on Windows
|
||||
|
||||
- **Which build:** zhongfly/mpv-winbuild's *LGPL* dev asset, pinned by name and
|
||||
sha256 in [Dockerfile.builder](../../Dockerfile.builder), which unpacks it to
|
||||
`/opt/libmpv-win64`. Licence terms: [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md).
|
||||
The same release also carries a GPL asset (x264/x265) — do not switch to it
|
||||
casually, it moves the installer onto GPL-3.0 terms.
|
||||
- **Import library:** the archive only ships a MinGW `libmpv.dll.a`. The image
|
||||
generates an MSVC `mpv.lib` from the DLL's own `mpv_*` exports
|
||||
(`llvm-readobj --coff-exports` → `.def` → `llvm-lib /def:`), so it cannot name
|
||||
a symbol the DLL lacks.
|
||||
- **One directory:** `scripts/build-windows-cross.sh` copies both files into
|
||||
`src-tauri/windows-libs/` (gitignored) before building. `build.rs` links
|
||||
`mpv.lib` from there and `tauri.windows.conf.json` bundles the DLL from there,
|
||||
so the DLL shipped is the one linked against. Outside the image, point
|
||||
`LIBMPV_WIN_DIR` at a directory holding `libmpv-2.dll` and `mpv.lib`.
|
||||
- **Bumping it:** change the three `LIBMPV_WIN_*` values together, rebuild and
|
||||
push the image, bump the image tag the workflows pin.
|
||||
|
||||
## Cross-compiling from Linux (MSVC + cargo-xwin)
|
||||
|
||||
@@ -35,7 +49,7 @@ Tauri CLI bundle the **NSIS installer from a Linux host**.
|
||||
|
||||
The builder image ([../Dockerfile.builder](../../Dockerfile.builder)) bakes in the
|
||||
whole toolchain: the `x86_64-pc-windows-msvc` rust target, `cargo-xwin`, `lld`,
|
||||
`llvm`, and `nsis`.
|
||||
`llvm`, `nsis`, and the pinned Windows libmpv.
|
||||
|
||||
```bash
|
||||
bun run docker:build:windows # NSIS installer + .exe -> ./dist
|
||||
@@ -71,8 +85,6 @@ Outputs:
|
||||
|
||||
## Outstanding for a first-class Windows release
|
||||
|
||||
1. Gapless/crossfade + SMTC (lockscreen) — currently no-ops in the webview audio
|
||||
path.
|
||||
2. Downloaded (`Local` source) file playback needs `convertFileSrc` on the
|
||||
frontend; streaming works today.
|
||||
3. Code signing + a Windows packaging CI job.
|
||||
1. SMTC (lockscreen / media keys) — not wired on Windows.
|
||||
2. Code signing — the installer is unsigned.
|
||||
3. Video through mpv (DR-237) — needs a WebView2-side surface.
|
||||
|
||||
Reference in New Issue
Block a user