================================================================
  YT LIVE STREAMER — COMPLETE ENGINEERING HISTORY
  Linux Edition · build record v0.01 through v3.0.0
================================================================

  This is the full development history, reconstructed from the
  project's own build transcripts. Unlike the short changelog in
  README.txt, this record includes per-version detail AND the
  features that were built then later removed, reverted or
  abandoned. The intent is that any past version, or any dropped
  feature, could be rebuilt from this document.

  Two numbering schemes appear in the history. Early builds used
  v1.00–v1.08; these were later renumbered to the v1.0.x form.
  Both are noted where they overlap.


================================================================
  PART 1 — VERSION-BY-VERSION HISTORY
================================================================

----------------------------------------------------------------
  ORIGINS (v0.01 – v0.09) — single-file prototype era
----------------------------------------------------------------

  v0.01  First prototype. Stream one local file to YouTube via
         ffmpeg to an RTMP URL. No GUI to speak of.
  v0.02  Playlist manager — add, remove, reorder; sequential play.
  v0.03  Loop and auto-start options.
  v0.04  Settings persistence to a JSON file in the home dir.
  v0.05  Download tab — single video via yt-dlp.
  v0.06  Health monitor — FPS and bitrate counters.
  v0.07  Basic schedule tab.
  v0.08  Image watermark overlay.
  v0.09  Multi-stream to two destinations.

----------------------------------------------------------------
  WINDOWS RELEASE & LINUX PORT (v1.00 / v1.0.0 – v1.0.3)
----------------------------------------------------------------

  v1.00 / v1.0.0  Original Windows release. Feature-complete for
         the era: tabs, scheduler, watermark, multi-stream.

  v1.01 / v1.0.1  Initial Linux port from the Windows version.
         Removed Windows-specific subprocess creationflags,
         switched fonts to DejaVu Sans. Every feature kept
         identical to the Windows build.

  v1.02 / v1.0.2  Playlist manager and live health monitor
         brought into the Linux build (add/remove/reorder,
         sequential streaming, loop playlist).

  v1.03 / v1.0.3  Fixed a NoneType crash when stopping the stream
         — a race condition in the ffmpeg stderr reader thread.
         (A working v1.0.3 zip from this point survives as an
         upload and independently confirms this entry.)

----------------------------------------------------------------
  DOWNLOAD & SEARCH ERA (v1.04 – v1.08 / v1.0.4 – v1.0.8)
----------------------------------------------------------------

  v1.04 / v1.0.4  YouTube Downloader tab, powered by yt-dlp.
         Quality selector (best/1080p/720p/480p/360p/audio).
         NOTE: a v1.0.4 "reverted" build also exists — see the
         Removed Features section for what was pulled back out.

  v1.05  Search tab with an EMBEDDED WEB BROWSER (tkinterweb),
         alongside the downloader. The embedded browser was later
         abandoned — see Removed Features.

  v1.06 / v1.0.6  Download tab overhaul: Playlist download mode
         (full YouTube playlists) and Channel download mode.
         "Skip already downloaded" option. Real-time progress.

  v1.07 / v1.0.7  Custom stream output addresses (edit RTMP URL
         and key separately). Multi-stream to two destinations.
         Pause/resume downloads. Download queue. Save/load
         playlists. Auto-start on launch.

  v1.08 / v1.0.8  RTMP/RTSP input relay — relay any RTMP or RTSP
         source (e.g. OBS) through the app. Skip/Prev/Switch
         controls. Image and title watermarks. Schedule tab.
         A Windows v1.0.8 build was also produced in parallel
         (feature-identical to Linux).

----------------------------------------------------------------
  FEATURE-GROWTH ERA (v1.1.0 – v1.1.9)
----------------------------------------------------------------

  v1.1.0  Interlude/preroll video. YouTube cookies support for
          VPS downloads. Seamless concat streaming. H.264 NAL
          fixes for clean joins between clips.

  v1.1.1  Uptime counter. Shuffle. Volume normalisation. Platform
          quick-select. .txt queue import. Countdown overlay.

  v1.1.2  Data management tools. Stream quality tools. Playlist
          tools. Download tools. Dark/Light theme. System tray.

  v1.1.3  Reliability and automation: auto-reconnect, pre-flight
          check, bandwidth meter, fade transitions, drag-and-drop,
          watch folder, play history, keyboard shortcuts, boot
          service, timezone-aware scheduling, World Times popup.

  v1.1.4  Maintenance release — version strings bumped to v1.1.4
          and the README rewritten with the full feature history
          to date. (No new runtime features; a housekeeping tag.)

  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.6  Stream stats bar below Start/Stop. Platform browser
          buttons. Completed-downloads management. Fullscreen/
          Restart/Close header buttons.

  v1.1.7  Webcam / capture card support via V4L2. Scan, Preview
          (auto-tries formats), Diagnose. v4l2-ctl image
          adjustments. Force-kill of the camera process on stop.

  v1.1.8  Picture in Picture — playlist fullscreen with a webcam
          overlay. Size, position (4 corners), margin, format,
          FPS, flip. Fixed an -re deadlock with mixed file + live
          inputs. (There was no separately shipped v1.1.7→v1.1.8
          gap; numbering is continuous here.)

  v1.1.9  Global Output Settings panel applying to ALL inputs.
          Default download quality. Open button on the playlist.
          Switch Input mid-stream. Help buttons throughout.

----------------------------------------------------------------
  THE 2.0 REWRITE (v2.0.0 – v2.0.4)
----------------------------------------------------------------

  v2.0.0  Feature-complete release. Playlist duration estimator
          with live ends-at display. Auto-restart on ffmpeg
          failure. Bitrate/FPS rolling graph. Download speed
          graph. Network bandwidth test (recommends a bitrate).
          Adaptive bitrate ladder (6000→3000→1500 kbps). Chroma
          key (green screen). Webcam border/frame. Gap-filler
          standby screen. Resource monitor (CPU/RAM/disk).

  v2.0.1  UI reorganisation. Health moved inside Stream; Log moved
          inside Settings. Search and My Channel and Help tabs
          added. Main bar: Stream · Search · Download · Schedule ·
          Playlists · My Channel · Settings · Help.
          Help tab: searchable built-in docs, 35+ articles, 11
          categories. YouTube Search tab: Data API v3, 4-column
          grid, 32 results/page, thumbnails (Pillow), full filter
          set. Playlist duration estimator. Minimise and tray
          buttons. Persistent download history. Custom colours.
          Scheduler global toggle. Screenshare preview popup.
          Playlists tab redesign. Multiple segfault fixes (canvas/
          build methods deferred via after()).

  v2.0.2  My Channel tab (YouTube Data API v3). OAuth 2.0, asked
          only when you open the tab and click Connect — not at
          startup. Four sub-tabs: Connect, Dashboard, Video
          Manager, Analytics Preview. Token saved to
          ~/.yt_live_streamer_oauth_token.json and auto-restored.
          Remote Control API introduced here: a Flask REST server
          on port 5000, 20 endpoints, optional auth token, QR-code
          generator for phone setup.

  v2.0.3  Bugfix release. Fixed THEMES-not-defined NameError in
          _apply_theme (added full dark+light colour maps). Fixed
          lbl() being called with a textvariable in My Channel
          (switched three calls to tk.Label directly). Fixed a
          _build_log_tab AttributeError on startup (late-binding
          tkinter). Remote API token fix on restart. Remote app
          (yt-remote) auto-connect fix: auto-connect on launch
          from saved config, 5-second heartbeat keeps connection
          state accurate across tabs, configRef pattern uses the
          latest saved IP/port/token.

  v2.0.4  Mobile Screen Share. A new input source that relays a
          phone's screen into the stream over RTMP, with an
          on-screen panel showing the RTMP address to point the
          phone at, plus an /api/mobile-screenshare route. This
          shipped as a v2.0.4 build but the feature did not carry
          forward into the plugin-era releases — see Removed
          Features.

----------------------------------------------------------------
  PLUGIN ARCHITECTURE ERA (v2.2.4 – v3.0.0)
----------------------------------------------------------------

  v2.2.4  Plugin architecture. Every feature becomes a standalone
          .py file in ~/streamer_plugins/. Plugins declare
          provides_tab to suppress the matching built-in tab.
          Health promoted to a standalone top-level tab. Remote
          Control API reimplemented as a plugin (remote_api.py),
          Flask REST server, 20 endpoints.
          (v2.2.0–v2.2.3 were internal steps during the plugin
          migration; v2.2.4 is the first shipped plugin build.)

  v2.2.5  Interim plugin build during the migration (packaged as
          a v2.2.5 zip). Consolidation and fixes between the
          first plugin release and the v2.2.6 feature wave; no
          standalone feature headline of its own.

  v2.2.6  Overlays plugin v2 (lower third, scrolling ticker,
          sponsor banner). Recording plugin (tee muxer, Rec
          button). Download manager site-detector badges and
          link-type auto-detect. Chapter markers (planner, history
          sub-tabs). Video trimmer (in/out points, no re-encode).
          Multi-RTMP (multiple destinations). AI Playlist Builder
          (initial version). Stream preview sidebar (thumbnails +
          notepad).

  v2.2.7  AI Playlist Builder plugin (topic → stream pipeline).
          SFTP Manager plugin (transfer/sync with a VPS over SSH).
          Search tab rebuilt as a clean column list (thumbnails
          dropped). Search Play button streams via mpv/vlc. Port
          5000 conflict 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, copy link).
          Fixed an _api_status_var crash. English-only filter in
          the AI Builder.

  v2.2.8  YouTube Live broadcast control (youtube_live.py) as a
          Broadcast sub-tab under Stream: broadcasts, create,
          stream key, live chat, monetization. Full analytics
          dashboard (youtube_analytics.py) with Canvas charts
          (overview, trends, top videos, traffic, geography, CSV
          export). My Channel OAuth scopes expanded (force-ssl,
          analytics) so one sign-in covers broadcasts and
          analytics; token restore no longer breaks on scope
          changes. Core: plugins can add sub-tabs under Stream via
          add_stream_subtab; the top-level tab loop tolerates
          plugins without add_tab. Windows Phase 1 core support
          (platform detection, launcher, path/binary helpers,
          no-console-window streaming).
          Late in v2.2.8 the Help tab and the debug/regression
          checklist were removed from the program and moved to the
          website — see Removed Features.

  v2.2.9  Input system rework and a major stability pass.

          Input system: Webcam and Capture Card split into two
          separate input sources, each with its own device, format
          and fps (capture scan detects real Video Capture nodes and
          skips metadata-only nodes). Picture in Picture upgraded with
          a selectable Background (playlist / screen / capture card)
          and Overlay (webcam / capture card), plus 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 removed. Previews stopped before
          streaming to free the device; device-busy dialog rewritten
          to explain the likely wrong-node cause.

          Stability and playback: fixed the playlist looping bug —
          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.

          Interface: the Start button is colour-coded green (start) and
          red (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.

          A standalone gapless-streaming prototype (persistent encoder
          + fifo + black fallback) was begun but deferred — not in this
          release.

  v3.0.0  Local recording, built in.

          Relay + Recording becomes a built-in plugin (replacing the old
          experimental, separate relay download). It records the stream to
          a local file at the same time as broadcasting to YouTube by
          running a local MediaMTX relay: the app pushes ONE stream to
          rtmp://localhost:1935/live (or /record), and MediaMTX forwards
          it to YouTube with -c copy while also writing the local copy.
          Because recording lives entirely in the relay and never in the
          streaming ffmpeg, it cannot affect the live stream — unlike the
          rejected tee-muxer (which broke the PiP/watermark filter paths
          with "at most one video stream is supported in flv") and the
          two-stage ffmpeg pipe (which broke at the concat boundary
          between videos). One-click setup downloads MediaMTX v1.19.0 and
          generates the config with the app's stream key and an absolute
          recordings path. The relay is started/stopped from inside the
          app and shut down cleanly on close, restart and exit; a Record
          toggle routes output between the live and record paths; the app
          self-heals a stale local-relay URL on the next launch.
          Recordings (~/recordings) are listed in-app with play and
          delete. The old tee-muxer recording stub was removed; the major
          version bump to 3.0.0 marks recording becoming a first-class,
          built-in capability.

          The 3.0.0 line also carried a round of UI and stability work. A
          new Tools tab declutters the main tab bar: the occasional-use
          plugins (AI Playlist Builder, Chapter Markers, Multi-RTMP, SFTP
          Manager, YouTube Analytics) move into a Tools sub-notebook, joined
          by a Utilities panel holding the maintenance and download helpers
          (Update yt-dlp, ffmpeg version, Bulk Rename, Clear Temp Files)
          lifted out of Settings; Download was promoted to a top-level tab
          with YouTube Search nested beside it as a sub-tab. The
          reorganisation is pure relocation — every moved feature keeps its
          original handler and behaviour. Separately, all open/save/folder
          pickers were routed through one shared helper that calls the
          native GTK chooser (zenity) with the same filters, default names
          and last-used directory, falling back to the original tkinter
          dialogs when zenity is absent. Finally, an intermittent startup
          SIGSEGV was traced (via the apport core dump) to libXft crashing
          on the system Noto Color Emoji font; a guard at the top of
          streamer.py points fontconfig away from the colour-emoji font
          before Tk loads, so UI emoji fall back to monochrome glyphs and
          the crash is gone — app-scoped, with no system-wide font change.


================================================================
  PART 2 — REMOVED, REVERTED & ABANDONED FEATURES
================================================================

  These were built at some point but are NOT in the current
  v3.0.0 program. Kept here so they can be rebuilt or understood.

----------------------------------------------------------------
  Embedded web browser (Search tab)         introduced ~v1.05
----------------------------------------------------------------
  The original Search tab embedded a real web browser using
  tkinterweb, later explored again with CEF (Chromium Embedded
  Framework). Both were abandoned:
    - tkinterweb rendering was too limited for YouTube.
    - CEF (cefpython3) broke on Python 3.10+ and segfaulted; it
      was skipped entirely on 3.10+ and ultimately dropped.
  Replaced by: a plain "Open YouTube in browser" button plus the
  API-key-based Search tab (yt_search.py). A browser_tab.py
  remained in the tree as an experimental, non-loaded file.

----------------------------------------------------------------
  Add-to-playlist (from browser/search)     reverted ~v1.0.4
----------------------------------------------------------------
  An early feature let you add videos to the playlist directly
  from the embedded browser/search. It was deliberately reverted
  together with the embedded browser. The user explicitly asked
  to "revert back to a version without the web browser and without
  the add-to-playlist features." A v1_0.4_reverted.zip preserves
  that rollback. The Download tab's three-mode design (Single /
  Playlist / Channel) replaced this path.

----------------------------------------------------------------
  Mobile Screen Share                        shipped v2.0.4
----------------------------------------------------------------
  A dedicated input source that relayed a phone's screen into the
  stream over RTMP, with a panel showing the RTMP target address
  and an /api/mobile-screenshare endpoint. Built and packaged in
  v2.0.4 but not carried into the plugin-era builds. Could be
  rebuilt as a plugin (e.g. mobile_screen.py) exposing the RTMP
  listener + a Mobile Screen input radio.

----------------------------------------------------------------
  Lazy-loading of tabs / Settings           attempted, partly reverted
----------------------------------------------------------------
  To speed startup, tabs and Settings sub-tabs were made to build
  on first selection instead of at launch. Several attempts were
  reverted after crashes:
    - health_monitor set app.log_box during deferred build, which
      the core's startup log poller needed immediately → reverted
      to eager build.
    - my_channel showed a blank tab when deferred → reverted to
      eager (token restore stays in on_load).
  The surviving mechanism is the core-driven _deferred_build hook,
  used by multi_rtmp, recording, scheduler and yt_search. Plugin-
  side <<NotebookTabChanged>> bindings were found to be clobbered
  by the core's own bind and were abandoned in favour of the hook.

----------------------------------------------------------------
  UI polish pass                            reverted after segfault
----------------------------------------------------------------
  A round of UI restyling was rolled back after it caused a
  segfault (the recurring tkinter pattern: unicode/emoji in widget
  text, and building canvas/widgets before the main loop was
  ready). The lesson baked into later code: ASCII-only widget
  text, and defer canvas/build work via after().

----------------------------------------------------------------
  Built-in Help tab                         removed in v2.2.8
----------------------------------------------------------------
  The searchable in-app Help tab (help_tab.py, plus a core
  fallback Help tab) was removed. The 2,262-line help_tab.py also
  contained dead code — orphaned api_* routes and _build_channel_*
  methods left from before those split into remote_api.py and
  my_channel.py. Help content moved to the website Help Center.
  The real REST API was unaffected (it lives in remote_api.py).

----------------------------------------------------------------
  Debug / regression checklist plugin       removed in v2.2.8
----------------------------------------------------------------
  development.py added a top-level Development tab with a 330-item
  pass/fail/untested regression checklist, notes, filtering and
  report export, saved to ~/.yt_live_streamer_devtest.json. It was
  removed from the program and rebuilt as the public Status board
  on the website. The core _deferred_build hook it had used was
  kept (other plugins rely on it).

----------------------------------------------------------------
  Orphaned data file                        leftover
----------------------------------------------------------------
  ~/.yt_live_streamer_devtest.json may remain on machines that ran
  the development.py checklist. Nothing reads it now; safe to
  delete.


================================================================
  PART 3 — NUMBERING NOTES
================================================================

  - Early builds were tagged v1.00–v1.08, then renumbered to the
    v1.0.x form (v1.00→v1.0.0, etc.). Descriptions match across
    both schemes.
  - v1.1.4 was a version/README housekeeping tag, not a feature
    release.
  - v2.0.4 (Mobile Screen Share) shipped but did not continue into
    the plugin era.
  - v2.2.0–v2.2.3 were internal steps of the plugin migration;
    v2.2.4 is the first shipped plugin build. v2.2.5 was an
    interim consolidation build.
  - Within v2.2.8, Help and the debug checklist were removed and
    relocated to the website.

================================================================
  End of engineering history.
================================================================
