• Implemented global offline mode for all HuggingFace-dependent modules to eliminate unauthenticated request warnings and prevent external connection attempts during startup and runtime. Changes • Global Offline Configuration: Added HF_HUB_OFFLINE=1 and TRANSFORMERS_OFFLINE=1 to the environment variables at the top of edit_api.py, embeddings.py, watcher.py, and pose_llm/pose_llm_api.py. • Explicit Local Files Only: Updated all huggingface_hub.hf_hub_download calls in edit_api.py to include local_files_only=True, ensuring they never attempt to reach the Hub if models are already cached. • LLM Service Optimization: Updated AutoTokenizer and AutoModelForCausalLM calls in pose_llm/pose_llm_api.py to use local_files_only=True. • Consistency: Ensured that shared modules like embeddings.py which uses open_clip are also locked to offline mode to prevent background downloads.
118 lines
4.5 KiB
Python
Executable File
118 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Pornhub Video Downloader Side-Script
|
|
Uses yt-dlp under the hood for highly robust and fast downloads.
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import subprocess
|
|
|
|
# Ensure yt-dlp and curl-cffi are installed
|
|
try:
|
|
import yt_dlp
|
|
import curl_cffi
|
|
except ImportError:
|
|
print("[-] yt-dlp or curl-cffi is not fully installed in this Python environment.")
|
|
print("[*] Attempting to install yt-dlp with curl-cffi automatically...")
|
|
try:
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "yt-dlp[default,curl-cffi]"])
|
|
import yt_dlp
|
|
import curl_cffi
|
|
print("[+] Successfully installed yt-dlp and curl-cffi!")
|
|
except Exception as e:
|
|
print(f"[!] Failed to install dependencies automatically: {e}")
|
|
print("[!] Please install manually with: pip install \"yt-dlp[default,curl-cffi]\"")
|
|
sys.exit(1)
|
|
|
|
import argparse
|
|
|
|
def download_video(url, output_dir=".", quality="best"):
|
|
print(f"[*] Initializing download for: {url}")
|
|
print(f"[*] Output directory: {os.path.abspath(output_dir)}")
|
|
|
|
if not os.path.exists(output_dir):
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
# Format selector configuration
|
|
# 'best' is the safest format because it downloads pre-merged streams and doesn't strictly require ffmpeg.
|
|
# 'bestvideo+bestaudio/best' will download separate video/audio streams and merge them if ffmpeg is present.
|
|
format_selector = 'best'
|
|
if quality != 'best':
|
|
if quality.endswith('p'):
|
|
height = quality[:-1]
|
|
format_selector = f'bestvideo[height<={height}]+bestaudio/best[height<={height}]'
|
|
else:
|
|
format_selector = quality
|
|
|
|
ydl_opts = {
|
|
'format': format_selector,
|
|
'outtmpl': os.path.join(output_dir, '%(title)s [%(id)s].%(ext)s'),
|
|
'noplaylist': True,
|
|
# Pornhub has age gates; standard user-agent and headers are handled by yt-dlp automatically,
|
|
# but let's add some basic robust options.
|
|
'ignoreerrors': False,
|
|
'logtostderr': False,
|
|
'quiet': False,
|
|
'no_warnings': False,
|
|
'nocheckcertificate': True,
|
|
}
|
|
|
|
# Setup browser impersonation to bypass Cloudflare/TLS fingerprinting blocks (e.g. HTTP 403 Forbidden)
|
|
try:
|
|
from yt_dlp.networking.impersonate import ImpersonateTarget
|
|
ydl_opts['impersonate'] = ImpersonateTarget.from_str('chrome')
|
|
except (ImportError, AttributeError):
|
|
ydl_opts['impersonate'] = 'chrome'
|
|
|
|
try:
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
info = ydl.extract_info(url, download=True)
|
|
filename = ydl.prepare_filename(info)
|
|
print("\n[+] Download completed successfully!")
|
|
print(f"[+] File saved to: {filename}")
|
|
return True
|
|
except Exception as e:
|
|
print(f"\n[!] Error downloading video: {e}")
|
|
# Try a safe fallback to 'best' format if we tried a complex format query
|
|
if format_selector != 'best':
|
|
print("[*] Retrying with fallback quality ('best')...")
|
|
ydl_opts['format'] = 'best'
|
|
try:
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
info = ydl.extract_info(url, download=True)
|
|
filename = ydl.prepare_filename(info)
|
|
print("\n[+] Download completed successfully via fallback!")
|
|
print(f"[+] File saved to: {filename}")
|
|
return True
|
|
except Exception as fe:
|
|
print(f"[!] Fallback download also failed: {fe}")
|
|
return False
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Pornhub / General Video Downloader")
|
|
parser.add_argument("url", nargs="?", help="URL of the video to download")
|
|
parser.add_argument("-o", "--output", default="/mnt/zim/tour-comfy/wireframe/", help="Output directory path (default: current directory)")
|
|
parser.add_argument("-q", "--quality", default="720p", help="Video quality (e.g. best, 1080p, 720p, 480p) (default: 720p)")
|
|
|
|
args = parser.parse_args()
|
|
|
|
url = args.url
|
|
if not url:
|
|
# Interactive mode
|
|
try:
|
|
url = input("Enter video URL (e.g., Pornhub link): ").strip()
|
|
except (KeyboardInterrupt, EOFError):
|
|
print("\n[-] Cancelled.")
|
|
sys.exit(0)
|
|
|
|
if not url:
|
|
print("[!] No URL provided. Exiting.")
|
|
sys.exit(1)
|
|
|
|
success = download_video(url, args.output, args.quality)
|
|
sys.exit(0 if success else 1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|