Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This is `ytx`, a .NET Global Tool that extracts YouTube video metadata and trans
2. YouTube video data extraction via YoutubeExplode
3. Caption track discovery and selection (prefers English, falls back to any available)
4. Transcript formatting (raw text + markdown with timestamped links) and caption status
5. JSON serialization to stdout
5. JSON serialization to stdout, or a transcript-only format (`--format md|txt|srt|vtt`) built from the normalized segments

## Development Commands

Expand Down
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ The positional URL and piped JSON forms are the original interfaces and remain s
(default: English). Falls back to English, then
any track, with a warning on stderr
--metadata-only Skip caption retrieval and return metadata only
-f, --format <format> json (default), or only the transcript as md, txt,
srt or vtt
--segments Add a segments array of {start, end, text} to the
JSON, with times in seconds
--list-languages List the video's caption tracks as JSON and exit
--proxy <url> Send requests through this proxy, such as
http://host:8080 or socks5://host:1080. Without it,
HTTPS_PROXY and the system proxy are used
--timeout <seconds> Give up after this many seconds (default: none)
-c, --compact Write compact JSON instead of indented JSON
-h, -?, --help Show help and exit
Expand All @@ -86,6 +94,19 @@ ytx dQw4w9WgXcQ
# Prefer French captions; falls back to English with a warning on stderr
ytx --language fr "https://www.youtube.com/watch?v=dQw4w9WgXcQ"

# See which caption tracks a video has
ytx --list-languages dQw4w9WgXcQ

# Write subtitles, or plain text with one caption per line
ytx --format srt dQw4w9WgXcQ > video.srt
ytx --format txt dQw4w9WgXcQ

# Add timed segments for agents and tools
ytx --segments dQw4w9WgXcQ

# Work from a server or CI runner through a proxy
ytx --proxy http://user:[email protected]:8080 dQw4w9WgXcQ

# Retrieve only the metadata and emit one-line JSON
ytx --metadata-only --compact "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
```
Expand Down Expand Up @@ -119,6 +140,11 @@ Every document has the same keys in the same order. Fields that YouTube does not
| `captionError` | Error message when `captionStatus` is `blocked` or `error` |
| `transcriptRaw` | All caption text as a single normalized string |
| `transcript` | Markdown list with `[HH:MM:SS](link) text` format |
| `segments` | With `--segments`, an array of `{start, end, text}` with times in seconds to the millisecond; otherwise `null` |

With `--format md|txt|srt|vtt`, only the transcript is written, with no JSON. If there is no transcript, stdout is empty and stderr says why. The exit codes are the same as for JSON.

`--list-languages` writes `{"videoId": "...", "tracks": [{"code": "en", "name": "English", "isAutoGenerated": false}, ...]}`. Pass a `code` or `name` from it to `--language`.

When `captionStatus` is not `ok`, the caption fields are `null` and both transcript fields are empty. Check `captionStatus` rather than the transcript text.

Expand Down Expand Up @@ -197,8 +223,8 @@ The GitHub Actions workflow uses NuGet Trusted Publishing and does not need a st

- Private, age-restricted, or region-blocked videos may not provide transcripts
- Videos with disabled captions return `captionStatus: "none"`
- YouTube blocks many cloud and datacenter IP addresses, which shows up as `captionStatus: "blocked"` or exit code `1`
- Timestamps are based on caption segment start times
- YouTube blocks many cloud and datacenter IP addresses, which shows up as `captionStatus: "blocked"` or exit code `1`. Use `--proxy` or `HTTPS_PROXY` with a residential proxy
- Markdown timestamps are rounded down to whole seconds; `segments`, SRT and WebVTT keep milliseconds
- Large transcripts are not truncated (full output provided)

## Dependencies
Expand Down
Loading
Loading