Spaces:
Runtime error
Runtime error
File size: 3,862 Bytes
4d60d14 f483bb7 4d60d14 f483bb7 4d60d14 f483bb7 4d60d14 f483bb7 4d60d14 f483bb7 4d60d14 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | from fastapi import FastAPI, Query
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from ytmusicapi import YTMusic
import yt_dlp
app = FastAPI(
title="Farel Music API + Audio Link",
description="Backend API Farel Music menggunakan Docker di HF Spaces",
version="2.0.0"
)
# Aktifkan CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# --- PERBAIKAN DI SINI: Menyisipkan User-Agent agar tidak diblokir SSL/EOF oleh YouTube ---
# Kita buat object YTMusic kosong, lalu isi headers-nya secara manual sebelum dipakai.
try:
yt = YTMusic()
# Ganti headers bawaan dengan user-agent browser modern
yt.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.9",
"Content-Type": "application/json",
"X-Goog-AuthUser": "0",
"Origin": "https://music.youtube.com"
}
except Exception as e:
yt = None
print(f"Gagal menginisialisasi YTMusic: {e}")
def get_direct_audio_url(video_id: str):
ydl_opts = {
'format': 'bestaudio/best',
'quiet': True,
'no_warnings': True,
'nocheckcertificate': True,
'preferredcodec': 'm4a',
# Tambahkan juga HTTP Headers untuk yt-dlp agar tidak diblokir saat ambil audio
'http_headers': {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.9',
}
}
youtube_url = f"https://www.youtube.com/watch?v={video_id}"
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(youtube_url, download=False)
return info.get('url')
except Exception as e:
print(f"Gagal ekstraksi audio: {e}")
return None
@app.get("/")
def home():
return {
"status": "Online via Docker",
"message": "Farel Music API Ready!",
"endpoint": "/search?q=judul_lagu"
}
@app.get("/search")
def search_music(q: str = Query(..., description="Kata kunci pencarian lagu")):
if not q.strip():
return JSONResponse(status_code=400, content={"error": "Query tidak boleh kosong."})
if yt is None:
return JSONResponse(status_code=500, content={"error": "YTMusic API bermasalah saat inisialisasi."})
try:
# Melakukan pencarian
results = yt.search(q, filter="songs")
formatted_results = []
for item in results[:5]:
video_id = item.get('videoId')
if not video_id:
continue
audio_url = get_direct_audio_url(video_id)
thumbnails = item.get('thumbnails', [])
thumbnail_url = thumbnails[-1]['url'] if thumbnails else None
artists = [a['name'] for a in item.get('artists', [])]
formatted_results.append({
"id": video_id,
"title": item.get('title'),
"artists": artists,
"album": item.get('album', {}).get('name', 'Single'),
"duration": item.get('duration'),
"thumbnail": thumbnail_url,
"youtube_url": f"https://www.youtube.com/watch?v={video_id}",
"audio_url": audio_url
})
return {
"query": q,
"total_results": len(formatted_results),
"results": formatted_results
}
except Exception as e:
return JSONResponse(status_code=500, content={"error": f"Terjadi kesalahan: {str(e)}"}) |