DR-237's video half. mpv now renders Windows video the way tauri-plugin-libmpv does on Windows: MpvBackend is handed the main window's HWND and sets it as `wid` before mpv initialises, so mpv draws as a child of the app window beneath the transparent WebView2, with vo=gpu-next,gpu. osc, default bindings, VO keyboard and cursor handling are off, so the Svelte controls drawn over the picture are the only ones. - video_output() decides per platform (UT-274): Window(hwnd) on Windows, RenderApi on Linux, Off without native video. Windows with no handle draws nothing rather than letting mpv open a top-level window. - native_video::enabled() is true on Windows as well, so the frontend takes the native path there: NativePlayerAdapter, and the page clears its background while video is on screen. - enableNativeVideoCompositing() no longer logs a missing Android bridge as an error on the desktop, where there is no bridge to have. Verified: every option, wid included, is accepted by the real libmpv on Linux and by the shipped Windows DLL under wine; the Windows unit suite passes under wine (949). Not yet seen on real Windows hardware.
97 lines
4.6 KiB
Markdown
97 lines
4.6 KiB
Markdown
# Windows build
|
|
|
|
JellyTau targets Linux and Android primarily, but a working Windows build —
|
|
including an **NSIS installer cross-compiled from Linux** — is produced by the
|
|
Docker tooling. It is not yet a first-class release target (no code signing / CI
|
|
job / SMTC lockscreen), but it runs and plays media.
|
|
|
|
## How playback works on Windows
|
|
|
|
- **Video** — **mpv**, drawing into the app's own window: `MpvBackend` is
|
|
handed the main window's HWND as `wid` before mpv initialises and renders with
|
|
`vo=gpu-next,gpu` as a child of it, beneath the transparent WebView2 whose page
|
|
clears its background while a video is on screen (`data-native-video`). mpv's
|
|
own controller, key bindings and cursor handling are off — the Svelte controls
|
|
drawn over it are the only ones. This is the arrangement tauri-plugin-libmpv
|
|
ships on Windows (same zhongfly LGPL DLL). **Not yet seen on real Windows
|
|
hardware** — if the picture ends up *over* the controls, the z-order of mpv's
|
|
child window is the first thing to check.
|
|
- **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)
|
|
|
|
We use the [official Tauri cross-compile path](https://v2.tauri.app/distribute/windows-installer/):
|
|
the **MSVC** target (`x86_64-pc-windows-msvc`) driven by
|
|
[`cargo-xwin`](https://github.com/rust-cross/cargo-xwin), which downloads the MSVC
|
|
CRT / Windows SDK headers and links with `lld`. MSVC is the target Tauri
|
|
officially supports for Windows (mingw/GNU is not), and — unlike GNU — it lets the
|
|
Tauri CLI bundle the **NSIS installer from a Linux host**.
|
|
|
|
> Why not mingw/GNU? The GNU target *does* link a valid `.exe`, but the Tauri CLI
|
|
> gates `--bundles` by the host OS unless it recognizes a real Windows build.
|
|
> `--runner cargo-xwin --target x86_64-pc-windows-msvc` is what flips it into
|
|
> Windows mode and enables the `nsis`/`msi` bundlers on Linux.
|
|
|
|
The builder image ([../Dockerfile.builder](../../Dockerfile.builder)) bakes in the
|
|
whole toolchain: the `x86_64-pc-windows-msvc` rust target, `cargo-xwin`, `lld`,
|
|
`llvm`, `nsis`, and the pinned Windows libmpv.
|
|
|
|
```bash
|
|
bun run docker:build:windows # NSIS installer + .exe -> ./dist
|
|
WIN_BUNDLES=none bun run docker:build:windows # exe only, skip bundling
|
|
```
|
|
|
|
Or directly on a host that has the toolchain:
|
|
|
|
```bash
|
|
scripts/build-windows-cross.sh # nsis installer + exe
|
|
WIN_BUNDLES=none scripts/build-windows-cross.sh # exe only
|
|
```
|
|
|
|
Under the hood the build runs:
|
|
|
|
```bash
|
|
tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc --bundles nsis
|
|
```
|
|
|
|
Outputs:
|
|
- `.exe` — `src-tauri/target/x86_64-pc-windows-msvc/release/jellytau.exe`
|
|
- NSIS installer — `.../release/bundle/nsis/*-setup.exe`
|
|
|
|
(both copied to `./dist` when `OUTPUT_DIR` is set).
|
|
|
|
## Caveats
|
|
|
|
- **Cross-compilation is a last resort** per Tauri's own docs — it's less tested
|
|
than building on Windows. If it misbehaves, a `windows-latest` CI job or a
|
|
Windows VM building natively (`tauri build --bundles nsis`) is the fallback.
|
|
- **Code signing is not wired up** — the installer is unsigned, so Windows
|
|
SmartScreen will warn on first run.
|
|
|
|
## Outstanding for a first-class Windows release
|
|
|
|
1. SMTC (lockscreen / media keys) — not wired on Windows.
|
|
2. Code signing — the installer is unsigned.
|
|
3. First run of mpv video on real Windows hardware (DR-237).
|