---
name: download-youtube-segment
description: Download a specific time range from a YouTube video with yt-dlp and ffmpeg while keeping the original streams. Use when the user wants only part of a YouTube video instead of the full download, asks to save a local segment from a public YouTube URL, or needs a reusable workflow for clipping by start/end time or start/duration.
---

# Download YouTube Segment

## Overview

Use `scripts/download-clip.py` to fetch direct media URLs with `yt-dlp` and cut only the requested range with `ffmpeg` without re-encoding. Prefer this over downloading the full source when bandwidth or time matters.

In this repository, save the resulting clips and extracted frames under `assets/` by default unless the user explicitly asks for another location.

## Quick Start

1. Confirm `yt-dlp` and `ffmpeg` are installed.
2. Collect the YouTube URL, clip start, and either clip end or clip duration.
3. Run `scripts/download-clip.py <url> <start> <end|+duration> <output.mp4>`.
4. Use `--dry-run` first when you need to verify the computed seek point and duration.

If the task also needs transcript context, subtitle timing, or quote selection, inspect and save subtitles before clipping:

```bash
yt-dlp --list-subs --no-warnings "https://www.youtube.com/watch?v=FXnC79xdnXQ"

yt-dlp \
  --skip-download \
  --write-sub \
  --sub-langs ru \
  --convert-subs srt \
  -o "assets/%(id)s.%(ext)s" \
  "https://www.youtube.com/watch?v=FXnC79xdnXQ"
```

This saves a subtitle file such as `assets/FXnC79xdnXQ.ru.srt`. If the video has no regular subtitles, try `--write-auto-sub` instead of `--write-sub`.

Example:

```bash
scripts/download-clip.py \
  "https://www.youtube.com/watch?v=FXnC79xdnXQ" \
  "50:00" \
  "51:20" \
  "assets/FXnC79xdnXQ-50m00s-to-51m20s.mp4"
```

The script also accepts a relative duration:

```bash
scripts/download-clip.py \
  "https://www.youtube.com/watch?v=FXnC79xdnXQ" \
  "50:00" \
  "+80" \
  "assets/clip.mp4"
```

## Workflow

1. Normalize the request into:
   - `url`
   - `start`
   - `end` or `duration`
   - output filename, usually under `assets/`
2. If the user gives `start` and `end`, pass both directly to the script.
3. If the user gives `start` and `duration`, prefix the duration with `+`.
4. Run `--dry-run` when you need to confirm the timing math before downloading.
5. Run the real command and report the output file path.

If the request involves finding a strong quote, picking a meme moment, or understanding the spoken content before clipping:

6. Run `yt-dlp --list-subs --no-warnings <url>` to see which subtitle languages exist.
7. Save the most useful subtitle track into `assets/` with `yt-dlp --skip-download --write-sub ... --convert-subs srt`.
8. If no normal subtitles exist, retry with `--write-auto-sub`.
9. Use the saved `.srt` as the text source for beat selection, quote search, and exact meme/punchline discovery before downloading or trimming final clips.

The script seeks a little earlier than the requested start and keeps that lead-in in the final file. By default it also keeps matching tail padding after the requested end, which makes later manual trimming easier.

## Script Behavior

- Default lead-in padding is 5.5 seconds.
- Override lead-in padding with `PREROLL_SECONDS=<value>`.
- Override tail padding with `POSTROLL_SECONDS=<value>`; by default it matches `PREROLL_SECONDS`.
- Accept timestamps as `SS`, `MM:SS`, or `HH:MM:SS`, with optional decimals.
- Copy the original streams without re-encoding for faster downloads and no generation loss.
- Prefer MP4-compatible source streams when asking `yt-dlp` for direct media URLs.
- For YouTube URLs, auto-enable `--js-runtimes node` when `node` is installed and default `--extractor-args` to `youtube:player_client=ios,android`.
- Add `-movflags +faststart` so the resulting MP4 is friendlier for playback and upload workflows.
- Override yt-dlp behavior with `YTDLP_JS_RUNTIMES`, `YTDLP_EXTRACTOR_ARGS`, `YTDLP_COOKIES_FROM_BROWSER`, `YTDLP_COOKIES`, or `YTDLP_EXTRA_ARGS`.

## Troubleshooting

- If `yt-dlp -g` returns fewer than two URLs, the script falls back to a single input when possible.
- If the clip needs more or less extra context, adjust `PREROLL_SECONDS` and `POSTROLL_SECONDS` and rerun. Stream copy is less frame-accurate than re-encoding.
- If the process is slower than expected, note that remote seeking is still network-bound; for long clips, full download plus local trim may be faster.
- If the subtitle command downloads nothing, first check `--list-subs`; many videos have only auto-captions or only specific languages.
- If the video is private, geo-restricted, members-only, or DRM-protected, expect this workflow to fail.

## Resources

- `scripts/download-clip.py`: Python entrypoint that fetches direct stream URLs and cuts the requested range into a local MP4 file.
