Skip to content

Client Mode Player

austincnunn edited this page Nov 9, 2026 · 1 revision

Client Mode Player

This is the easy way to put your channels on a TV. The player PC runs the same Docker image as the server, with one setting changed: FS42_ROLE=client. It then sets itself up:

  • It copies the server's schedule, station list and catalog about once a minute. Only the parts that changed are sent.
  • It plays the channels on the screen plugged into the PC. mpv draws straight to the screen, so there is no desktop to set up.
  • It shows the channel number in the top left corner when you change channels.
  • It tells the server how it's doing. The server's Status page lists it under Players.

The older way, with a hand-built FieldStation42 install and an hourly copy over SSH, is still on the Remote Player and Syncing a Remote Player pages. You don't need it if you use this page.

This only works on your own network (or a VPN like Tailscale). It is not made to run over the internet.

What you need

  • A server already set up from Server Setup, running a version with client mode.
  • A PC for the TV (tv-player, 192.168.1.30 in these guides) with Ubuntu Server (or any Linux with Docker). An old laptop is fine. Intel graphics decode most video for free.
  • The TV hooked to the PC. Any output works: HDMI, VGA, or an adapter to a CRT.

1. On the server: turn on client sync

Make a long random token and put it in the server's .env file:

cd ~/fieldstation42
echo "FS42_SYNC_TOKEN=$(openssl rand -hex 32)" >> .env

Then pass it to the container. In docker-compose.yml, under environment: of the wrapper, add:

      FS42_SYNC_TOKEN: ${FS42_SYNC_TOKEN:-}

Restart the server:

docker compose up -d

Check that it works. This should print some JSON:

T=$(grep ^FS42_SYNC_TOKEN= .env | cut -d= -f2)
curl -s -H "Authorization: Bearer $T" http://localhost:5004/sync/state

Without the token, the same address answers 403. The token only lets a player read the schedule. It can't change anything.

2. On the player: the basics

Set the same time zone as the server. If they differ, every show starts at the wrong time.

sudo timedatectl set-timezone America/New_York

Install Docker:

sudo apt-get update
sudo apt-get install -y docker.io docker-compose-v2 cifs-utils

3. On the player: mount the media share

The player reads the videos straight from the NAS. It must see them at the same path as the server does: /mnt/media. The schedule names every video by that path, so a different path means nothing plays.

Save the share's login in a file only root can read:

sudo install -m 600 /dev/stdin /root/.smb-media <<'EOF'
username=your-share-user
password=your-share-password
EOF

Add the share to /etc/fstab and mount it:

sudo mkdir -p /mnt/media
echo "//192.168.1.10/media /mnt/media cifs ro,credentials=/root/.smb-media,vers=3.0,iocharset=utf8,_netdev,nofail 0 0" | sudo tee -a /etc/fstab
sudo systemctl daemon-reload
sudo mount /mnt/media
ls /mnt/media

You should see the same folders the server has.

4. On the player: start it

Make a folder and get the two files:

mkdir -p ~/fs42-player && cd ~/fs42-player
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/austincnunn/station-wrapper-43/main/client/docker-compose.client.yml
curl -fsSL -o .env https://raw.githubusercontent.com/austincnunn/station-wrapper-43/main/client/.env.example
chmod 600 .env

Open .env and fill it in:

Setting What to put
FS42_SERVER The server's address with port 5004, like http://192.168.1.20:5004
FS42_SYNC_TOKEN The same token as the server's .env
FS42_SCREEN hd for a modern TV, crt for an old 4:3 TV (see below)
FS42_DRM_CONNECTOR Which output to use, like HDMI-A-1 or VGA-1. Leave it out to use the first one that's plugged in.
FS42_PLAYER_NAME The name the server's Status page shows, like living-room

To list the outputs your PC has, and which ones have a screen:

for c in /sys/class/drm/card*-*; do echo "$(basename $c): $(cat $c/status)"; done

Nothing else may be drawing on the screen. If the PC boots to a desktop, or logs in and starts X, turn that off first. mpv needs the screen to itself.

Start it:

sudo docker compose up -d
sudo docker logs -f fs42-player

The first copy takes a minute or two. Then you should see client: ready: the player can start, and the TV starts playing.

Screen settings

FS42_SCREEN picks good settings for the kind of TV you have. Each one can be changed on its own in .env.

crt hd Change it with
Widescreen video Cropped to fill the 4:3 screen Shown whole FS42_PANSCAN (0 to 1)
Screen mode The screen's preferred mode The screen's preferred mode FS42_DRM_MODE, like 1024x768@60
Picture scaling fast (light on old PCs) high-quality FS42_MPV_PROFILE
Channels streamed from the server 1500 kbps, 854x480 4000 kbps, 1280x720 FS42_STREAM_KBPS (500 to 4000)

Most channels play the video files straight from the NAS, at their own quality. Only a few channels come as a stream from the server, mainly the guide channel. The bitrate setting is for those.

Other settings:

  • FS42_GAMMA brightens the picture. Try 10 if a CRT looks too dark. It goes from -100 to 100.
  • FS42_BANNER_SECONDS is how long the channel number stays up. The default is 8. FS42_BANNER=off turns it off.

After changing .env, run sudo docker compose up -d again.

Changing channels

The player runs FieldStation42's remote control page at http://192.168.1.30:4242. Open it on your phone.

Keeping it up to date

The player and the server must run the same version. Update the server first, then the player:

cd ~/fs42-player
sudo docker compose pull
sudo docker compose up -d

If they don't match, both the player's log and the server's Status page say so.

When it doesn't work

What you see What to check
the server refused the sync token The token in the player's .env must match the server's exactly.
the server has client sync switched off The server's container doesn't have FS42_SYNC_TOKEN. See step 1.
videos in the coming schedule are missing here The share isn't mounted at /mnt/media, or it's a different folder than the server's. Run ls /mnt/media on both.
time zone ... is not the server's Set the same time zone on both (step 2), then restart the player.
Black screen, nothing in the log about mpv Something else has the screen. Turn off the desktop or X login, then sudo docker compose restart.
Picture on the wrong output Set FS42_DRM_CONNECTOR.
Choppy video on an old PC Use FS42_SCREEN=crt or FS42_MPV_PROFILE=fast. Very new video formats (HEVC, AV1) may be too much for old graphics chips.

Clone this wiki locally