Python Livestream Toolkit provides two explicit YouTube playout modes:
- a minimal continuous terminal feed that captures one public market page at a fixed, high-quality
1080p30 - an optional narrated show that researches topics, generates scripts and TTS, and composes a branded studio page
The continuous terminal feed is the default container path. It navigates to STREAM_URL once and keeps Chromium and Xvfb alive while FFmpeg reconnects in process after transient output failures. The narrated runtime remains available through stream_url.py and its buffered producer-consumer pipeline.
- Streams a public terminal page without exposing the host desktop
- Publishes
1920x1080at30 FPSwith H.264 High, 10 Mbps CBR, a two-second GOP, and silent AAC audio - Uses encrypted RTMPS for remote ingest and rejects plaintext remote RTMP endpoints
- Keeps stream credentials out of logs and out of Chromium/FFmpeg child environments
- Loads a reusable show profile from
shows/*.toml - Pulls source material from
rss,webpage,json, ormanualadapters - Builds a local browser-based studio page with headline, source cards, ticker, and branding
- Buffers prepared audio segments ahead of playout
- Persists rolling memory per show to reduce repetition
- Routes script generation across xAI, Gemini, or OpenRouter
- Supports stable screenshot capture, macOS screen capture, and isolated virtual-display capture for containers
- Mixes continuous background music under narrated segments
- Supports optional music-only breaks between segments
Each show profile defines:
- topic and editorial framing
- host voice and branding
- source adapters
- studio labels and optional iframe reference panel
- scene modes such as
overlay,clean-feed, andtransition - segment rundown, for example headline, live feed, deep dive, and recap
Bundled profile:
shows/hb_capital.toml
| Backend | Best for | Notes |
|---|---|---|
playwright |
stability | Default path, typically around 12 FPS |
screen |
local macOS experiments | Captures an entire display via avfoundation |
virtual-screen |
Docker or Linux VM | Captures only an isolated Xvfb-hosted Chromium session |
If you do not want to stream your real desktop, use virtual-screen on Linux or in the provided container image.
The runtime is split into small modules:
shows/loads show configs, source adapters, and segment briefsllm/builds prompts and routes script generationtts/renders narrationbroadcast/pipeline.pyprepares queued segments and local studio pagesbroadcast/streaming.pyhandles narrated FFmpeg playoutbroadcast/memory.pyrecords prior coverage context per show
The dedicated continuous path is split across stream_terminal.py and the small broadcast/terminal_stream*.py modules. See docs/terminal-stream.md for its operating contract.
More detail lives in docs/architecture.md.
git clone https://github.com/SebastianBoehler/python_livestream.git
cd python_livestream
pip install -r requirements.txt
playwright installrequirements.txt includes the full local-model stack. The default container intentionally uses the lighter requirements-stream.txt instead.
Copy .env.example to .env and set the values you need.
Common settings:
STREAM_URL=https://www.hb-capital.app/livestream
YOUTUBE_STREAM_KEY_FILE=/run/secrets/youtube_stream_keyFor local development only, YOUTUBE_STREAM_KEY is accepted as a fallback. Production should mount the key as a readable, tightly permissioned file and set YOUTUBE_STREAM_KEY_FILE; if the file setting is present but unreadable or empty, startup fails instead of falling back to the environment.
Notes:
SHOW_IDselects a profile inshows/SHOW_CONFIG_PATHcan point to any custom TOML fileSTREAM_URLis always required by the continuous feed and by narrated profiles that reference itNEWS_SEGMENT_SECONDSis still supported as a global duration overridehb_capitaluses an HB Capital scene pack with overlay desk shots, clean-feed terminal views, and branded transitions
Provider credentials depend on which services you use:
GEMINI_API_KEYXAI_API_KEYOPENROUTER_API_KEYELEVENLABS_API_KEYHF_TOKEN
python stream_terminal.pyThis entry point is Linux-only because it uses Xvfb and X11 capture. On macOS, use the container or a Linux VM.
For a receiver-free VM burn-in, set STREAM_OUTPUT_FILE=/tmp/terminal.flv, stop the stream after the soak window, and inspect it with ffprobe. This is mutually exclusive with STREAM_OUTPUT_URL.
python stream_url.pySHOW_CONFIG_PATH=/absolute/path/to/my_show.toml python stream_url.pySTREAM_ORIENTATION=portrait python stream_url.pyINTER_SEGMENT_MUSIC_SECONDS=20 python stream_url.pyINTER_SEGMENT_DELAY_SECONDS is still accepted as a compatibility alias.
STREAM_CAPTURE_BACKEND=virtual-screen STREAM_FPS=25 python stream_url.pyvirtual-screen is Linux-only and is the recommended mode for long-running container or VM deployment.
show_id = "my_show"
title = "Niche Desk"
tagline = "Automated coverage for one clear audience."
host_name = "Desk"
host_role = "Operator anchor"
description = "Explain what changed and why it matters."
base_prompt = "Cover the most relevant developments from the last 24 hours."
llm_system_instruction = "You are a sharp and concise anchor."
tts_voice = "Charon"
[branding]
primary_color = "#93f5d8"
accent_color = "#f6c35c"
background_start = "#04141a"
background_end = "#11172a"
card_background = "rgba(8, 18, 31, 0.78)"
text_color = "#f4f7fb"
muted_text_color = "#9bb4c8"
[studio]
label = "Live Desk"
strapline = "Source-driven coverage"
ticker_prefix = "Radar"
iframe_url = ""
layout_mode = "split"
[[sources]]
kind = "rss"
name = "Google News Topic"
url = "https://news.google.com/rss/search?q=my+topic+when:1d&hl=en-US&gl=US&ceid=US:en"
limit = 5
[[sources]]
kind = "manual"
name = "Editorial Guardrails"
text = "Stay concrete and explain implications."
[[segments]]
kind = "headline"
label = "Top Setup"
instructions = "Open with the biggest development."
duration_seconds = 180
scene_mode = "overlay"The default Dockerfile is optimized for the continuous terminal feed on Linux hosts:
- base image:
python:3.11-slim-bookworm - isolated Chromium capture via Xvfb
- fixed
1080p30libx264encoding for stable YouTube quality - only streaming/runtime dependencies installed
- a non-root runtime user with Chromium's sandbox left enabled
Build and run it:
docker build -t python-livestream .
docker run --env-file .env python-livestreamFor persistent operation:
docker compose up -dThe included docker-compose.yml uses the dedicated virtual-screen path and restart: unless-stopped.
The narrated show remains an opt-in Compose profile:
docker compose --profile narrated up narratedIf you want a heavier local-model image for GPU-backed TTS experiments, use Dockerfile.gpu:
docker build -f Dockerfile.gpu -t python-livestream-gpu .broadcast/ streaming, capture backends, memory, intermissions, studio pages
docs/ architecture notes
llm/ provider routing and prompt generation
shows/ show configs, source adapters, segment brief helpers
tts/ TTS backends and chunking
tests/ unit tests for core streaming behavior
Run the baseline checks before opening a PR:
python -m py_compile $(git ls-files '*.py')
python -m unittest discover -s tests -p 'test_*.py' -vCI also builds the default Docker image to catch container regressions early.
See CONTRIBUTING.md for workflow and expectations.
In short:
- keep changes modular
- avoid large files and duplicated logic
- add or update tests for behavioral changes
- document operator-facing config changes
If you discover a security issue, see SECURITY.md.
This project is licensed under the MIT License. See LICENSE.