# Sync play for MPV Goal: write an Odin application to sync playback between remote viewers via a small Odin program. The program will be called `syncplay`. The player is called `mpv`. `syncplay` is a single executable that can be run by clients, and is also executable in a remote server that functions as events dispatcher. The server is required. Use case: two friends want to see the same movie using MPV, and they want synchronized playback. If one pauses, the video pauses for the other viewer. If one seeks to xx:xx:xx, also the other player seeks to xx:xx:xx. **Server** ```sh ./syncplay server --port --host 0.0.0.0 ``` **Client** ```sh ./syncplay client --port --host \ [--mpv ] [--socket ] ``` Supported operations: - play - pause - seek On macOS, the client launches MPV with a JSON IPC UNIX socket. `syncplay` connects to that socket, observes pause changes and seek events, and sends JSON commands to apply events received from the relay server. The TCP protocol is newline-delimited JSON. There is one global session, no authentication, and no server-held playback state. Messages are absolute state changes: ```json {"version":1,"type":"welcome","client_id":1} {"version":1,"type":"pause","paused":true} {"version":1,"type":"pause","paused":false} {"version":1,"type":"seek","position":123.456} ``` The server assigns a numeric ID when a client connects and includes the triggering ID in every relayed event. Both server and client terminals log each play, pause, and seek action with that client ID. Clients start paused at `00:00:00` and are assumed to use the same movie. There is no clock synchronization or drift correction. If a connection is lost, playback continues locally and the event is logged; clients do not reconnect. **Example flow**: 0. Someone starts `syncplay` on a remote server. 1. User A starts `syncplay`. The program starts and runs the `mpv` player. 2. Then it connects to the remote `syncplay` instance. 3. `syncplay` observes pause and seek events reported by MPV over JSON IPC. 4. `syncplay` translates supported local events and sends them to the server. 5. The server will stream to all connected clients the same event. 6. Any connected client receives the event and sends the corresponding JSON IPC command to its local MPV instance. Remote seeks use a serialized transaction: disable delivery of the `seek` event for the IPC connection, apply an `absolute+exact` seek, wait for mpv's `playback-restart` completion event, then re-enable the `seek` event even when the operation fails. A successful command reply alone is not a completion barrier because mpv can deliver seek effects afterward. Keeping delivery disabled through completion prevents remote seeks from being reported as new local seeks and looping through the server. **Example cli command to run MPV** Pay attention to the socket path. That, along with the MPV path must likely be constants in the Odin program. ```sh /Applications/mpv.app/Contents/MacOS/mpv \ --force-window=yes \ --idle=yes \ --pause=yes \ --start=0 \ --hr-seek=always \ --keep-open=always \ --keep-open-pause=yes \ --input-ipc-server=/tmp/mpv-socket \ --input-terminal=no \ --terminal=no ```