Hanime plugin

NSFW

I dont know much about making plugin for yt-dlp, can anyone make this into a yt-dlp plugin please 🥺 🥺 🥺

import subprocess
import sys
import time
import re
from requests import get
from bs4 import BeautifulSoup
from selenium import webdriver # NOTE: selenium==4.9.0, also need brotli to decompress the data 
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options

DEBUG = False

def get_signature_and_stime(url):
    options = Options()
    options.add_argument("--headless")
    options.set_preference("general.useragent.override", 
                          "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
    
    try:
        with webdriver.Firefox(service=Service(), options=options) as driver:
            driver.set_page_load_timeout(30)
            driver.get(url)
            time.sleep(3)
            
            signature = driver.execute_script("return window.ssignature || null;")
            stime = driver.execute_script("return window.stime || null;")
            
            if DEBUG:
                print(f"Signature: {signature}\nStime: {stime}")
            return signature, stime
    except Exception as e:
        print(f"Error: {e}")
        return None, None

def get_json_download(referer_url, url_id, signature, stime):
    api_url = f"https://cached.freeanimehentai.net/rapi/v7/downloads?id={url_id}&kind=requestlinks"
    
    headers = {
        "Accept": "application/json, text/plain, */*",
        "Referer": referer_url,
        "Origin": "https://hanime.tv",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        "x-signature": signature or "",
        "x-time": str(stime) or "",
        "x-signature-version": "web2"
    }
    
    try:
        response = get(api_url, headers=headers, timeout=30)
        return response.json() if response.status_code == 200 else None
    except Exception as e:
        print(f"API Error: {e}")
        return None

def download_video(json_data):
    videos = []
    for server in json_data.get("videos_manifest", {}).get("servers", []):
        videos.extend([{
            "id": s["id"],
            "url": s["extra2"],
            "filename": s["filename"],
            "extension": s["extension"],
            "height": s["height"]
        } for s in server.get("streams", []) if "extra2" in s and s["extra2"]])
    
    if not videos:
        print("No videos found!")
        return
    
    for i, v in enumerate(videos, 1):
        print(f"{i:2d}. {v['height']}p - {v['extension']}")
    
    try:
        selections = [int(idx) for idx in input("Select videos (comma-separated): ").split(",") if idx.strip()]
        selected = [videos[i-1] for i in selections if 1 <= i <= len(videos)]
        
        for v in selected:
            print(f"\nDownloading {v['height']}p video...")
            subprocess.run(["yt-dlp", "-o", v["filename"], v["url"]], check=True)
            print("✓ Done!")
            
    except (ValueError, KeyboardInterrupt):
        print("\nDownload cancelled.")

def main():
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <URL>")
        sys.exit(1)
    
    BASE_URL = "https://hanime.tv"
    
    try:
        soup = BeautifulSoup(get(sys.argv[1]).text, 'html.parser')
        href = next((a['href'] for a in soup.find_all("a", href=re.compile(r'/downloads/')) if a.get('href')), None)
        
        if not href:
            print("No download link found!")
            return
        
        download_url = BASE_URL + href
        url_id = re.search(r'/downloads/(.+)', href).group(1)
        
        signature, stime = get_signature_and_stime(download_url)
        if not (signature and stime):
            print("Failed to get signature/stime")
            return
        
        data = get_json_download(download_url, url_id, signature, stime)
        if data:
            download_video(data)
        else:
            print("Failed to get video data")
            
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()

Posted Dec 3, 2025, 1:34 AM UTC

05
Loading comments…