Spaces:
Sleeping
Sleeping
Download main.py from Keychain112/streamy-backend: direct link, hf CLI and curl.
- Browser
- Download file 2.7 kB
-
https://huggingface.co/spaces/Keychain112/streamy-backend/resolve/main/main.py
- Command line
-
hf download hf://spaces/Keychain112/streamy-backend/main.py
-
curl -L -o main.py https://huggingface.co/spaces/Keychain112/streamy-backend/resolve/main/main.py
2.7 kB
| 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=["*"], | |
| ) | |
| async def root(): | |
| return {"status": "Online", "mode": "HuggingFace"} | |
| 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"} | |
| 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) |