Skip to content

feat: livestreams command for managing YouTube live broadcasts - #12

Merged
jdwit merged 2 commits into
mainfrom
feat/livestreams
May 26, 2026
Merged

jdwit merged 2 commits into
mainfrom
feat/livestreams

Conversation

@jdwit

@jdwit jdwit commented May 26, 2026

Copy link
Copy Markdown
Owner

Summary

Add a new ytstudio livestreams typer app with list, show, schedule, start, stop, and update subcommands driving the YouTube liveBroadcasts API. Inspired by ParkerClelland/ytstudio-cli but rewritten against the current codebase and reviewed against the YouTube Live API docs.

What you get

  • livestreams list with --status all|upcoming|active|completed and table/json output.
  • livestreams show <id> with optional --ingest (RTMP/RTMPS URLs from the bound liveStream) and --show-key (reveals the stream key; redacted by default).
  • livestreams schedule with --title, --scheduled-start, optional --scheduled-end, --privacy, --description, --made-for-kids/--not-made-for-kids and --execute (dry-run is default).
  • livestreams start <id> with --to testing|live for the monitor-stream-first workflow.
  • livestreams stop <id> for transition to complete.
  • livestreams update <id> partial update; only sends the parts that actually changed, but always carries contentDetails.monitorStream when contentDetails is touched (YouTube rejects updates that omit it).

Improvements vs. the fork

  • Stream key plumbing. show --ingest fetches the bound liveStream and prints ingestionAddress/rtmpsIngestionAddress plus their backups; streamName is masked unless --show-key is passed explicitly.
  • Monitor-stream preservation. Update keeps monitorStream.enableMonitorStream and broadcastStreamDelayMs on every contentDetails write, fixing the fork's silent bug.
  • update aligned with API surface. Drops the --made-for-kids flag here because liveBroadcasts.update only accepts privacyStatus under status; the COPPA flag is set at schedule time.
  • Friendly errors. livePermissionBlocked, insufficientLivePermissions, errorExecutingTransition, rate-limit and concurrency errors map to actionable messages instead of raw HttpError.
  • Typed output. --output is an enum (table/json); anything else is rejected.
  • No em-dash / smart unicode. Uses ASCII - for empty cells.
  • Demo mode. _DemoLiveBroadcasts + _DemoLiveStreams and broadcasts.json / live_streams.json fixtures so YTSTUDIO_DEMO=1 drives the new commands offline.

Out of scope (deliberate follow-ups)

  • Auto-create-and-bind a liveStream from schedule (today you bind in Studio or with an encoder). Would add ~50 quota units and another OAuth-scoped write; worth a separate PR.
  • Setting made-for-kids on the broadcast's resulting video resource via videos.update.

Review

Reviewed first by myself, then handed to Codex via the rescue subagent. Codex returned 1 high (the monitorStream bug), 2 medium (status update surface, demo update validation), 3 low (missing error reasons, missing RTMPS backup, untyped --output). All five were applied in commit b1a6e54; the demo update validation was intentionally left as echo since demo mode is an offline aid, not a contract test.

Test plan

  • pytest -q -> 164 passed (was 134 on main)
  • ruff check . and ruff format --check . -> clean
  • YTSTUDIO_DEMO=1 ytstudio livestreams list --status all shows seeded demo broadcasts
  • YTSTUDIO_DEMO=1 ytstudio livestreams show demo-broadcast-upcoming-1 --ingest shows redacted stream key
  • YTSTUDIO_DEMO=1 ytstudio livestreams update demo-broadcast-upcoming-1 --no-dvr dry-run shows old/new diff
  • Smoke test against a real channel with live streaming enabled (manual, before/after merge)

jdwit added 2 commits May 26, 2026 22:31
New 'ytstudio livestreams' typer app with list, show, schedule, start, stop,
update subcommands driving the YouTube liveBroadcasts API. Inspired by the
ParkerClelland fork but rewritten against the current codebase.

Improvements over the fork's implementation:

- 'show --ingest' fetches the bound liveStream and prints the RTMP URLs; the
  stream key is redacted unless '--show-key' is passed explicitly.
- 'start --to testing|live' covers the monitor-stream transition that streamers
  use to verify a feed before going live.
- 'update' computes a partial change set, only touching the contentDetails
  part when any contentDetails field is actually changed.
- ASCII '-' for empty values (project style) and no redundant
  BroadcastStatus.to_api_value mapping.
- Demo-mode support via _DemoLiveBroadcasts and _DemoLiveStreams plus
  broadcasts.json / live_streams.json fixtures so 'YTSTUDIO_DEMO=1' can drive
  the new commands offline.

Tests cover list/filter/empty, show with ingest redaction and reveal, start to
testing vs live, stop, schedule dry-run vs execute body, partial update body,
and friendly error mapping for liveStreamingNotEnabled. 160 tests pass, ruff
clean.
- Preserve contentDetails.monitorStream (enableMonitorStream + broadcastStreamDelayMs)
  on update; YouTube rejects contentDetails updates that omit it.
- Drop --made-for-kids from update; liveBroadcasts.update only accepts privacyStatus
  under status. Schedule keeps the flag (the resource is set on insert).
- Parse and surface rtmpsBackupIngestionAddress in show --ingest.
- Add OutputFormat enum so --output rejects anything other than table/json.
- Expand _LIVESTREAM_ERRORS map with livePermissionBlocked, insufficientLivePermissions,
  errorExecutingTransition, userRequestsExceedRateLimit,
  concurrentBroadcastsExceedLimit, sharedIngestionBroadcastsExceedLimit.
- Demo broadcasts.json fixtures carry monitorStream so demo mode mirrors the
  real resource shape.

Tests cover monitorStream preservation through partial update, --output json
redaction vs reveal, RTMPS backup display, and rejection of invalid --output
values.
@jdwit
jdwit merged commit e86ae32 into main May 26, 2026
5 checks passed
@jdwit
jdwit deleted the feat/livestreams branch May 26, 2026 20:50
@jdwit jdwit mentioned this pull request May 26, 2026
3 tasks done
jdwit added a commit that referenced this pull request May 26, 2026
Highlights since v0.1.1:

- Multi-channel profile support: 'ytstudio profile add/use/list/remove'
  with per-profile credential storage and automatic migration from
  single-channel installs (#10).
- New 'ytstudio livestreams' command: list/show/schedule/start/stop/update
  YouTube live broadcasts, with stream-key handling and demo-mode support
  (#12).
- New 'yts' short CLI alias (#11).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant