diff --git a/README_public.md b/README_public.md deleted file mode 100644 index 5dc59d9..0000000 --- a/README_public.md +++ /dev/null @@ -1,348 +0,0 @@ -# MXL Player -MXL Player is a desktop player for local [Media eXchange Layer](https://github.com/dmf-mxl/mxl) -audio and video flows, with GUI controls and command-line startup configuration. -It can play either feed independently, play both simultaneously, or switch a -configured pair into and out of native MXL synchronization while running. - -The application uses: -- SDL3 for its window, input, and audio output; -- Vulkan for video and ImGui rendering; -- [`go-mxl`](https://github.com/qvest-digital/go-mxl) for MXL access. - -## Features - -- Synchronized playback for compatible same-domain feeds; cross-domain feeds - currently use independent readers. -- Finite or unlimited reconnect attempts with exponential backoff. -- JSON playlists with manual selection, timed advance, looping, and failure - policies. -- Playback, media, timing, retry, and dropped-frame statistics. - -## Planned - -- MXL Fabrics support; -- MXL URI/addressability support; -- Coordinated cross-domain reading using TAI timestamps; -- GUI-created playlist; -- GPU selection; -- LUFS meter; -- patching audio channels to selected device. - -## Installation - -Prebuilt packages are available from -[GitHub Releases](../../releases). - -- **macOS ARM64:** `.app` bundle with SDL3, libmxl, and MoltenVK included. -- **Linux AMD64:** binary built on Ubuntu. A compatible libmxl installation, - SDL3, Vulkan loader, and Vulkan-capable driver are required. - -Download the archive for your platform and verify its SHA-256 checksum before -running it. - -## Tested platforms - -- Ubuntu and Fedora: build and feed playback tested. -- macOS ARM64: build and feed playback tested. - -## Building from source: requirements - -- Go 1.26 or newer. -- A C/C++ build toolchain for cgo dependencies. -- A compatible shared build of `libmxl` and its development headers. -- pkg-config metadata for `libmxl`. -- SDL3 shared library. -- Vulkan loader and a working Vulkan driver. -- libmxl 1.2.0 or a compatible build providing - `mxlCreateFlowSynchronizationGroup`. - -The project currently pins: -```text -github.com/qvest-digital/go-mxl v1.1.0-rc.2 -``` - -## Building on Linux - -First verify that pkg-config resolves the intended MXL installation: - -```sh -pkg-config --modversion libmxl -pkg-config --cflags --libs libmxl -pkg-config --variable=pcfiledir libmxl -pkg-config --variable=libdir libmxl -``` - -If MXL is installed in a nonstandard prefix: - -```sh -export MXL_PREFIX=/opt/mxl/1.2.0 -export PKG_CONFIG_PATH="$MXL_PREFIX/lib/pkgconfig" -export LD_LIBRARY_PATH="$MXL_PREFIX/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" -``` - -Then build and test: - -```sh -go mod download -go test ./... -mkdir -p build -go build -o build/mxl-player ./cmd/mxl-player -``` - -Confirm which native library the executable will use: - -```sh -ldd build/mxl-player | grep libmxl -``` - -## macOS - -The SDL3 and Vulkan loaders contain macOS library-name support. The Vulkan -dependency is temporarily replaced by a portability fork while the upstream -change is reviewed. - -Building currently requires: -- Xcode Command Line Tools; -- Go; -- SDL3; -- MoltenVK; -- a macOS build of libmxl with matching headers and pkg-config metadata. - -When libmxl has been built from its source tree but has not been installed into -a standard prefix, expose its build metadata, source headers, and library -directory to cgo. For example: - -```sh -export MXL_SOURCE=/path/to/mxl -export MXL_BUILD="$MXL_SOURCE/build/Darwin-Clang-Release" - -export PKG_CONFIG_PATH="$MXL_BUILD${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" -export CGO_CFLAGS="-I$MXL_SOURCE/lib/include" -export CGO_LDFLAGS="-L$MXL_BUILD/lib" - -mkdir -p build -go build -o build/mxl-player ./cmd/mxl-player -``` - -The `CGO_CFLAGS` workaround is needed because the headers are still in the MXL -source tree. A properly installed MXL SDK should expose them through -`libmxl.pc` instead. - -Nonstandard loader locations can be supplied explicitly (for example, in case of installing with homebrew): - -```sh -export SDL3_LIBRARY="$(brew --prefix sdl3)/lib/libSDL3.dylib" -export VULKAN_LIBRARY=/absolute/path/to/libMoltenVK.dylib -export DYLD_LIBRARY_PATH="$MXL_BUILD/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" - -./build/mxl-player -``` - -The resulting executable may currently need an additional libmxl runtime search -path, for example: - -```sh -install_name_tool -add_rpath "$MXL_BUILD/lib" build/mxl-player -``` - -These workarounds are only needed for development builds. The packaged `.app` -uses bundled libraries and relative runtime paths instead. - -### Running the macOS application bundle - -The package is ad-hoc signed but is not signed with an Apple Developer ID or notarized by Apple. -Consequently, Gatekeeper may block its first launch. Right-click **MXL Player.app**, -select **Open**, and confirm the prompt. It can also be allowed -from **System Settings → Privacy & Security** after a blocked launch. - -If macOS still retains a quarantine restriction, it can be removed manually: - -```sh -xattr -dr com.apple.quarantine "/Applications/MXL Player.app" -``` -Only remove quarantine from an archive downloaded from the official project release and verified against its SHA-256 checksum. - -## Running - -Start with no configured feed and enter domains/UUIDs in the GUI: - -```sh -./build/mxl-player -``` - -Video only: - -```sh -./build/mxl-player \ - --domain /dev/shm/mxl \ - --video VIDEO_UUID -``` - -Audio only: - -```sh -./build/mxl-player \ - --domain /dev/shm/mxl \ - --audio AUDIO_UUID -``` - -Independent video and audio: - -```sh -./build/mxl-player \ - --video-domain /dev/shm/video \ - --video VIDEO_UUID \ - --audio-domain /dev/shm/audio \ - --audio AUDIO_UUID -``` - -Start a compatible pair synchronized: - -```sh -./build/mxl-player \ - --domain /dev/shm/mxl \ - --video VIDEO_UUID \ - --audio AUDIO_UUID \ - --sync -``` - -Synchronization is not a permanent startup mode. It can be enabled and -disabled at runtime from the settings window. - -## Command-line options - -| Option | Short | Meaning | -|---|---:|---| -| `--help` | `-h` | Show help and exit. | -| `--domain PATH` | `-d` | Default domain for feeds without a specific domain. | -| `--video-domain PATH` | | Domain for the video feed. | -| `--audio-domain PATH` | | Domain for the audio feed. | -| `--video UUID` | `-v` | Initial video flow UUID. | -| `--audio UUID` | `-a` | Initial audio flow UUID. | -| `--sync` | `-s` | Start a configured A/V pair synchronized. | -| `--max-attempts N` | | Attempts per playback lifecycle; `0` means unlimited. | -| `--playlist FILE` | | Load a JSON playlist. | -| `--fullscreen` | `-f` | Start fullscreen. | -| `--gpu-id N` | `-g` | Select GPU ID; currently incomplete. | -| `--playback-id N` | `-p` | Select the SDL playback-device ID. | -| `--list-playback` | | List SDL playback devices and exit. | -| `--list-gpu` | | List Vulkan physical devices and exit. | -| `--verbose` | | Reserved; currently incomplete. | - -Run `./build/mxl-player --help` for the authoritative list. - -## GUI controls - -The settings window accepts separate video/audio domains and UUIDs. - -- **Apply feeds** applies the complete desired configuration. -- **Stop** stops a feed while retaining its UUID and domain. -- **Resume** starts a stopped configured feed with a fresh lifecycle. -- **Remove** stops a feed and clears its configuration. -- **Stop all** and **Resume all** operate on both configured feeds. -- **Synchronize** switches a compatible active pair between synchronized and - independent playback. - -Keyboard shortcuts: - -| Key | Action | -|---|---| -| `F1` | Show or hide settings. | -| `F2` | Show or hide statistics. | -| `F` | Toggle fullscreen. | -| `Q` or `Esc` | Quit. | - -## Retry behavior - -Each playback lifecycle starts at attempt 1. Failed connections/readers are -retried with exponential delay from 500 ms up to 5 seconds. - -```sh -# Retry indefinitely -./build/mxl-player -d /dev/shm/mxl -v VIDEO_UUID --max-attempts 0 - -# Stop after three failed attempts -./build/mxl-player -d /dev/shm/mxl -v VIDEO_UUID --max-attempts 3 -``` - -With independent A/V, one failed feed retries without stopping the other. A -synchronized pair reconnects as one lifecycle. - -## Playlists - -Start a playlist with: - -```sh -./build/mxl-player --playlist playlist.json -``` - -Example: - -```json -{ - "loop": true, - "on_failure": "next", - "retry": { - "max_attempts": 3, - "initial_delay": "500ms", - "max_delay": "5s" - }, - "entries": [ - { - "name": "Synchronized pair", - "video": { - "domain": "/dev/shm/mxl", - "uuid": "VIDEO_UUID" - }, - "audio": { - "domain": "/dev/shm/mxl", - "uuid": "AUDIO_UUID" - }, - "sync": true, - "duration": "10s" - }, - { - "name": "Video only", - "video": { - "domain": "/dev/shm/mxl", - "uuid": "ANOTHER_VIDEO_UUID" - }, - "duration": "15s" - }, - { - "name": "Audio until manually advanced", - "audio": { - "domain": "/dev/shm/mxl", - "uuid": "ANOTHER_AUDIO_UUID" - } - } - ] -} -``` - -Playlist rules: - -- `duration` uses Go duration syntax such as `500ms`, `10s`, or `2m`. -- Missing/empty duration means manual advance. -- `loop: true` returns to the first entry after the last. -- `on_failure: "wait"` remains on an exhausted entry. -- `on_failure: "next"` advances after retry exhaustion. -- A synchronized entry must contain both video and audio. -- Playlist retry settings override the CLI defaults unless - `--max-attempts` was explicitly supplied. - -The GUI supports entry selection, previous/next navigation, and pausing or -resuming a timed entry. - -## Third-party assets - -The embedded JetBrainsMonoNL Nerd Font Mono is distributed under the SIL Open -Font License 1.1. Its copyright notice, license, and source information are in -[`internal/assets/fonts`](internal/assets/fonts/). - -## License - -MXL Player is licensed under the GNU General Public License, version 3 or any -later version. See [`LICENSE`](LICENSE). - -The embedded font retains its separate SIL Open Font License 1.1. diff --git a/playlists/sample-list.json b/playlists/sample-list.json index ffce9b2..51c60e5 100644 --- a/playlists/sample-list.json +++ b/playlists/sample-list.json @@ -15,19 +15,6 @@ "sync": true, "duration": "10s" }, - { - "name": "fail", - "video": { - "domain": "/dev/shm/mxl", - "uuid": "6fbec3b1-1b0f-417d-9059-8b94a47197ed" - }, - "audio": { - "domain": "/dev/shm/mxl", - "uuid": "6fbec3b1-1b0f-417d-9059-8b94a47197ec" - }, - "sync": true, - "duration": "10s" - }, { "name": "F1 Highlights", "video": {