Documentation
README
QUICK START
1. Extract zip to a folder
2. Run: chmod +x install_and_run.sh && ./install_and_run.sh
3. First launch opens the Quick Setup wizard
4. Enter your YouTube stream key
5. Add videos to the playlist on the Stream tab
6. Click Start Stream
Install plugins:
mkdir -p ~/streamer_plugins
cp streamer_plugins/*.py ~/streamer_plugins/
Restart the app — plugins load automatically
WHAT'S NEW IN v3.0.0
Relay + Recording — new built-in plugin
Record your stream to a local file at the same time as broadcasting to
YouTube, straight from the app. A new "Relay + Recording" tab runs a
local MediaMTX relay: the app sends ONE stream to the relay, which
forwards it to YouTube AND writes a local copy. Because recording
happens entirely in the relay — never in the streaming ffmpeg — it
cannot affect or interrupt your live stream.
One-click setup
The first time, click "Set up relay" — it downloads MediaMTX and writes
the config with your stream key. No terminal, no manual editing.
Record toggle and in-app controls
Start and stop the relay from inside the app, with a live status line;
it shuts down cleanly when the app closes or restarts. A "Record this
stream" toggle routes the output between live-only and live + record.
Recordings (saved to ~/recordings) are listed in the tab with play and
delete buttons.
Replaces the separate relay download
Local recording is now a built-in plugin — the old experimental,
separate relay download is gone, and the previous tee-muxer recording
stub has been removed.
Tools tab — UI declutter
A new "Tools" tab groups the occasional-use features so the main tab bar
stays focused on going live: the AI Playlist Builder, Chapter Markers,
Multi-RTMP, SFTP Manager and YouTube Analytics, plus a Utilities panel
(Update yt-dlp, ffmpeg version, Bulk Rename, Clear Temp Files). Download
is now its own main tab with YouTube Search as a sub-tab beside it. Every
moved feature works exactly as before — only its location changed.
Native file dialogs
All open / save / folder pickers now use the native GTK file chooser
(zenity) — thumbnails, search, bookmarks and proper multi-select — and
reopen at the last-used folder. If zenity is not installed the app falls
back automatically to the built-in Tk dialogs, so behaviour is identical
either way.
Startup stability
Fixed an intermittent crash on launch caused by the system colour-emoji
font (Noto Color Emoji) crashing the Tk text renderer (libXft). Font
matching now steers away from the colour-emoji font at startup, so UI
emoji render as plain glyphs and the crash is gone. The fix is app-scoped
and changes no system-wide font settings.
WHAT'S NEW IN v2.2.9
Stability and playback
Playlist looping is fixed — videos now advance through the whole list
and the playlist loops as a whole instead of sticking on one video. A
source-file corruption that had orphaned class methods and broken tab
and plugin loading is repaired; plugins now load reliably on restart.
The now-playing bar shows a per-video timecode (elapsed / total /
remaining). YouTube encode quality is improved: constant frame rate
(CFR), keyframes every 2 seconds, and a capped bitrate for a stable,
spec-friendly stream.
Interface
The Start button is colour-coded — green to start, red while live. The
Stream tab is now vertically scrollable so no controls are cut off on
smaller screens. The Download tab gained an "Add to Playlist" button to
send a downloaded file straight to the active playlist.
Experimental
An optional MediaMTX relay-recording setup (relay + local recording) is
offered as a separate download.
Reworked input system
Two separate camera inputs, an upgraded Picture in Picture, and
one-click input switching.
Two separate video inputs
Webcam and Capture Card are now separate input sources, each with
its own device, format and FPS. Set a USB webcam on one and an HDMI
capture card on the other — they remember their own devices, so you
never re-pick when switching between them. The capture scan detects
real Video Capture nodes and skips metadata-only nodes.
Upgraded Picture in Picture
PiP now has a selectable Background (Playlist, Screen, or Capture
Card) and a selectable Overlay (Webcam or Capture Card). Mix any
combination — game capture with a facecam, a tutorial screen with a
webcam corner. Guards block using one capture device as both layers.
One-click input switching
Each input has a Launch button under its radio. Click it to stop the
current stream and start that input with its current settings, in a
single click. Each input panel also has a Save settings button with
a brief "Settings saved" notice. The old Switch Input dialog has been
removed in favour of these per-input Launch buttons.
Fixes
Capture/webcam previews are now stopped before streaming so the
device is free (no false "device busy"). The "device busy" dialog now
explains the likely wrong-node cause instead of suggesting chmod.
FILES IN THIS RELEASE
streamer.py Main application (v3.0.0) install_and_run.sh Launcher / dependency checker streamer_plugins/ Plugin files — copy to ~/streamer_plugins/ player_website/ Self-hosted stream player (see player_website/README.txt) README.txt This file
PLUGINS (19 included)
File Tab / Location What it does ───────────────────────────────────────────────────────────────────── remote_api.py (API only) Flask REST server, 20 endpoints download_manager.py Download tab yt-dlp queue, site detector badges scheduler.py Schedule tab Weekly schedule, auto-fire yt_search.py Search tab YouTube API v3, column list results my_channel.py My Channel tab OAuth 2.0, dashboard, video manager health_monitor.py Health tab Live graphs, stat tiles, stream log webcam.py Input source V4L2 scanning, preview screenshare.py Input source X11/Wayland, preview pip_overlay.py Input source Picture-in-Picture overlay overlays.py Settings/Overlays Watermark, title, chroma, tickers stream_preview.py Stream tab sidebar Live preview + now playing + notepad chapter_markers.py Chapters tab Live markers, playlist planner video_trimmer.py Playlists/Trimmer In/out points, no re-encode multi_rtmp.py Multi-RTMP tab Stream to multiple destinations recording.py Settings/System Record stream locally ai_playlist_builder.py AI Builder tab Topic to playlist pipeline sftp_manager.py SFTP tab Transfer/sync files with a VPS over SSH youtube_live.py Stream > Broadcast Create and manage YouTube live broadcasts youtube_analytics.py Analytics tab Full analytics dashboard with charts
PLUGIN DEPENDENCIES
Required:
ffmpeg sudo apt install ffmpeg
python3-tk sudo apt install python3-tk
yt-dlp sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/
latest/download/yt-dlp -o /usr/local/bin/yt-dlp
sudo chmod +x /usr/local/bin/yt-dlp
Plugin dependencies:
flask pip install flask (remote_api)
psutil pip install psutil (health_monitor)
websockets pip install websockets (player chat server)
paramiko pip install paramiko (sftp_manager)
google-auth pip install google-auth (my_channel)
pip install google-auth-oauthlib
pip install google-api-python-client
For AI Playlist Builder search / Search tab:
YouTube Data API v3 key (free, 10,000 units/day)
console.cloud.google.com -> Enable YouTube Data API v3
-> Credentials -> Create API Key
-> paste into Search tab or AI Builder -> Set API key
For Play button in Search tab (streams without downloading):
sudo apt install mpv (recommended)
sudo apt install vlc (alternative)
AI PLAYLIST BUILDER
1. Click the AI Builder tab
2. Type a topic e.g. "lo-fi study music" or "wildlife documentary"
3. Set target hours — how long the stream should be
4. Set filters:
Min/max video duration skip clips and very long videos
Min view count quality filter
No Shorts / vertical checks actual pixel dimensions via ffprobe
Creative Commons only license filter via YouTube API
English only biases search to English content
Quality best / 1080p / 720p / 480p
5. Click Build Playlist — the pipeline runs automatically:
Searches YouTube API v3 (up to 500 results)
Scores by keyword relevance against topic
Removes duplicates already in download folder
Downloads via yt-dlp with thumbnails embedded
Verifies with ffprobe — skips vertical, checks duration
Assembles to target duration, loops if needed
Saves as a named playlist JSON
6. Results tab shows all built playlists
7. Load into Streamer button pushes to the active playlist
Stop saves whatever has already finished downloading as a
partial playlist. Pause holds after the current download
completes and resumes on click.
Requires: YouTube Data API v3 key (same as Search tab)
SEARCH TAB
Results display as a scrollable list with columns:
# Title Channel Duration Views Date [Download] [Play] [Web]
Download — sends URL to the download manager queue
Play — streams in mpv or vlc without downloading (install mpv first)
Web — opens in browser
Filters: sort, type, duration, upload date, quality, captions,
safe search, region, language, min views, no Shorts,
Creative Commons
Requires: YouTube Data API v3 key
SFTP MANAGER
Transfer and sync files between this machine and a VPS over SSH/SFTP.
Adds an SFTP tab with four sub-tabs.
Requires: pip install paramiko
Your VPS must have SSH enabled (port 22 by default).
Connection sub-tab:
Enter host, port, username and password — OR tick "Use SSH key
file" and browse for a private key (e.g. ~/.ssh/id_rsa).
Set the remote start path, Save Settings, then Connect.
The status dot turns green when connected.
Files sub-tab:
Side-by-side local and remote file browsers.
Double-click folders to navigate, Up to go back.
Upload sends the selected file or folder to the VPS.
Download brings the selected remote file or folder local.
Progress bar and transfer speed shown; Cancel stops a transfer.
Delete removes a remote file (with confirmation).
Sync sub-tab:
Three pre-configured jobs:
Video Downloads ~/Downloads/ai_streams
Playlists ~/.yt_live_streamer_playlists
Settings ~/.yt_live_streamer_settings.json
Each has editable local and remote paths and three buttons:
Upload Local -> VPS
Download VPS -> Local
Compare (reports local-only / remote-only / in-sync / differ)
Log sub-tab:
Colour-coded history of all transfers.
Connection settings are saved in the settings JSON (sftp_* keys).
Transfers are manual — there is no automatic schedule.
REMOTE CONTROL API
Settings -> System -> Remote Control API -> Start API
Auto-starts on launch if previously enabled.
Endpoints (GET):
/api/status streaming state, fps, bitrate
/api/now-playing current track, index, elapsed
/api/playlists list all saved playlists
/api/playlist current playlist items
/api/health fps/bitrate history, CPU/RAM
/api/downloads queue and completed list
/api/schedule weekly schedule
/api/server-info IP, port, version, auth status
Endpoints (POST):
/api/start start the stream
/api/stop stop the stream
/api/skip skip to next video
/api/prev go to previous video
/api/switch-playlist {name} switch playlist live
/api/set-input {source} change input source
/api/download-add {url, type} add to download queue
/api/download-start start download queue
/api/download-stop stop downloads
/api/schedule-enable {enable: true/false}
/api/schedule-override {playlist} start now
Auth: X-API-Token header or ?token= query param
Requires: pip install flask
PLAYER WEBSITE
Self-hosted stream player — stream to your own website alongside YouTube.
See player_website/README.txt for full setup and feature guide.
Quick setup:
cd player_website
chmod +x setup_stream_server.sh
./setup_stream_server.sh
sudo cp stream_player.html /var/www/html/index.html
Enable Multi-RTMP plugin and add your server as a destination:
rtmp://YOUR_MACHINE_IP/live/stream
MY CHANNEL — OAUTH SETUP
1. console.cloud.google.com -> your project
2. Enable YouTube Data API v3 + YouTube Analytics API
3. Credentials -> OAuth 2.0 Client ID -> Desktop app
4. My Channel -> Connect -> enter ID + Secret -> Connect
Token saved to: ~/.yt_live_streamer_oauth_token.json
DATA FILE LOCATIONS
Settings: ~/.yt_live_streamer_settings.json (incl. sftp_* keys) Playlists: ~/.yt_live_streamer_playlists/ Schedule: ~/.yt_live_streamer_schedule.json DL History: ~/.yt_live_streamer_dl_history.json OAuth Token: ~/.yt_live_streamer_oauth_token.json Chapters: ~/.yt_live_streamer_chapters/ Trims: ~/.yt_live_streamer_trims.json Recordings: ~/.yt_live_streamer_recordings.json Notes: ~/.yt_live_streamer_notes.txt Plugin dir: ~/streamer_plugins/ AI downloads: ~/Downloads/ai_streams/
KEYBOARD SHORTCUTS
Space Start / Stop stream -> Skip to next video <- Go to previous video F11 Toggle fullscreen Esc Exit fullscreen
VPS / BOT DETECTION FIX
1. Export cookies.txt from browser (youtube.com)
2. scp cookies.txt user@server:~/cookies.txt
3. Settings -> Download -> YouTube Cookies -> Browse
CHANGELOG
v3.0.0
New built-in plugin: Relay + Recording — record locally while
broadcasting, via a managed local MediaMTX relay (replaces the old
separate relay download; the old tee-muxer recording stub removed)
One-click MediaMTX setup writes the config with your stream key
Start/stop the relay in-app with live status; clean shutdown on
app close and restart
"Record this stream" toggle routes output between live and record
In-app recordings browser (~/recordings) with play and delete
Recording runs entirely in the relay — it can never affect the
live stream (no tee muxer, no two-stage pipe)
New Tools tab groups occasional-use features (AI Playlist Builder,
Chapter Markers, Multi-RTMP, SFTP Manager, YouTube Analytics) plus a
Utilities panel (Update yt-dlp, ffmpeg version, Bulk Rename, Clear
Temp Files); Download is now a main tab with Search as a sub-tab
Native GTK file dialogs (zenity) app-wide — thumbnails, search,
multi-select, last-used folder — with automatic Tk fallback
Fixed an intermittent startup crash from the system colour-emoji font
(Noto Color Emoji) crashing the Tk renderer (libXft); app-scoped fix
v2.2.9
Playlist looping fixed — videos advance through the whole list and the
playlist loops as a whole instead of sticking on one video
Repaired source-file corruption that orphaned class methods and broke
tab/plugin loading; plugins now load reliably on restart
Now-playing bar shows per-video timecode (elapsed / total / remaining)
YouTube encode quality — constant frame rate (CFR), 2-second keyframes,
capped bitrate for a stable, spec-friendly stream
Green/red Start button (green = start, red = live)
Stream tab is now vertically scrollable — no controls cut off
Add to Playlist button in the Download tab
Input system rework. Webcam and Capture Card are now two separate
input sources, each remembering its own device/format/fps. Capture
scan detects real Video Capture nodes and skips metadata nodes.
Picture in Picture upgraded: selectable Background (playlist / screen /
capture card) and Overlay (webcam / capture card), with guards
against using one capture device as both layers.
One-click input switching: a Launch button under each input radio
stops the current stream and starts that input in a single click.
Per-panel Save settings button with a fading notice. The old
Switch Input dialog was removed.
Previews stopped before streaming so the device is free; the
device-busy dialog now explains the likely wrong-node cause.
Experimental MediaMTX relay-recording option (separate download).
v2.2.8
New plugin: youtube_live.py — create and manage YouTube live broadcasts
(broadcasts, create, stream key, live chat, monetization) as a
Broadcast sub-tab under Stream
New plugin: youtube_analytics.py — full analytics dashboard with
Canvas charts (overview, trends, top videos, traffic, geography, CSV export)
My Channel: expanded OAuth scopes (force-ssl, analytics) so one sign-in
covers broadcasts and analytics; token restore no longer breaks on
scope changes
Core: plugins can now add sub-tabs under Stream via add_stream_subtab;
top-level tab loop tolerates plugins without add_tab
Windows: Phase 1 core support (platform detection, launcher, path/binary
helpers, no-console-window streaming)
v2.2.7
New plugin: ai_playlist_builder.py — topic to stream pipeline
New plugin: sftp_manager.py — transfer and sync files with a VPS over SSH
Search tab rebuilt as clean column list (no thumbnails)
Search tab Play button streams via mpv/vlc
Port 5000 conflict error suppressed — clean skip if already bound
Header download speed indicator always visible
Player website v2 — theatre mode, reactions, mentions, sounds,
now playing bar, stats bar, uptime, poster image, copy link
_api_status_var crash fixed
English only filter in AI Builder
v2.2.6
Overlays plugin v2 — lower third, scrolling ticker, sponsor banner
Recording plugin — tee muxer integration, Rec button
Download manager — site detector badges, link type auto-detect
Chapter markers — playlist planner, history sub-tabs
Video trimmer — in/out points, no re-encode
Multi-RTMP — stream to multiple destinations
AI Playlist Builder — initial version
Stream preview — sidebar with thumbnails and notepad
v2.2.4
Plugin architecture — all features as standalone .py files
Tab suppression — plugins declare provides_tab
Health tab as standalone top-level tab
Remote Control API — Flask REST server, 20 endpoints
v2.0.3
Fixed THEMES not defined — _apply_theme crashed with NameError
because the THEMES colour dict was missing; added full dark
and light theme colour maps
Fixed lbl() missing argument — My Channel tab called lbl() with
a textvariable; changed three calls to tk.Label() directly
Fixed _build_log_tab AttributeError on startup (late-binding tkinter)
Remote Control API token fix — restarting after killing port 5000
now correctly loads a blank token from settings
Remote App (yt-remote) auto-connect fix — auto-connects on launch
from saved config, 5-second heartbeat keeps connected state
accurate across tabs, configRef pattern uses the latest config
v2.0.2 — My Channel (YouTube Data API v3)
New My Channel tab with four sub-tabs; OAuth 2.0 only when you
open the tab and click Connect, not at startup
Connect — enter OAuth Client ID and Secret, sign in once, token
saved to ~/.yt_live_streamer_oauth_token.json and auto-restored
Dashboard — subscriber count, total views, video count, recent
likes, recent uploads table, refresh
Video Manager — list up to 50 videos, real-time title filter,
sortable columns, colour by privacy, edit title/description,
copy URL, add to download queue, right-click menu
Analytics Preview — 7/28/90/365 day periods, views, watch time,
subscribers gained, estimated revenue, top 15 videos
Remote Control API — Flask REST server on port 5000, 20 endpoints,
optional auth token, QR code generator for APK setup
v2.0.1 — UI reorganisation, Help tab, YouTube Search
Tab structure overhaul — Health moved inside Stream, Log inside
Settings, Search and My Channel and Help tabs added
Help tab — searchable built-in docs, 35+ articles, 11 categories
YouTube Search tab — Data API v3 search, 4-column grid, 32 per
page, thumbnails, full filter set, download to queue
Playlist duration estimator with 24-hour warning
Minimise and tray buttons; persistent download history
Custom colours; scheduler global toggle; screenshare preview
Playlists tab redesign — day tabs, custom playlists, editor
Multiple segfault fixes — canvas/build methods deferred via after()
v2.0.0 — Feature complete
Playlist duration estimator with live ends-at display
Auto-restart on ffmpeg failure
Bitrate/FPS rolling graph; download speed graph
Network bandwidth test recommending a bitrate
Adaptive bitrate ladder (6000 to 3000 to 1500 kbps)
Chroma key green screen; webcam border; gap-filler standby screen
Resource monitor — CPU, RAM, disk in Health
v1.1.9 — Global output settings
Global video output panel applies to all inputs
Default download quality; Open button on playlist
Switch input mid-stream; help buttons throughout
v1.1.8 — Picture in picture
PiP playlist fullscreen with webcam overlay; size, position,
margin, format, FPS, flip; fixed -re deadlock on mixed inputs
v1.1.7 — Webcam / capture card
V4L2 webcams and HDMI capture; scan, preview (auto format),
diagnose; v4l2-ctl image adjustments; force-kill on stop
v1.1.6 — Stream stats & file management
Live stats bar; platform browser buttons; completed downloads
management; fullscreen/restart/close header buttons
v1.1.5 — Major UI overhaul
Settings split into 5 sub-tabs with collapsible sections;
tooltips; compact mode; status dot; Quick Setup wizard
v1.1.3 — Reliability & automation
Auto-reconnect; pre-flight check; bandwidth meter; fade
transitions; drag-and-drop; watch folder; play history;
keyboard shortcuts; boot service; timezone-aware scheduling
v1.1.2 — Tools & appearance
Data management; stream quality tools; playlist tools;
download tools; dark/light theme; system tray
v1.1.1 — Stream enhancements
Uptime counter; shuffle; volume normalisation; platform
quick-select; .txt queue; countdown overlay
v1.1.0 — VPS & seamless streaming
Interlude/preroll video; YouTube cookies for VPS; seamless
concat streaming; H.264 NAL fixes
v1.0.8 — Multi-stream & watermarks
RTMP relay; skip/prev/switch controls; image and title
watermarks; schedule tab; multi-stream
v1.0.7 — Download queue & playlists
Custom RTMP; pause/resume downloads; download queue;
save/load playlists; auto-start on launch
v1.0.6 Playlist and channel download modes
v1.0.5 yt-dlp integration, quality selector
v1.0.4 YouTube downloader tab
v1.0.3 Fixed stream stop crash
v1.0.2 Playlist manager, health monitor
v1.0.1 Linux port (from Windows)
v1.0.0 Initial Windows release
v0.09 Multi-stream to two destinations
v0.08 Image watermark overlay
v0.07 Basic schedule tab
v0.06 Health monitor (FPS/bitrate counters)
v0.05 Download tab (single video)
v0.04 Settings persistence (JSON)
v0.03 Loop and auto-start options
v0.02 Playlist manager
v0.01 First prototype — stream one file to YouTube
YT LIVE STREAMER