YT Live Streamer — Linux Edition
Version 3.0.0
=============


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
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 downloads MediaMTX and writes the config with your
      stream key (no manual editing).
      Start / stop the relay from inside the app; it shuts down cleanly
      when the app closes or restarts.
      A "Record this stream" toggle routes the output between live-only
      and live + record per stream.
      Browse, play and delete recordings (saved to ~/recordings) in-app.
    This replaces the old experimental, separate relay download — local
    recording is now a built-in plugin. 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. It holds 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 —
    instead of the dated Tk dialogs, 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). The app
    now steers font matching 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 — it changes no system-wide font settings.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
WHAT'S NEW IN v2.2.9
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Stability and playback
    Playlist looping fixed — videos now advance correctly through the
    whole list and the playlist loops AS A WHOLE instead of sticking
    on a single video.
    Repaired source-file corruption that had orphaned class methods and
    broken tab and plugin loading; plugins now load reliably on restart.
    The now-playing bar shows a per-video timecode (elapsed / total /
    remaining).
    YouTube encode quality improved — constant frame rate (CFR),
    keyframes every 2 seconds, and a capped bitrate for a stable,
    spec-friendly stream.

  Input system rework
    Webcam and Capture Card are now two separate input sources, each
    with its own device, format and fps. The capture scan detects real
    Video Capture nodes and skips metadata-only 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.
    Each input panel has a Save settings button with a brief notice.
    The old Switch Input dialog has been removed.
    Previews are 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.

  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.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
WHAT'S NEW IN v2.2.8
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  YouTube Live (youtube_live.py) — NEW PLUGIN
    Create and manage YouTube live broadcasts from inside the app.
    A Broadcast sub-tab under Stream with five areas:
      Broadcasts   - list, go live, test, end, delete, copy watch URL
      Create       - new broadcast with title/privacy/options, auto
                     creates + binds a stream key
      Stream Key   - view/create stream keys, apply to streamer output
      Live Chat    - read and send live chat in real time
      Monetization - Super Chats and channel members
    Requires one re-sign-in via My Channel (adds the youtube.force-ssl scope).

  YouTube Analytics (youtube_analytics.py) — NEW PLUGIN
    Full analytics dashboard as a top-level Analytics tab:
      Overview     - 8 metric tiles + estimated revenue
      Trends       - Canvas line chart (views / watch time / subs)
      Top Videos   - sortable table of your best videos
      Traffic      - bar chart of traffic sources
      Geography    - bar chart of top countries
      Export CSV   - daily breakdown export
    Charts are drawn on a tkinter Canvas - no extra dependencies.
    Requires enabling the YouTube Analytics API in Google Cloud and one
    re-sign-in via My Channel (adds the yt-analytics.readonly scope).

  Core and platform
    Plugins can now add sub-tabs under Stream (add_stream_subtab hook).
    My Channel uses expanded OAuth scopes so one sign-in covers
    broadcasts and analytics; token restore no longer breaks when scopes
    change.
    Windows Phase 1 core support (see the separate Windows package).

  Previous (v2.2.7)
    AI Playlist Builder, SFTP Manager, rebuilt Search tab, player
    website v2, port 5000 fix. See changelog at the end.

  Search Tab (yt_search.py) — REBUILT
    Results now display as a clean scrollable list with columns:
    row number, title, channel, duration (yellow), views, date,
    Download (green), Play (blue) and Web buttons.
    All thumbnail code removed — fast and reliable.
    Play button streams via mpv or vlc if installed.

  Remote API (remote_api.py) — FIXED
    Port 5000 conflict error on startup is now silent — the plugin
    checks if the port is already bound before starting Flask and
    skips cleanly instead of printing "Address already in use".

  Header download speed indicator — NEW
    A second status pill in the header (next to the network indicator)
    shows download activity at all times regardless of which tab is open:
      Green  DL + speed   — download manager active
      Blue   AI DL        — AI builder downloading videos
      Purple AI           — AI builder running other steps
      Grey   Idle         — nothing downloading

  Player Website (player_website/) — UPGRADED
    Theatre mode, stream uptime counter, animated offline screen with
    retry countdown, optional poster image, reaction buttons with
    floating emoji animation, mention highlighting and notification
    toast, sound notifications (ping on message, chime on mention),
    Now Playing / Next Up bar from streamer API, live stats bar
    (viewers, uptime, bitrate, FPS), Copy Link button, Hide/Show Chat.

  _api_status_var crash — FIXED
    AttributeError when API auto-started before Settings tab was
    visited is now fixed — var is initialised in __init__.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
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             Relay + Recording tab Local recording via a managed MediaMTX relay
  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)

  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 split into two separate
      inputs, each remembering its own device/format/fps; capture scan
      detects real Video Capture nodes and skips metadata nodes
    Picture in Picture upgraded — selectable Background and Overlay, with
      guards against using one capture device as both layers
    One-click input switching — a Launch button under each input radio;
      per-panel Save settings; old Switch Input dialog removed
    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.0
    Major rewrite — YouTube Search, My Channel, Scheduler,
    Download Manager, Health Monitor, Screenshare, PiP, Overlays
