Raspberry Pi Zero-based media player in a 3D-printed miniature TV that plays classic TV shows on loop with Bluetooth audio.
Supports two modes:
- VLC mode - plays local video files from
~/Videos/ - Jellyfin mode - streams random episodes from a Jellyfin server
~/.pitv.conf (MODE=VLC or JELLYFIN)
|
v
pitv.sh (launcher)
/ \
/ \
vlc.sh jellyfin.sh
| |
| Jellyfin API --> playlist of stream URLs
| |
v v
cvlc (fullscreen, random, loop)
|
v
PulseAudio null-sink (vlc_output)
|
v
PulseAudio combine-sink (vlc_bt)
|
v
Bluetooth A2DP speaker (auto-connects on power-on)
- 320x480 DPI display driven via
vc4-kms-dpi-genericoverlay - Rotated 270 degrees (portrait display used in landscape) via
wlr-randr - Boot config:
boot/config.txt - Rotation service:
systemd/user/rotate-display.service
- VLC mode: plays all files in
~/Videos/randomly in a loop - Jellyfin mode: queries a Jellyfin server for episodes from shows listed in
~/shows.txt, builds a streaming playlist, and plays randomly in a loop - Auto-restarts on crash (handles bluetooth disconnections gracefully)
- Config template:
home/.pitv.conf.example(copied to~/.pitv.conf) - Launcher:
home/pitv.sh - VLC script:
home/vlc.sh - Jellyfin script:
home/jellyfin.sh - Show list template:
home/shows.txt.example(copied to~/shows.txt)
The audio pipeline uses PulseAudio to route VLC audio to a Bluetooth speaker:
- Null sink (
vlc_output) - virtual audio device that VLC outputs to - Combine sink (
vlc_bt) - merges the null sink with the Bluetooth output device - Bluetooth auto-connect - PulseAudio's
module-bluetooth-discoverdetects when the paired BT speaker powers on and connects automatically
Key configs:
etc/pulse/default.pa- PulseAudio with bluetooth modules,tsched=0,autodetect_mtu=yesetc/pulse/daemon.conf.snippet- Lower fragment size for BT audio latencyetc/bluetooth/main.conf.snippet-AutoEnable=true, BlueZ reconnect disabled (PulseAudio handles it)
sudo apt install vlc pulseaudio pulseaudio-module-bluetooth bluez curl jq# Boot config (requires reboot)
sudo cp boot/config.txt /boot/firmware/config.txt
# PiTV scripts
cp home/pitv.sh home/vlc.sh home/jellyfin.sh ~/ && chmod +x ~/pitv.sh ~/vlc.sh ~/jellyfin.sh
# Config templates — copy, then edit (these hold your mode, Jellyfin URL/API key, and show list).
# The real ~/.pitv.conf and ~/shows.txt are gitignored, so only the .example files ship in the repo.
cp home/.pitv.conf.example ~/.pitv.conf
cp home/shows.txt.example ~/shows.txt
# System service. The template uses two placeholders you must fill in:
# PITV_USER -> the Linux user PiTV runs as
# BT_MAC_ADDR -> your Bluetooth speaker MAC, underscores not colons (e.g. AA_BB_CC_DD_EE_FF)
# The sed below auto-fills PITV_USER with the current user; you still set the MAC.
# (The unit also assumes that user's UID is 1000 — the Raspberry Pi OS default. If yours
# differs, also update the two /run/user/1000 paths in the installed file.)
sed "s/PITV_USER/$USER/g" systemd/system/vlc.service | sudo tee /etc/systemd/system/vlc.service >/dev/null
sudo sed -i 's/BT_MAC_ADDR/AA_BB_CC_DD_EE_FF/' /etc/systemd/system/vlc.service # <-- set your speaker's MAC
sudo systemctl daemon-reload
sudo systemctl enable vlc.service
# Display rotation (user service)
mkdir -p ~/.config/systemd/user/graphical-session.target.wants
cp systemd/user/rotate-display.service ~/.config/systemd/user/
ln -sf ~/.config/systemd/user/rotate-display.service ~/.config/systemd/user/graphical-session.target.wants/
# PulseAudio
sudo cp etc/pulse/default.pa /etc/pulse/default.pa
# Apply daemon.conf snippet manually
# Bluetooth
# Apply main.conf.snippet changes to /etc/bluetooth/main.conf [Policy] sectionbluetoothctl
> power on
> scan on
> pair XX:XX:XX:XX:XX:XX
> trust XX:XX:XX:XX:XX:XX
> connect XX:XX:XX:XX:XX:XXEdit ~/.pitv.conf:
# For local files:
MODE=VLC
# For Jellyfin streaming:
MODE=JELLYFIN
JELLYFIN_URL=https://jellyfin.server.home
JELLYFIN_API_KEY=your-api-key-hereFor Jellyfin mode, add shows to ~/shows.txt (one per line):
Friends
IT Crowd
Home Improvement
Place video files in ~/Videos/ (subdirectories supported).
sudo systemctl start vlc.service