Metadata-Version: 2.4
Name: yt-dlp-threads
Version: 0.1.0
Summary: yt-dlp extractor plugin for Threads (threads.com / threads.net)
Author: tribixbite
License: Unlicense
Project-URL: Homepage, https://github.com/tribixbite/yt-dlp-threads
Project-URL: Issues, https://github.com/tribixbite/yt-dlp-threads/issues
Keywords: yt-dlp,yt-dlp-plugin,threads,instagram,downloader,video
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Environment :: Plugins
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: Public Domain
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: yt-dlp
Dynamic: license-file

# yt-dlp-threads

A [yt-dlp](https://github.com/yt-dlp/yt-dlp) extractor plugin for **Threads**
(`threads.com` / `threads.net`).

yt-dlp has no built-in Threads extractor — support has been requested for years
without a merged implementation ([#7523](https://github.com/yt-dlp/yt-dlp/issues/7523),
[#10133](https://github.com/yt-dlp/yt-dlp/issues/10133),
[#12021](https://github.com/yt-dlp/yt-dlp/issues/12021)) — and Threads serves
anonymous clients a JavaScript login wall with no media in the HTML.

## How it works

Meta server-renders the full post — including the CDN media URLs — for
link-preview crawlers. This plugin fetches the post page with a **Googlebot
User-Agent** to bypass the login wall, then extracts the progressive (muxed)
mp4 URL(s) from the embedded JSON. Handles canonical `@user/post/<id>` links,
`/share/<code>/` short links, and multi-video (carousel) posts.

> **Caveat:** this bypass is inherently fragile. If Meta stops serving crawlers
> the full payload or changes the embedded JSON keys, extraction will break.
> There is no cookie/auth support — only publicly viewable posts work.

## Install

Requires yt-dlp with plugin support (2023.01.02+).

**As a pip package** (installs into the same environment as yt-dlp):

```bash
pip install git+https://github.com/tribixbite/yt-dlp-threads
```

<!-- Swap the line above for `pip install yt-dlp-threads` once the PyPI
     release is published. -->



**As a manual plugin** (no install): drop the `yt_dlp_plugins` folder into a
yt-dlp plugin directory, e.g.

```bash
mkdir -p ~/.config/yt-dlp/plugins/yt-dlp-threads
cp -r yt_dlp_plugins ~/.config/yt-dlp/plugins/yt-dlp-threads/
```

## Usage

```bash
yt-dlp "https://www.threads.com/@someone/post/ABC123"
yt-dlp -F "https://www.threads.com/share/xxxxxxxx/"   # list formats (hd/sd)
```

Verify it loaded: `yt-dlp --verbose <url>` prints `[debug] Extractor Plugins: ThreadsIE`.

## Notes

- A Threads page embeds **many** posts (thread items, replies, recommendations).
  The extractor selects the one whose shortcode matches your URL; if that post
  isn't in the page data (deleted, private, login-gated) it raises an error
  rather than returning some other post's video.
- `duration` is decoded from the CDN URL's `efg` parameter — Threads posts have
  no `video_duration` field.
- Image-only and text-only posts are not supported (video only).

## Development

```bash
python -m unittest discover -s tests -v   # offline tests, no network
ruff check .
```

## License

Unlicense (public domain).
