Repository navigation
Syncing a Remote Player
This page connects tv-player (set up in Remote Player) to tv-server. When it's done, the player copies the server's schedule every hour and plays exactly what Emby and Jellyfin show, at the same moment.
The server is in charge. It builds every schedule. The player never schedules anything on its own. Once an hour, it copies four things from the server:
- The schedule database. What plays when, on every channel.
- The station configs. One file per channel.
- The catalog. The folders of links your channels play, plus bump cards and other small files.
- The Sources list. Live stream channels, like the weather channel.
The videos themselves are never copied. Both PCs read them from the NAS at the same path, /mnt/media.
graph TD
subgraph tv-server
wrapper[Station Wrapper 43 builds the schedules]
feed[fs42-feed.sh: snapshot plus read-only copy]
end
subgraph tv-player
sync[fs42-sync, every hour]
streams[fs42-streams]
player[FieldStation42 player]
end
nas[NAS videos at /mnt/media]
wrapper --> feed
feed -->|SSH, one locked-down key| sync
sync --> streams --> player
nas --> player
Why not have the player build its own schedules? Then it would pick different episodes than the server, and the TV wouldn't match Emby. Copying the server's schedule keeps them in step.
All three are in the repo's extras/remote-player folder.
| Script | Runs on | Job |
|---|---|---|
fs42-feed.sh |
the server | The only thing the player's SSH key is allowed to run. It can make a fresh snapshot of the schedule, or let the player copy files. It can't change anything. |
fs42-sync |
the player | Runs every hour from cron. Copies everything over, then restarts the player if something changed. |
fs42-streams |
the player | Called by fs42-sync. Turns the server's live stream channels and guide channel into something the player can show. |
The player logs in to the server over SSH to copy files. That login uses its own key, and the server only lets that key run fs42-feed.sh. So even if someone got hold of the player and its key, they couldn't run commands on the server or change any files there. All they could do is read your channel data.
The read-only copying is done by rrsync, a small helper that comes with Ubuntu's rsync package. It only allows reading, and only inside one folder.
cd ~/fieldstation42
curl -fsSLO https://raw.githubusercontent.com/austincnunn/station-wrapper-43/main/extras/remote-player/fs42-feed.sh
chmod +x fs42-feed.shOpen it and check the two settings at the top:
| Setting | Set it to |
|---|---|
DATA |
Your data folder, like /home/tv/fieldstation42/data
|
CONTAINER |
The wrapper container's name (station-wrapper-43 if you used the compose file from Server Setup) |
Your user must be able to run docker without sudo, because the script reads two files through the container.
ls -l /usr/bin/rrsyncIf it's missing, install rsync: sudo apt-get install -y rsync.
SSH_ORIGINAL_COMMAND=snapshot ~/fieldstation42/fs42-feed.sh && ls -l ~/fieldstation42/data/crt/You should see three files: fs42_fluid.db, FS42_REF and sources.json. (The folder is called crt because this was first built for a CRT TV.)
The key has no password, because cron needs to use it with no one around. That's fine, since the server limits what it can do.
ssh-keygen -q -t ed25519 -N "" -C "tv-player fs42 feed" -f ~/.ssh/fs42_feed
cat ~/.ssh/fs42_feed.pubCopy the line it prints. You'll paste it on the server in the next step.
On the server, add one line to ~/.ssh/authorized_keys. Put this in front of the key you copied, all on one line:
command="/home/tv/fieldstation42/fs42-feed.sh",restrict ssh-ed25519 AAAA...your key... tv-player fs42 feed
-
command="..."means this key always runs the feed script, no matter what the player asks for. -
restrictturns off everything else: no terminal, no port forwarding, no agent forwarding.
Make sure the file's permissions are tight:
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keysAdd this to ~/.ssh/config on the player:
Host fs42-feed
HostName 192.168.1.20
User tv
IdentityFile ~/.ssh/fs42_feed
IdentitiesOnly yes
StrictHostKeyChecking accept-new
chmod 600 ~/.ssh/configNow fs42-feed means "the server, with that key". The scripts use this name.
ssh -T fs42-feed snapshot && echo OKYou should see OK. The first time, SSH saves the server's fingerprint.
Try something the key isn't allowed to do:
ssh -T fs42-feed whoamiIt won't print tv. Instead you'll see rrsync error: SSH_ORIGINAL_COMMAND does not run rsync. The server ran the feed script, which only allows copying. That's the lock working.
mkdir -p ~/bin
cd ~/bin
curl -fsSLO https://raw.githubusercontent.com/austincnunn/station-wrapper-43/main/extras/remote-player/fs42-sync
curl -fsSLO https://raw.githubusercontent.com/austincnunn/station-wrapper-43/main/extras/remote-player/fs42-streams
chmod +x fs42-sync fs42-streamsOpen fs42-sync and check its settings:
| Setting | Set it to |
|---|---|
FS42_DIR |
Your FieldStation42 folder, like /home/tv/FieldStation42
|
FEED |
fs42-feed, the SSH name from step 6 |
STREAMS |
Where fs42-streams is. The default (next to fs42-sync) is right if both are in ~/bin. |
SKIP_PACKAGES |
Packages left out when FieldStation42 is updated. Remove evdev if you installed it for a remote. |
Open fs42-streams and check its two settings:
| Setting | Set it to |
|---|---|
TUNER |
The server's tuner, http://192.168.1.20:5004. You can also set the FS42_TUNER_URL environment variable instead. |
PANSCAN |
How widescreen video fits the TV. 0 shows the whole picture with black bars, which is right for a widescreen TV. 1.0 fills a 4:3 TV by cutting off the sides. |
Then run its self-check:
~/bin/fs42-streams --testIt should print ok.
~/bin/fs42-syncThe first run copies the whole catalog of links, so it takes longer than later runs. After that, check what arrived:
ls ~/FieldStation42/confs/
ls ~/FieldStation42/runtime/confs/ should have one .json file per channel. runtime/ should have fs42_fluid.db, server_sources.json, server_fs42_ref and fs42_ref.
If the server runs a different FieldStation42 version than you cloned, this run also switches yours to match and reinstalls its packages.
crontab -eAdd this line:
0 * * * * /home/tv/bin/fs42-sync 2>&1 | logger -t fs42-sync
Its messages go to the system log, tagged fs42-sync.
sudo rebootThe PC logs in by itself, starts X, and the player starts on the TV.
Every hour, fs42-sync does this:
- Takes a lock, so two syncs never run at once. If the last one is still going, this one quietly skips.
- Asks for a snapshot. The server makes a clean copy of the schedule database. (The real database is busy all the time. Copying it as-is could catch it half-written.)
-
Copies the catalog.
rsynconly sends what changed, so this is quick after the first time. Links removed on the server are removed here too. -
Copies the station configs. It keeps three things on the player that the server doesn't have: FieldStation42's
main_config.json, itsexamples/folder, and thestream-*.jsonstations thatfs42-streamsmakes. -
Copies the schedule snapshot into
runtime/fs42_fluid.db. -
Runs
fs42-streams(see below). - Checks the FieldStation42 version. The server's image records which FieldStation42 commit it runs. If the player's is different, it fetches and switches to that exact commit, then reinstalls the packages. Both sides read the same database, so they need to agree.
- Restarts the player if needed. If any station config or the FieldStation42 version changed, it stops the player. The autologin starts it again on the new setup a few seconds later. If nothing changed, the TV isn't touched.
The player and the server don't handle everything the same way. fs42-streams fixes up the copied configs, on the player only:
- Live stream channels. Each channel on the server's Sources page (a weather channel, a camera, an IPTV playlist) becomes a FieldStation42 "streaming" station on the player, with the same number and name as in Emby. Remove a source on the server, and its station goes away here at the next sync. The player opens these streams itself, so it must be able to reach them on the network.
-
The guide channel. FieldStation42's own guide is plain. The server's guide shows show names and posters. So the player plays the server's guide channel as a stream from the server's tuner (
TUNER/auto/v<number>). A guide set to Standard (4:3) on the server is cropped to fill a 4:3 TV. A widescreen guide is shown whole. -
Panscan. Every other station gets your
PANSCANsetting, unless its config already has its own. This has to go in each station's config, because FieldStation42 resets mpv's panscan for every video. Putting it inmpv.confdoesn't stick.
The sync's log:
journalctl -t fs42-sync -n 20The player's log:
journalctl -t fs42 -n 50When did the last schedule copy arrive?
ls -l ~/FieldStation42/runtime/fs42_fluid.dbIt should be less than an hour old.
| What you see | What to check |
|---|---|
Permission denied (publickey) |
The key line on the server (step 5). It has to be one line, with the command= part in front of the key. Check the permissions too: ~/.ssh is 700 and authorized_keys is 600. |
ssh -T fs42-feed snapshot hangs or fails |
Run the snapshot on the server by hand (step 3). Can your user run docker? Is DATA right? |
rrsync: command not found |
Install rsync on the server, or fix the path at the bottom of fs42-feed.sh. |
| Shows play at the wrong time | The two PCs' time zones don't match. See Remote Player, step 1. |
| Black screen, or "file not found" in the player log | The player can't see the videos at /mnt/media. Run ls /mnt/media and compare with what the container sees (docker exec station-wrapper-43 ls /mnt/media on the server). |
| A channel shows up in Emby but not on the TV | The sync hasn't run since you made it. Run ~/bin/fs42-sync by hand. |
| A stream channel is skipped | The log says why, for example channel '47' is not a whole number free on this player. Each stream needs a whole channel number that no other station uses. |
| The weather channel or a stream won't play | The player opens the stream's address itself. Try it with mpv <address> from the player. |
| The picture is cut off, or has bars | Change PANSCAN in fs42-streams, then run ~/bin/fs42-sync. The configs are copied fresh from the server each time, so the new setting reaches every station at once. The only exception is a station whose config on the server sets its own panscan. |
More general problems are on the Troubleshooting page.
Guides
- Server Setup
- Making Channels
- Client Mode Player (the easy way to a TV)
The manual way to a TV
Extras