Streamlining media publishing: prepare, upload, and edit videos (YouTube) and podcasts
Project description
yb
Streamline media publishing: prepare a piece of media once, publish it anywhere — to YouTube (upload + edit) or as a podcast (show notes, chapters, RSS) — plus a download module for pulling videos back down.
import yb
# Download a video (-> ~/Downloads, named "Title (id).mp4")
r = yb.download_youtube_video("https://youtu.be/PRa9ciOe-us")
# One call: transcribe, write title/description/keywords, detect chapters,
# render a thumbnail, and upload to YouTube (unlisted) with captions.
yb.prepare_and_publish(r.path, language="English", language_code="en",
audio_language_code="en", privacy_status="unlisted")
Why
yb separates what you publish from where you publish it. A media file
is turned into a platform-neutral PublicationContent — title,
description, keywords, chapters, captions, thumbnail — and thin adapters map
that onto each destination's API. The media work itself (transcription, chapter
detection, thumbnails, dubbing/translation) lives in the
mixing package; yb is the
publication layer on top.
Install
pip install yb # core (needs `mixing`)
pip install 'yb[youtube]' # YouTube upload/edit (Google API client)
pip install 'yb[download]' # yt-dlp downloader
pip install 'yb[podcast]' # podcast chapters (ID3/PSC) + RSS
pip install 'yb[llm]' # LLM metadata/chapter copy (via `aix`)
pip install 'yb[all]' # everything
Everything heavy is an optional extra, and import yb never fails for a missing
one — the error only surfaces when you actually call that feature. You also need
ffmpeg on PATH for media work, and an ELEVENLABS_API_KEY for transcription.
Common tasks
Download
from yb.download import download_youtube_video, youtube_video_info
youtube_video_info(url) # metadata only, no download
download_youtube_video(url) # best quality -> ~/Downloads/"Title (id).mp4"
download_youtube_video(url, download_dir="~/clips", write_info_json=True,
write_subtitles=True, subtitle_langs=("en", "fr"))
The destination defaults to $YB_DOWNLOAD_DIR (else ~/Downloads). Every knob
— format, filename template, which sidecar metadata to also save — is
overridable, and any raw yt-dlp option can be passed via extra_opts=.
Publish to YouTube
from yb.youtube import prepare_and_publish, VideoMetadata, publish_video, CaptionTrack
# High level: prepare assets from the media file, then upload.
result = prepare_and_publish("promo.fr.mp4", language="French",
language_code="fr", audio_language_code="fr",
privacy_status="unlisted")
print(result["url"])
# Lower level: you supply the metadata and captions.
meta = VideoMetadata(title="...", description="...", tags=[...],
default_language="en", default_audio_language="en")
publish_video("promo.en.mp4", meta, privacy_status="unlisted",
captions=[CaptionTrack("promo.en.srt", "en", "English")],
thumbnail="thumb.jpg")
Chapters are on by default: when the media is long enough to host them
(YouTube requires ≥3 markers, each ≥10 s, first at 0:00), they are detected
from the transcript and embedded in the description so YouTube renders
interactive chapters. Short clips simply get none.
Edit an already-published video
from yb.youtube import update_video_fields, upsert_caption, set_chapters, set_thumbnail
from mixing.chapters import Chapter
update_video_fields("VIDEO_ID", title="New title", tags=["a", "b"])
upsert_caption("VIDEO_ID", "subs.fr.srt", language="fr", name="Français") # replaces same-lang track
set_chapters("VIDEO_ID", [Chapter(0, "Intro"), Chapter(45, "Demo")])
set_thumbnail("VIDEO_ID", "thumb.jpg")
Publish a podcast episode
from yb.podcast import prepare_podcast_episode, PodcastChannel, EpisodeFeedItem, build_feed
ep = prepare_podcast_episode("episode.mp3", "out/",
cover_image="cover.jpg", make_cover_video=True)
# -> out/episode.mp3 (with ID3 chapters), .shownotes.txt, .psc.xml,
# .chapters.json, and .cover.mp4
# Assemble an RSS feed (delivery to Spotify/Apple is via your podcast host).
A podcast episode and a YouTube video are built from the same
PublicationContent: an episode "could just be audio with a cover image" (or a
Ken Burns video), which is exactly what prepare_podcast_episode can render.
Setup (YouTube OAuth)
YouTube upload needs a Google OAuth Desktop client (one-time). gcloud is
not required — the console path works. See the yb-setup skill for the
full walkthrough (enable the API, create the OAuth client, run consent, test).
Point yb at the client JSON via $YOUTUBE_CLIENT_SECRETS_FILE.
Note: until your Google Cloud project passes YouTube's one-time API compliance audit, uploads may be forced to private even when you request
unlisted/public.
Layout
| Module | Role | Extra |
|---|---|---|
yb.content |
platform-neutral content prep (metadata, chapters, thumbnail) | core |
yb.youtube |
upload + edit via YouTube Data API v3 | youtube |
yb.podcast |
show notes, ID3/PSC chapters, cover video, RSS | podcast |
yb.download |
yt-dlp downloader | download |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file yb-0.1.3.tar.gz.
File metadata
- Download URL: yb-0.1.3.tar.gz
- Upload date:
- Size: 32.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac2b0fc633047123ffb774ac2de270d559c4a71da05afcdd5f431629de62d5ba
|
|
| MD5 |
2434f8bcecf33c696d00029067883f7a
|
|
| BLAKE2b-256 |
235ffd8d311ddbb5513aa099978bbefffd3e3a7baf8ffbefc712c4f9c5f5d1c4
|
File details
Details for the file yb-0.1.3-py3-none-any.whl.
File metadata
- Download URL: yb-0.1.3-py3-none-any.whl
- Upload date:
- Size: 37.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9da68e211f099814f8b12b6818bcb08019057785bc2e5a64797ae55ff307d089
|
|
| MD5 |
d3cf1a9146432278b82abc13e0d7d716
|
|
| BLAKE2b-256 |
860bfc4cd8e57adfc34703524ff1d63e1f8209cc2e6956bdba55c5b2277be35d
|