Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

Short video automation

Turn a long YouTube workshop into chapters, YouTube description timestamps, per-chapter transcript JSON, social posts, optional ffmpeg split commands, and optional Typefully drafts with video attached.

Each video is stored in a folder at the project root named after the 11-character YouTube video ID (for example 5eMytPBgmVs/).


Prerequisites

  • Python 3.10+ (uses type hints and standard library patterns from recent 3.x)
  • ffmpeg on your PATH if you plan to run the generated split commands (not required for transcript/chapter/social steps)
  • OpenAI API key for chapter detection and social copy (scripts/create_chapters.py, scripts/create_social_post.py)
  • YouTube Data API is not used; transcripts come from youtube-transcript-api
  • Optional: Oxylabs proxy env vars if YouTube blocks plain transcript requests
  • Optional: Typefully API key and matching social set ID in code for scripts/create_typefully_drafts.py

Setup

1. Clone and enter the repo

cd short-video-automation

2. Create a virtual environment and install dependencies

python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt

3. Configure environment variables

Copy the example env file and edit it:

cp .env.example .env
Variable Required for Purpose
OPENAI_API_KEY create_chapters.py, create_social_post.py OpenAI API
TYPEFULLY_API_KEY create_typefully_drafts.py Typefully API
OXYLABS_USER, OXYLABS_ENDPOINT, OXYLABS_PASSWORD youtube.py only, optional Proxy for transcript fetches

scripts/youtube.py and the other scripts load .env from the project root (the parent of scripts/).


End-to-end pipeline (recommended order)

Run all commands from the project root so relative paths like VIDEO_ID/ resolve correctly.

Step 1 — Download transcript as JSON

Script: scripts/youtube.py
Input: YouTube URL or bare video ID
Output: <VIDEO_ID>/full_transcript.json (Whisper-like shape: text + segments with start, end, text)

python scripts/youtube.py "https://www.youtube.com/watch?v=VIDEO_ID"
# or
python scripts/youtube.py VIDEO_ID

Step 2 — Generate topic chapters with OpenAI

Script: scripts/create_chapters.py
Input: Folder containing full_transcript.json (or path to that file)
Output: <VIDEO_ID>/chapters.json (starts, titles, summaries, standalone_post_candidate)

python scripts/create_chapters.py VIDEO_ID

Step 3 — Split transcript into per-chapter files and a table CSV

Script: scripts/split_transcript_into_chapters.py
Input: full_transcript.json + chapters.json in the same folder
Output:

  • <VIDEO_ID>/chapters/chapter_0001.json, …
  • <VIDEO_ID>/chapters-table.csv (columns: chapter, start, end, title)
python scripts/split_transcript_into_chapters.py VIDEO_ID

Step 4 — YouTube chapter lines (description timestamps)

Script: scripts/write_youtube_chapters.py
Input: chapters.json
Output: youtube-chapters.txt next to it (each line: HH:MM:SS Title)

python scripts/write_youtube_chapters.py VIDEO_ID/chapters.json
# custom output:
python scripts/write_youtube_chapters.py VIDEO_ID/chapters.json -o VIDEO_ID/my-chapters.txt

Paste the contents of youtube-chapters.txt into the video description. YouTube expects the first chapter to start at 00:00:00.

Step 5 — Generate social posts (batch into CSV)

Script: scripts/create_social_post.py

  • Batch mode (directory = chapters/): processes every chapter_*.json where standalone_post_candidate is "yes", calls OpenAI, and writes the post into the social_post column of chapters-table.csv (column is created if missing).
python scripts/create_social_post.py VIDEO_ID/chapters
  • Single chapter (one file): prints the post to stdout; optional --output file.
python scripts/create_social_post.py VIDEO_ID/chapters/chapter_0003.json --output /tmp/post.txt

Optional: --model (default in script: gpt-5.4-mini), --table in batch mode to point at a non-default CSV path.

Step 6 — Append ffmpeg commands for chapters that have a social post (optional)

Script: scripts/generate_ffmpeg_commands.py

Requirements:

  • chapters-table.csv must include a social_post column (added when you run batch create_social_post.py; you can also fill cells manually for chapters you want to clip).
  • youtube-chapters.txt must already exist in the same folder (create it with Step 4 first).

The script appends to youtube-chapters.txt: a watch URL derived from the parent folder name (treated as video ID), a Commands: heading, and one stream-copy command per row with non-empty social_post:

ffmpeg -ss START -to END -i input.mp4 -c copy chapter_XXXX.mp4

Examples:

# Defaults: ./chapters-table.csv and ./youtube-chapters.txt (run inside VIDEO_ID/)
cd VIDEO_ID
python ../scripts/generate_ffmpeg_commands.py . --input-file ../downloads/my_video.mp4

# From project root:
python scripts/generate_ffmpeg_commands.py VIDEO_ID --input-file /path/to/source.mp4

Adjust --input-file to your real source file name/path as printed inside the commands.

Step 7 — Create Typefully drafts with video (optional)

Script: scripts/create_typefully_drafts.py

For each CSV row with non-empty social_post, expects chapter_XXXX.mp4 in the same folder as the CSV (or --folder). Uploads media, waits for processing, attaches to an X (Twitter) draft.

export TYPEFULLY_API_KEY=...   # or set in .env
python scripts/create_typefully_drafts.py VIDEO_ID/chapters-table.csv --folder VIDEO_ID
python scripts/create_typefully_drafts.py VIDEO_ID/chapters-table.csv --dry-run

Note: SOCIAL_SET_ID in the script is set for a specific Typefully social set; change it in scripts/create_typefully_drafts.py to match your account.


Folder layout (after a full run)

VIDEO_ID/
  full_transcript.json      # from youtube.py
  chapters.json             # from create_chapters.py
  chapters-table.csv        # from split + social_post from create_social_post
  youtube-chapters.txt      # from write_youtube_chapters (+ optional ffmpeg block)
  chapters/
    chapter_0001.json
    chapter_0002.json
    ...

Troubleshooting

  • Transcript errors / IP blocks: set Oxylabs variables in .env and retry youtube.py.
  • generate_ffmpeg_commands says output file not found: run write_youtube_chapters.py first so youtube-chapters.txt exists.
  • No chapters with non-empty social_post: run batch create_social_post.py on VIDEO_ID/chapters, or add social_post text manually for the rows you need.
  • Typefully skips uploads: ensure each chapter_XXXX.mp4 exists next to the CSV or in --folder.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages