import os import re import requests import json import time import gradio as gr from huggingface_hub import InferenceClient # ===== CONFIG ===== HF_TOKEN = os.environ.get("HF_TOKEN") DOWNLOAD_FOLDER = "/tmp/" # ===== TIKTOK DOWNLOADER ===== def download_tiktok(url): session = requests.Session() session.headers.update({'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}) api_url = 'https://www.tikwm.com/api/' params = {'url': url, 'hd': 1} response = session.get(api_url, params=params, timeout=30) data = response.json() if data.get('code') != 0: return None, None, None, data.get('msg', 'API error') video_data = data.get('data', {}) video_url = video_data.get('play', '') or video_data.get('wmplay', '') if not video_url: return None, None, None, 'No video URL found' author = video_data.get('author', {}).get('unique_id', 'unknown') video_id = video_data.get('id', 'unknown') desc = video_data.get('title', 'TikTok Video') filename = f"{author}_{video_id}.mp4" filepath = os.path.join(DOWNLOAD_FOLDER, filename) video_response = session.get(video_url, stream=True, timeout=60) with open(filepath, 'wb') as f: for chunk in video_response.iter_content(chunk_size=8192): if chunk: f.write(chunk) return filepath, desc, author, video_id # ===== AI TITLE GENERATOR ===== def generate_title(desc, author): try: if not HF_TOKEN: return f"🔥 {desc[:40]} 🔥" client = InferenceClient(token=HF_TOKEN) prompt = f"""Generate a viral YouTube title for this TikTok video: Original: {desc[:50]} Author: @{author} Rules: - Use emojis (🔥, 😱, 🤯, 💀, 🚀) - Add power words: "SHOCKING", "BEST", "INSANE", "MUST WATCH" - Max 60 characters - Clickbait style Title:""" response = client.text_generation( prompt, model="microsoft/DialoGPT-medium", max_new_tokens=30, temperature=0.9 ) title = response.strip()[:60] return title if title else f"🔥 {desc[:40]} 🔥" except Exception as e: print(f"AI Error: {e}") return f"🔥 {desc[:40]} 🔥" # ===== GRADIO FUNCTION ===== def process_tiktok(url, include_ai): try: # Download result = download_tiktok(url) if not result or not result[0]: return f"❌ Download failed: {result[3] if result else 'Unknown error'}", None filepath, desc, author, video_id = result # Generate title if include_ai: title = generate_title(desc, author) else: title = f"TikTok by @{author}" # Status message status = f"""✅ Download Complete! 📹 Video ID: {video_id} 👤 Author: @{author} 📝 Original: {desc[:100]}... 🎯 Generated Title: {title} """ return status, filepath except Exception as e: return f"❌ Error: {str(e)}", None # ===== GRADIO INTERFACE ===== with gr.Blocks(title="TikTok → YouTube Uploader", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🎬 TikTok → YouTube Auto-Uploader ### Paste TikTok link → Auto download → AI title → Preview """) with gr.Row(): with gr.Column(scale=3): url_input = gr.Textbox( label="🔗 TikTok URL", placeholder="https://www.tiktok.com/@user/video/123456789", lines=2 ) with gr.Row(): ai_check = gr.Checkbox(label="🤖 Generate AI Title", value=True) process_btn = gr.Button("🚀 Download & Process", variant="primary") with gr.Column(scale=1): gr.Markdown("### 📋 Supported Formats") gr.Markdown(""" - `vt.tiktok.com/...` - `vm.tiktok.com/...` - `www.tiktok.com/@.../video/...` """) with gr.Row(): output_text = gr.Textbox(label="📤 Status", interactive=False, lines=8) with gr.Row(): video_preview = gr.Video(label="🎥 Preview", height=400) process_btn.click( fn=process_tiktok, inputs=[url_input, ai_check], outputs=[output_text, video_preview] ) gr.Markdown(""" --- ⚠️ **Note:** This app downloads TikTok videos using tikwm.com API. YouTube upload requires OAuth setup with `client_secret.json` file. """) demo.launch()