Skip to main content

Extract slides from YouTube presentations with transcript text

Project description

yt-slide-mark

Extract slides from YouTube presentations and pair them with transcript text.

Takes a YouTube video URL, downloads the video, extracts unique slide frames using SSIM comparison, fetches the transcript with timestamps, maps text to slides, restores punctuation, and generates a Markdown document with embedded slide images and clickable YouTube timestamps.

Installation

pip install yt-slide-mark

Or with uv:

uv pip install yt-slide-mark

Usage

# Single video
yt-slide-mark "https://youtube.com/watch?v=VIDEO_ID"

# Batch — from a file with URLs
yt-slide-mark -b urls.txt

# Without installing (via uvx)
uvx yt-slide-mark "https://youtube.com/watch?v=VIDEO_ID"

# Or via python -m
python -m yt_slide_mark "https://youtube.com/watch?v=VIDEO_ID"

Options

yt-slide-mark <url> [-b FILE]
  -b, --batch FILE        Text file with URLs (one per line)
  -l, --language          Transcript language (default: en)
  -o, --output            Output directory (default: ./output)
  --similarity            SSIM threshold 0.0-1.0 (default: 0.85)
  --sample-interval       Seconds between frame checks (default: 1.0)
  --cooldown              Seconds to skip after new slide detected (default: 10.0)
  --include REGION        Only compare within this region (repeatable)
  --exclude REGION        Ignore this region during comparison (repeatable)
  --no-punctuate          Disable punctuation restoration
  --keep-video            Keep the downloaded video file
  -v, --verbose           Verbose logging

Region of interest (--include / --exclude)

Lecture videos often show the speaker alongside slides, causing excessive slide detections. Use --include or --exclude to limit which part of the frame is used for SSIM comparison. Full frames are still saved as slide images.

Format: x1,y1-x2,y2 — two diagonal corners of a rectangle. Values can be pixels or percents:

--exclude 0,400-200,720          # pixels: exclude bottom-left speaker area
--include 25%,0%-100%,100%       # percents: only compare right 75% of frame

Multiple regions can be specified by repeating the flag:

--exclude 0,80%-25%,100% --exclude 75%,80%-100%,100%

--include and --exclude are mutually exclusive.

Batch file format

One URL per line. Blank lines and # comments are ignored:

# lectures.txt
https://youtube.com/watch?v=VIDEO1
https://youtube.com/watch?v=VIDEO2

# this one is optional
https://youtube.com/watch?v=VIDEO3

Examples

# Basic usage
yt-slide-mark "https://youtube.com/watch?v=dQw4w9WgXcQ"

# Custom output directory, verbose
yt-slide-mark "https://youtube.com/watch?v=dQw4w9WgXcQ" -o ./my_notes -v

# Skip punctuation, keep video, lower similarity threshold
yt-slide-mark "https://youtube.com/watch?v=dQw4w9WgXcQ" --no-punctuate --keep-video --similarity 0.80

# Faster sampling for long lectures, wider cooldown
yt-slide-mark "https://youtube.com/watch?v=dQw4w9WgXcQ" --sample-interval 2.0 --cooldown 15.0

# Exclude speaker area in bottom-left corner (pixels)
yt-slide-mark "https://youtube.com/watch?v=dQw4w9WgXcQ" --exclude 0,500-250,720

# Only compare the slide area (right 75% of frame, percents)
yt-slide-mark "https://youtube.com/watch?v=dQw4w9WgXcQ" --include 25%,0%-100%,100%

# Batch: process a list of videos from file
yt-slide-mark -b lectures.txt -o ./lectures -v

Output

output/video-title/
├── video-title.md
└── slides/
    ├── slide_001.jpg
    ├── slide_002.jpg
    └── ...

The Markdown file contains:

  • Video title, author, and source link
  • Each unique slide as a JPEG image
  • Clickable YouTube timestamps linking to the exact moment
  • Transcript text mapped to each slide with restored punctuation

In batch mode, each video gets its own subfolder. A summary is printed at the end showing successes and failures; one failed video does not stop the rest.

Pipeline

YouTube URL
  → extract video ID
  → get video info (noembed.com API)
  → download video (yt-dlp, 720p)
  → fetch transcript (youtube-transcript-api, 4-level fallback)
  → extract unique frames (OpenCV + SSIM)
  → map transcript to slides (by timestamps)
  → restore punctuation (punctuators pcs_en, ONNX)
  → generate Markdown

Dependencies

  • youtube-transcript-api — transcript fetching with fallbacks
  • yt-dlp — video downloading
  • opencv-python-headless — frame extraction
  • scikit-image — SSIM structural similarity
  • punctuators — punctuation/capitalization restoration (ONNX, CPU)
  • requests — video metadata via noembed.com

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

yt_slide_mark-1.0.0.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

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

yt_slide_mark-1.0.0-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file yt_slide_mark-1.0.0.tar.gz.

File metadata

  • Download URL: yt_slide_mark-1.0.0.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for yt_slide_mark-1.0.0.tar.gz
Algorithm Hash digest
SHA256 06d868ea1e43115565fe8fc15a5316822f2385c7eed1650a9f81be720c339132
MD5 1ed92ca1da670efb5493346659e6cfe7
BLAKE2b-256 3c9613f095ddc71245c9ec98ef51c3f90dcf41770a6cb06875ae36f5b1921887

See more details on using hashes here.

File details

Details for the file yt_slide_mark-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: yt_slide_mark-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 16.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for yt_slide_mark-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c89e6c51d7632eaa11c7ac74823c5a2d7ba3c92f255eaccbb542078d17d192ff
MD5 0d0e6ca6f249c2ebdae3447baebb2475
BLAKE2b-256 27f77568bef1797adece2ebd6438d54180c7d022fc4677ab10360e0620ff5b13

See more details on using hashes here.

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