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
81 changes: 47 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Extract videos from X (formerly Twitter) tweets.
- ✅ Automatic format selection (highest quality)
- ✅ Download videos directly or just get the URL
- ✅ Clip videos to a specific time range (`--from` and `--to`)
- ⚠️ Downloading videos from private tweets (experimental alpha features)
- ✅ Download videos from private tweets via CDP mode (connects to your Chrome)
- ❌ Windows support

## Quick Install
Expand Down Expand Up @@ -59,13 +59,13 @@ x-dl https://x.com/user/status/123456
- **Download:**
- mp4/webm/gif files: direct download
- HLS (m3u8) playlists: downloads via ffmpeg to produce mp4
- If direct download fails with 401/403 auth errors and `--profile` is used, automatically retries using authenticated Playwright requests
- In CDP mode, uses your Chrome's authenticated session for private tweets
- **Clipping:**
- `--from` and `--to` (MM:SS format) trim videos to a specific time range
- HLS streams are clipped during download with ffmpeg re-encoding
- MP4 streams download full video, then clip locally
- Clipped files get a `_clip` suffix in the filename
- **Auth:** with `--profile`, Playwright reuses cookies/session from a persistent profile directory
- **Auth:** CDP mode uses a persistent Chrome profile, reusing your logged-in session
- **ffmpeg:** checked at runtime and auto-installed when possible

Examples:
Expand All @@ -76,11 +76,8 @@ x-dl --url-only https://x.com/WesRoth/status/2013693268190437410
```

```bash
# Log in once (interactive browser), saving cookies to a profile dir (alpha)
x-dl --login --profile ~/.x-dl-profile

# Then extract using the logged-in session
x-dl --profile ~/.x-dl-profile --url-only https://x.com/WesRoth/status/2013693268190437410
# Download a private tweet using CDP mode (connects to your Chrome)
x-dl cdp https://x.com/user/status/123456
```

## Installation
Expand Down Expand Up @@ -162,8 +159,6 @@ x-dl install --with-deps
| `--quality <best|worst>` | Video quality preference (default: best) |
| `--timeout <seconds>` | Page load timeout in seconds (default: 30) |
| `--headed` | Show browser window for debugging |
| `--profile [dir]` | Use a persistent browser profile for authenticated extraction (default: `~/.x-dl-profile`) |
| `--login` | Open X in a persistent profile and wait for you to log in |
| `--from <MM:SS>` | Clip start time in minutes and seconds (e.g. `00:30`) |
| `--to <MM:SS>` | Clip end time in minutes and seconds (e.g. `01:30`) |
| `--help, -h` | Show help message |
Expand Down Expand Up @@ -192,15 +187,13 @@ x-dl --url-only https://x.com/user/status/123456
x-dl --headed https://x.com/user/status/123456
```

**Login once, then reuse the session (alpha):**
**Download a private tweet via CDP mode:**
```bash
# Log in interactively (creates/uses the profile dir)
x-dl --login --profile ~/.x-dl-profile

# Extract using the logged-in session
x-dl --profile ~/.x-dl-profile https://x.com/user/status/123456
x-dl cdp https://x.com/user/status/123456
```

See [CDP Mode](#cdp-mode-private-tweets) below for setup instructions.

**Custom timeout:**
```bash
x-dl --timeout 60 https://x.com/user/status/123456
Expand Down Expand Up @@ -282,21 +275,44 @@ When extracting a video, the tool will:
✅ Video saved to: ~/Downloads/Remotion_2013626968386765291_clip.mp4
```

## CDP Mode (Private Tweets)

CDP mode uses Google Chrome with a dedicated profile to download private or login-walled tweets.

### Setup

1. **Google Chrome** must be installed
2. Log in first: `x-dl login`
3. Download private tweets: `x-dl cdp <url>`

### Login

```bash
# Open Chrome to log in to X/Twitter (session is saved for future use)
x-dl login
```

Chrome opens with the X/Twitter login page. Log in normally — x-dl detects the login automatically and closes the browser.

### Examples

```bash
# Download a private tweet
x-dl cdp https://x.com/user/status/123456

# Just get the URL
x-dl cdp --url-only https://x.com/user/status/123456
```

Session data is stored in `~/.x-dl-chrome-profile`. Delete this directory to log out.

## Limitations

- **Public tweets only**: Private or protected tweets cannot be extracted
- **Clipping requires ffmpeg**: `--from` and `--to` require ffmpeg for processing
- **Clipping time format**: Times must be in MM:SS format (e.g., `00:30`, not `0:30` or `30`)

- **Public tweets only**: Private or protected tweets cannot be extracted
- **Time-limited URLs**: Video URLs may expire after some time
- **Rate limiting**: X may rate-limit excessive requests
- **Login walls**: Use `--login` and `--profile` to extract login-walled tweets (alpha)

**How to tell if a tweet can be extracted:**
1. Try opening the tweet in an incognito/private browser window
2. If you see a "Sign up" or "Log in" prompt, this tool cannot extract it
3. If the content loads without login, extraction should work
- **CDP mode requires Chrome**: CDP mode needs Google Chrome installed (not Chromium)


## Testing
Expand Down Expand Up @@ -341,6 +357,7 @@ Use `--headed` mode to see the browser for debugging.
│ ├── index.ts # CLI entry point
│ ├── extractor.ts # Video extraction logic
│ ├── downloader.ts # Download logic (Bun fetch)
│ ├── private.ts # Private tweet browser session (persistent Chrome profile)
│ ├── ffmpeg.ts # HLS download via ffmpeg
│ ├── installer.ts # Dependency management (Playwright + ffmpeg)
│ ├── types.ts # TypeScript interfaces
Expand Down Expand Up @@ -390,19 +407,15 @@ bun run src/index.ts <url>

The tool will verify ffmpeg capabilities automatically.

### Authenticated extraction doesn't work

- Run `x-dl --login --profile ~/.x-dl-profile` and make sure you can view the tweet in that browser
- Then rerun extraction with `--profile ~/.x-dl-profile`
### CDP mode doesn't work

Security note: your profile directory contains authentication cookies.
- Make sure Google Chrome is installed (not just Chromium)
- Try deleting `~/.x-dl-chrome-profile` and logging in again
- Use `--headed` if you need to debug: the browser window will stay visible

### "This tweet is private or protected"

Only public tweets can be extracted. Verify that:
- The account is not private/protected
- You're not trying to access sensitive content
- The tweet is publicly accessible
Use CDP mode to download private tweets: `x-dl cdp <url>`. This uses your Chrome's logged-in session.

### "No video found in this tweet"

Expand Down
Loading
Loading