A high-performance YouTube POT (Proof-of-Origin Token) provider implemented in Rust
5.3K
A high-performance YouTube POT (Proof-of-Origin Token) provider implemented in Rust, designed to help yt-dlp bypass the "Sign in to confirm you're not a bot" restrictions with improved performance and reliability.
Caution
Providing a POT token does not guarantee bypassing 403 errors or bot checks, but it _may_ help your traffic seem more legitimate.
This Rust implementation uses LuanRT's BotGuard interfacing libraryā through the rustypipe-botguard crateā to generate authentic POT tokens, helping bypass YouTube's bot detection when using yt-dlp from flagged IP addresses. See the PO Token Guideā for technical details.
This Rust rewrite offers significant improvements over the original TypeScript version:
The system consists of two main components working together:
yt-dlp
ā (via POT plugin)
Python Plugin
ā HTTP API calls or CLI calls
Rust POT Provider
ā BotGuard integration
YouTube BotGuard API
ā returns POT Token
yt-dlp (bypasses bot check)
Rust POT Provider (this project): Two operation modes:
bgutil-pot server): Always-running REST API service (recommended)bgutil-pot): Per-request command-line executionPython Plugin: Integrates with yt-dlp's POT framework to automatically fetch tokens from the provider.
2025.05.22 or aboveDownload the latest release from GitHub Releasesā :
# Download the binary for your platform
# Example for Linux x86_64:
wget https://github.com/jim60105/bgutil-ytdlp-pot-provider-rs/releases/latest/download/bgutil-pot-linux-x86_64
# Make executable and move to PATH
chmod +x bgutil-pot-linux-x86_64
sudo mv bgutil-pot-linux-x86_64 /usr/local/bin/bgutil-pot
Requirements: Rust 1.85+ (edition 2024) and Cargo
git clone https://github.com/jim60105/bgutil-ytdlp-pot-provider-rs.git
cd bgutil-ytdlp-pot-provider-rs
# Option 1: Build only (binaries in target/release/)
cargo build --release
# Option 2: Build and install to ~/.cargo/bin (recommended)
cargo install --path .
Note
The Containerfile is designed for SELinux-enabled systems. On non-SELinux systems, remove the `,z` flags from `--mount` options.
# Build the container image
podman build -f Containerfile -t bgutil-pot .
# Run the container (basic usage)
podman run -p 4416:4416 bgutil-pot
# Run with custom configuration
podman run -p 8080:4416 -e RUST_LOG=debug bgutil-pot server --host 0.0.0.0 --port 4416
# Using Docker instead of Podman
docker build -f Containerfile -t bgutil-pot .
docker run -p 4416:4416 bgutil-pot
bgutil-ytdlp-pot-provider-rs.zip)~/yt-dlp-plugins
āāā bgutil-ytdlp-pot-provider
āāā pyproject.toml
āāā yt_dlp_plugins
āāā extractor
āāā getpot_bgutil_cli.py
āāā getpot_bgutil_http.py
āāā getpot_bgutil.py
Important
This plugin is different from the upstream TypeScript implementation. If you have an existing `bgutil-ytdlp-pot-provider` folder from the original project, please remove it first to avoid conflicts before installing this Rust version.
The HTTP server mode provides the best performance and user experience.
# Using default settings (binds to [::]:4416, IPv6 with IPv4 fallback)
./bgutil-pot server
# Custom port
./bgutil-pot server --port 8080
# Custom host address
./bgutil-pot server --host 127.0.0.1 --port 4416
# With verbose logging
./bgutil-pot server --verbose
Server Command Line Options:
--host <HOST>: Host address to bind to (default: ::)--port <PORT>: Listen port (default: 4416)--verbose: Enable verbose loggingThe HTTP server provides the following REST API endpoints:
POST /get_pot: Generate a new POT tokenGET /ping: Health check endpointPOST /invalidate_caches: Clear all internal cachesPOST /invalidate_it: Invalidate integrity tokensGET /minter_cache: Get minter cache statusOnce the server is running, yt-dlp will automatically detect and use it:
# Standard usage - works automatically with default settings
yt-dlp "https://www.youtube.com/watch?v=VIDEO_ID"
# If using a custom port, specify the base URL
yt-dlp --extractor-args "youtubepot-bgutilhttp:base_url=http://127.0.0.1:8080" "VIDEO_URL"
# If tokens stop working, try legacy mode
yt-dlp --extractor-args "youtubepot-bgutilhttp:base_url=http://127.0.0.1:4416;disable_innertube=1" "VIDEO_URL"
For occasional use or environments where running a persistent service is not desired:
# Generate token for a specific video
./bgutil-pot --content-binding "VIDEO_ID"
# With proxy support
./bgutil-pot --content-binding "VIDEO_ID" --proxy "http://proxy.example.com:8080"
# Bypass cache to force new token generation
./bgutil-pot --content-binding "VIDEO_ID" --bypass-cache
# With verbose logging
./bgutil-pot --content-binding "VIDEO_ID" --verbose
Generate Command Line Options:
--content-binding <CONTENT_BINDING>: Content binding (video ID, visitor data, etc.)--proxy <PROXY>: Proxy server URL (format: http://host:port, socks5://host:port, etc.)--bypass-cache: Bypass cache and force new token generation--source-address <SOURCE_ADDRESS>: Source IP address for outbound connections--disable-tls-verification: Disable TLS certificate verification--verbose: Enable verbose logging--version: Show version information# Specify the script path for yt-dlp integration
yt-dlp --extractor-args "youtubepot-bgutilscript:script_path=/path/to/bgutil-pot" "VIDEO_URL"
Both modes support comprehensive configuration via:
Environment Variables:
| Variable | Description | Default |
|---|---|---|
RUST_LOG | Logging level (error, warn, info, debug, trace) | info |
POT_SERVER_HOST | Server bind address | :: |
POT_SERVER_PORT | Server listen port | 4416 |
TOKEN_TTL | Token TTL in hours | 6 |
HTTPS_PROXY | HTTPS proxy URL | None |
HTTP_PROXY | HTTP proxy URL | None |
ALL_PROXY | All protocols proxy URL | None |
DISABLE_INNERTUBE | Disable Innertube API usage | false |
CACHE_DIR | Cache directory path | Platform default |
Configuration File Example (config.toml):
[server]
host = "::"
port = 4416
timeout = 30
enable_cors = true
[token]
ttl_hours = 6
enable_cache = true
max_cache_entries = 1000
[botguard]
request_key = "O43z0dpjhgX20SCx4KAo"
enable_vm = true
vm_timeout = 30
disable_innertube = false
[network]
connect_timeout = 30
request_timeout = 60
max_retries = 3
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
[logging]
level = "info"
verbose = false
format = "text"
[cache]
enable_file_cache = true
memory_cache_size = 100
enable_compression = false
Example usage with environment variables:
# Set logging level
export RUST_LOG=debug
./bgutil-pot server
# Multiple settings
RUST_LOG=debug ./bgutil-pot --content-binding "VIDEO_ID"
Both modes support proxy configuration:
# HTTP/HTTPS proxy
--proxy "http://proxy.example.com:8080"
# SOCKS5 proxy
--proxy "socks5://proxy.example.com:1080"
# Proxy with authentication
--proxy "http://user:[email protected]:8080"
To verify the plugin installation, check yt-dlp's verbose output:
yt-dlp -v "https://www.youtube.com/watch?v=VIDEO_ID"
You should see output similar to:
[debug] [youtube] [pot] PO Token Providers: bgutil:http-1.2.2 (external), bgutil:script-1.2.2 (external)
If tokens stop working, try the following in order:
--bypass-cachedisable_innertube=1 to extractor arguments# Check if the server is running (HTTP mode)
curl http://127.0.0.1:4416/ping
# Test with verbose logging
./bgutil-pot server --verbose
# Test script mode
./bgutil-pot --content-binding "test" --verbose
Verify the plugin installation:
yt-dlp -v "https://www.youtube.com/watch?v=dQw4w9WgXcQ" 2>&1 | grep -i "pot"
Should show: [debug] [youtube] [pot] PO Token Providers: bgutil:http-...
| Variable | Description | Default |
|---|---|---|
RUST_LOG | Logging level | info |
This project welcomes contributions! Please see CONTRIBUTING.mdā for guidelines.
git clone https://github.com/jim60105/bgutil-ytdlp-pot-provider-rs.git
cd bgutil-ytdlp-pot-provider-rs
# Install development dependencies
cargo build
# Run tests
cargo nextest run
# Run quality checks
./scripts/quality_check.sh
This project is licensed under the GPL-3.0-or-later License. See LICENSEā for details.
Content type
Image
Digest
sha256:289d82576ā¦
Size
14.8 MB
Last updated
7 months ago
docker pull jim60105/bgutil-pot