Skip to content

feat(stream): video libraries, directory linking, uploads, and video management - #203

Draft
amir-at-bunny wants to merge 3 commits into
mainfrom
feat/stream
Draft

feat(stream): video libraries, directory linking, uploads, and video management#203
amir-at-bunny wants to merge 3 commits into
mainfrom
feat/stream

Conversation

@amir-at-bunny

@amir-at-bunny amir-at-bunny commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

A new experimental stream namespace for managing bunny.net Stream, plus a small openapi-client fix (verbose logging skips binary request bodies, redacts secret-shaped fields, and surfaces Stream API error messages).

Commands

bunny stream library (aliases libraries, lib)

  • list, create, show, update, delete
  • credentials: retrieve a library's Stream API keys (masked unless --show-secret)
  • link / unlink: bind the current directory to a library via .bunny/stream.json so other stream commands can omit --lib
  • create/update carry the encoding and transcribing settings: --encoding-tier, --jit, --codecs, --resolutions, --transcribing, --transcribing-languages, and the generation toggles

bunny stream video (alias videos)

  • upload <file>: create-and-upload in one command; files over 2 GiB upload resumably via TUS
  • fetch <url>: server-side fetch of a remote video, with --header for authenticated origins
  • list (--search, --collection), show, update (--title, --collection, --chapters, --moments), delete
  • thumbnail (--url or --file), resolutions, cleanup, stats (--heatmap, --play-data)
  • upload and fetch accept --collection and --thumbnail-time

bunny stream collection (alias collections)

  • create, list, show, rename, delete

bunny stream caption (alias captions)

  • add <video> <lang> --file (.vtt/.srt), delete <video> <lang>

Paid operations

  • bunny stream encode enable / encode reencode
  • bunny stream transcribe <video> (--languages, --source-language, --generate-*, --force)
  • bunny stream smart <video> (--title, --description, --chapters, --moments)

All commands support --output json|csv|markdown, resolve the library from --lib <id>, the linked directory, or an interactive picker, and take --force to skip confirmations non-interactively.

@changeset-bot

changeset-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 65772e2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

…face Stream error messages

Verbose debug logging read every request body as JSON, which would buffer
an entire video into memory on octet-stream uploads; non-JSON bodies are
now described from their headers instead. Error extraction also learns the
Stream API's StatusModel shape (lowercase message), so 400/422/429 responses
carry the API's explanation instead of a generic HTTP error.
…management

New experimental stream namespace:
- stream library: list, create, show, credentials, delete (aliases: libraries, lib)
- stream link / unlink: bind a directory to a library via .bunny/stream.json
- stream upload: local file via binary PUT, or a URL fetched server side
  (--header for authenticated origins); library from --lib <id>, the linked
  directory, or an interactive picker
- stream videos: list, show, update, delete by GUID

Library CRUD runs on the core API with the account key; uploads and video
commands use the library's own Stream API key, resolved automatically.
No output format prints API keys (credentials --show-secret is the
deliberate reveal path); JSON output strips ApiKey, ReadOnlyApiKey, and
the deprecated ApiAccessKey.
…ctions, and captions

Restructure: the video group is canonical (videos stays an alias), upload
splits into video upload (local files) and video fetch (server-side URL
fetch with --header/--collection/--thumbnail-time), and link/unlink move
under library.

library update: new command for library settings, sharing the encoding and
transcribing flags with create (--encoding-tier, --jit, --codecs,
--resolutions, --transcribing and its language/generation options); sparse
bodies send only the flagged fields, and a no-flag TTY run opens an
interactive editor.

New video verbs: thumbnail (--url or --file), resolutions, cleanup (full
selector surface, confirmed, --dry-run), stats (--heatmap/--play-data),
and update gains --collection/--chapters/--moments.

New namespaces: collection (create/list/show/rename/delete) and caption
(add with the API's validation surfaced, delete). Paid operations: encode
enable/reencode, transcribe, and smart, each printing its billing note;
smart confirms before implicitly transcribing a caption-less video.

Uploads over 2 GiB switch to TUS resumable uploads automatically: 64 MiB
chunks, every request signed, offsets driven by the server, and resume via
HEAD after transient failures.

openapi-client: verbose debug logging redacts secret-shaped fields (keys,
passwords, tokens, authorization headers) from request and response body
dumps.

Hardening from review: pagination drains tolerate absent or misreported
totalItems, --force disables pickers on paid commands too, collection show
requests the preview URLs it documents, and video show reports captions.
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