farrakhan1986 889c5fc8ef [fix] add jitter to exponential retry backoff
Without jitter, multiple concurrent instances that hit the same
transient error will wake up and retry simultaneously, creating
a stampede. Adding up to 0.5 s of uniform random jitter spreads
the retries out without meaningfully increasing average wait time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 05:27:45 +00:00

Chat Downloader

chat-downloader-2026 is a maintained fork of xenova/chat-downloader for retrieving chat messages from YouTube and Twitch. It supports CLI usage, a small Python API, multiple output formats, and focused tooling for debugging parser changes.

This fork targets Python 3.10+ and keeps the project source-compatible for users who already know the upstream package, while improving typing, testing, Twitch coverage, and internal maintainability.

Highlights

  • Download chat from YouTube and Twitch URLs through one interface.
  • Use the CLI or embed the library in Python code.
  • Write to json, jsonl, csv, and txt.
  • Attach more than one output at the same time with repeated --output.
  • Supply cookies, proxy settings, custom headers, and a custom user agent when the platform requires them.
  • Filter by time range, message groups, message types, and message limits.
  • Use typed request/config dataclasses: ChatRequest and DownloaderConfig.

Installation

Install from a local checkout:

python3 -m pip install .

For development work:

python3 -m pip install -e ".[dev]"

Quick Start

Print messages to stdout:

chat_downloader "https://www.youtube.com/watch?v=jfKfPfyJRdk" --max_messages 20

Capture a Twitch VOD to JSONL:

chat_downloader "https://www.twitch.tv/videos/123456789" \
  --output vod-chat.jsonl \
  --max_messages 500

Write the same run to two formats:

chat_downloader "https://www.youtube.com/watch?v=jfKfPfyJRdk" \
  --output chat.jsonl \
  --output chat.txt

Use cookies and custom headers:

chat_downloader "https://www.youtube.com/watch?v=jfKfPfyJRdk" \
  --cookies cookies.txt \
  --request_profile youtube_android \
  --header "Accept-Language: en-US,en;q=0.9"

Enable automatic YouTube profile fallback on incomplete continuations:

chat_downloader "https://www.youtube.com/watch?v=jfKfPfyJRdk" \
  --request_profile youtube_web \
  --auto_profile_fallback true

Restrict output to a time window:

chat_downloader "https://www.youtube.com/watch?v=jfKfPfyJRdk" \
  --start_time 00:10:00 \
  --end_time 00:12:30

Python API

The simplest entry point is ChatDownloader.get_chat():

from chat_downloader import ChatDownloader

downloader = ChatDownloader()
chat = downloader.get_chat(
    "https://www.youtube.com/watch?v=jfKfPfyJRdk",
    max_messages=10,
)

for message in chat:
    print(message["author"]["name"], ":", message["message"])

You can also use the typed request objects exposed by the package:

from chat_downloader import ChatDownloader, ChatRequest, DownloaderConfig

config = DownloaderConfig(cookies="cookies.txt", read_timeout=45.0)
request = ChatRequest(
    url="https://www.twitch.tv/videos/123456789",
    max_messages=100,
    output=["chat.jsonl", "chat.txt"],
)

downloader = ChatDownloader(**config.as_dict())
chat = downloader.get_chat(**request.to_legacy_kwargs())

for message in chat:
    pass

For the current export list and dataclass details, see docs/python-api-reference.md.

Output Formats

Format Notes
json Final JSON array written on close. Best for finite captures.
jsonl One JSON object per line. Best for long or live captures.
csv Flattens nested fields and rewrites the file when new columns appear.
txt Applies the configured message formatter.

When a live capture targets a .json path, the runtime upgrades it to .jsonl so the output stays crash-safe. Pass --format json to keep JSON-array output for live captures.

Supported Platforms

Platform Current focus
YouTube Live chat, replay chat, URL discovery, optional cookies/auth headers
Twitch Live IRC chat, VOD chat, clip/VOD metadata lookups, richer notice parsing

Support still depends on the platform exposing chat data. Subscriber-only, login-gated, or platform-throttled content may require cookies or may not be accessible.

CLI Notes

Run chat_downloader --help for the complete argument list. Common flags:

  • --message_groups or --message_types to filter events.
  • --format or --format_file to change rendered text output.
  • --output to write one or more files.
  • --timeout and --inactivity_timeout to bound long-running captures.
  • --proxy, --cookies, --user-agent, and --header for request control.
  • --request_profile to apply Grayjay-inspired request header presets.
  • --auto_profile_fallback to rotate YouTube request profiles when continuation payloads are repeatedly incomplete.
  • --logging debug or --verbose for transport/parser debugging.

Documentation Map

Troubleshooting

  • 403, 429, or LoginRequired errors usually mean the platform wants cookies, a slower request pace, or both.
  • Use jsonl for long or live captures; plain json is finalized only when the writer closes cleanly.
  • If a platform changes its private APIs, run again with --logging debug and review the site-specific code under chat_downloader/sites/.
  • Network tests are opt-in. The default local and CI path is the offline test suite.

Development

See docs/developer-workflow-guide.md for the canonical development workflow, commands, and contributor guidance.

Credits

License

MIT

Description
No description provided
Readme MIT 5.8 MiB
Languages
Python 99.8%
Makefile 0.2%