import os import certifi os.environ['SSL_CERT_FILE'] = certifi.where() import yt_dlp import tempfile from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from ytmusicapi import YTMusic # Initialize with a common browser header to avoid 500 errors in datacenters try: ytm = YTMusic() except Exception as e: print(f"Init Error: {e}") ytm = None app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=False, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def root(): return {"status": "Online", "mode": "HuggingFace"} @app.get("/search") async def search(q: str): if not ytm: return {"error": "YTMusic not initialized"} try: # We add a try-except here to catch the specific 500 error raw_results = ytm.search(q, filter="songs") results = [] for res in raw_results: artists = ", ".join([a['name'] for a in res.get('artists', [])]) thumb = res['thumbnails'][-1]['url'] if res.get('thumbnails') else "" results.append({ "id": res['videoId'], "title": res['title'], "artist": artists or "Unknown Artist", "thumbnail": thumb }) return results except Exception as e: # This will show the real error in your Hugging Face Logs tab print(f"Search Crash: {e}") return {"error": str(e), "tip": "Check Hugging Face logs"} @app.get("/get_audio") async def get_audio(id: str): video_url = f"https://www.youtube.com/watch?v={id}" # These extra arguments trick YouTube into seeing a phone browser, not a server ydl_opts = { 'format': 'bestaudio/best', 'nocheckcertificate': True, # This stops the protocol error you're seeing 'quiet': True, 'no_warnings': True, 'extractor_args': { 'youtube': { 'player_client': ['android'], # Android is often more stable than iOS for this 'skip': ['dash', 'hls'] } } } with yt_dlp.YoutubeDL(ydl_opts) as ydl: try: # Adding a retry loop for stability in the cloud info = ydl.extract_info(video_url, download=False) return {"url": info['url']} except Exception as e: print(f"Extraction failed: {e}") # If it still fails, we send the error back to see it on the phone return {"error": str(e), "status": "YouTube blocked this request"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)