Skip to main content

AI-powered YouTube Shorts generator — script, TTS, visuals, assemble, upload

Project description

utube

AI-powered YouTube Shorts generator. Give it a topic — it writes the script, synthesizes narration, fetches stock visuals, assembles the video, and uploads it to YouTube. Supports Vietnamese-language content via VBee TTS.

Python 3.12+ License: MIT

How it works

topic → script (LLM) → assets (TTS + visuals) → assemble → upload
Step What happens Providers
script LLM generates title, scenes, narration, tags Anthropic, OpenAI-compatible
assets TTS audio + stock visual fetched per scene OpenAI TTS, ElevenLabs, VBee
assemble MoviePy builds the final MP4 + thumbnail
upload Uploads to YouTube with title, description, tags YouTube Data API v3

Each step is independently resumable — a failed or interrupted job can be continued from where it left off.

Examples

Videos generated with this tool:

Requirements

  • Python 3.12+
  • uv — dependency manager
  • FFmpeg — required by MoviePy for video encoding

Installation

git clone https://github.com/your-org/utube.git
cd utube
uv sync

Configuration

cp .env.example .env
# Edit .env with your API keys

Minimum required keys

Variable Description
LLM_PROVIDER anthropic or openai (default: openai)
ANTHROPIC_API_KEY Required if LLM_PROVIDER=anthropic
OPENAI_API_KEY Required if LLM_PROVIDER=openai
TTS_PROVIDER openai, elevenlabs, or vbee
PEXELS_API_KEY Stock video/photo visuals (free tier works)

See .env.example for the full variable reference.

Usage

Run end-to-end

uv run utube run --niche "5 mind-blowing facts about black holes"

Runs all four steps and uploads as private by default.

Common flags

Flag Description
--visibility private (default), unlisted, or public
--public Shorthand for --visibility public
--no-auto Stop after script — review before continuing
--audio-speed X Narration speed multiplier (e.g. 1.2 for faster)
--caption Overlay on-screen text captions on each scene

Resume or restart a job

uv run utube continue <job_id>                   # advance one step
uv run utube continue <job_id> --from assets     # restart from assets step
uv run utube status  <job_id>                    # inspect current state

Restart targets: script, assets, assemble, upload.

YouTube auth (first time)

uv run utube auth     # opens browser, caches token
uv run utube whoami   # verify the connected channel

Place your Google OAuth client secret at secrets/client_secret.json before running auth. See the YouTube Data API docs for how to create OAuth credentials.

Job files

Each run creates a directory under ./jobs/<job_id>/ containing all intermediate files: script JSON, per-scene MP3s, visuals, final MP4, and thumbnail.

Vietnamese content with VBee

VBee is a Vietnamese AI TTS platform with high-quality voices. Set it as your TTS provider to generate Vietnamese-language Shorts.

TTS_PROVIDER=vbee
VBEE_API_TOKEN=your_token
VBEE_APP_ID=your_app_id
VBEE_VOICE_CODE=hn_female_ngochuyen_full_48k-fhg   # default
VBEE_WEBHOOK_URL=https://your-server.com/vbee/callback
VBEE_SPEED=1.0

VBee uses an async batch API — the tool submits the synthesis job and polls the webhook URL for the result. VBEE_WEBHOOK_URL must be a publicly reachable HTTPS endpoint that VBee can POST the audio back to.

Extending

utube uses a provider registry pattern. Adding a new TTS, visuals, or LLM provider requires only a new file — no edits to existing pipeline code.

Example: add a TTS provider

# src/utube/providers/tts/mytts.py
from utube.providers.registry import register_tts
from utube.providers.base import TTSProvider

@register_tts("mytts")
class MyTTS:
    async def synthesize(self, text: str, voice: str) -> bytes:
        ...  # return raw audio bytes

Then set TTS_PROVIDER=mytts in .env. The same pattern applies to:

  • LLM / script providers — implement ScriptProvider, register with @register_script
  • Visuals providers — implement VisualProvider, register with @register_visual

See src/utube/providers/base.py for the Protocol definitions.

Development

uv run pytest                  # run all tests
uv run ruff check src tests    # lint
uv run mypy src                # type-check

Tests never hit the network — all HTTP and external clients are mocked. New provider implementations should follow the same pattern.

Contributing

Pull requests are welcome. For significant changes, open an issue first to discuss the approach.

License

MIT

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

utube_shorts-0.1.0.tar.gz (111.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

utube_shorts-0.1.0-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

Details for the file utube_shorts-0.1.0.tar.gz.

File metadata

  • Download URL: utube_shorts-0.1.0.tar.gz
  • Upload date:
  • Size: 111.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for utube_shorts-0.1.0.tar.gz
Algorithm Hash digest
SHA256 75f0cbd2c5ca6c2348946ac52225eaaea5e6f5c7a626b2cbe957f190f029aaaf
MD5 2547114c1058b53095c1c197bb655504
BLAKE2b-256 9dd83f2de2b85778bdd1b840288360a530e00a55b961acaf07d8046834873d88

See more details on using hashes here.

Provenance

The following attestation bundles were made for utube_shorts-0.1.0.tar.gz:

Publisher: python-publish.yml on viet-dinh/utube

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file utube_shorts-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: utube_shorts-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for utube_shorts-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6b0ae4573b05a0965390c47da0b7b3c485052552a7dfeb884569d1a889c08323
MD5 c90a3b7e911776fe36dfb99671174dc1
BLAKE2b-256 91c079fd5c28254618adeb2fd1470f86d89ed3c9d9723c72a8f1d3155fef2c44

See more details on using hashes here.

Provenance

The following attestation bundles were made for utube_shorts-0.1.0-py3-none-any.whl:

Publisher: python-publish.yml on viet-dinh/utube

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page