feat(player): add explicit detection, inline audio preview, seeking scrubber, and stream endpoint
This commit is contained in:
1 parent
49bd123a03
commit
30ba67c707
5 files changed
+382
-20
No files matched your search
+46
-5
@@ -29,13 +29,26 @@ def _search_yandex_sync(query: str) -> Dict[str, List[Dict[str, Any]]]:
|
||||
res = client.search(query, type_="all")
|
||||
|
||||
if res.tracks and res.tracks.results:
|
||||
for t in res.tracks.results[:6]:
|
||||
for t in res.tracks.results[:8]:
|
||||
if not t:
|
||||
continue
|
||||
artists = ", ".join(a.name for a in t.artists) if t.artists else "Unknown"
|
||||
album_title = t.albums[0].title if t.albums else "Single"
|
||||
year = t.albums[0].year if t.albums and t.albums[0].year else None
|
||||
cover = "https://" + t.cover_uri.replace("%%", "400x400") if t.cover_uri else None
|
||||
|
||||
content_warning = getattr(t, "content_warning", None)
|
||||
version = getattr(t, "version", None)
|
||||
title_lower = (t.title or "").lower()
|
||||
version_lower = (version or "").lower()
|
||||
|
||||
if content_warning == "explicit" or any(w in title_lower or w in version_lower for w in ["explicit", "18+", "uncensored"]):
|
||||
explicit_status = "explicit"
|
||||
elif content_warning == "clean" or any(w in title_lower or w in version_lower for w in ["clean", "censored", "радио", "radio edit"]):
|
||||
explicit_status = "clean"
|
||||
else:
|
||||
explicit_status = "neutral"
|
||||
|
||||
tracks.append({
|
||||
"service": "yandex",
|
||||
"service_name": "Яндекс Музыка",
|
||||
@@ -46,7 +59,10 @@ def _search_yandex_sync(query: str) -> Dict[str, List[Dict[str, Any]]]:
|
||||
"year": year,
|
||||
"duration": format_duration(t.duration_ms),
|
||||
"cover": cover,
|
||||
"url": f"https://music.yandex.ru/track/{t.id}"
|
||||
"url": f"https://music.yandex.ru/track/{t.id}",
|
||||
"explicit_status": explicit_status,
|
||||
"version": version,
|
||||
"preview_url": None
|
||||
})
|
||||
|
||||
if res.albums and res.albums.results:
|
||||
@@ -86,6 +102,15 @@ async def search_apple(query: str) -> Dict[str, List[Dict[str, Any]]]:
|
||||
duration_ms = r.get("trackTimeMillis", 0)
|
||||
release_date = r.get("releaseDate", "")
|
||||
year = int(release_date[:4]) if release_date else None
|
||||
|
||||
track_explicitness = (r.get("trackExplicitness") or "").lower()
|
||||
if track_explicitness == "explicit":
|
||||
explicit_status = "explicit"
|
||||
elif track_explicitness == "cleaned":
|
||||
explicit_status = "clean"
|
||||
else:
|
||||
explicit_status = "neutral"
|
||||
|
||||
tracks.append({
|
||||
"service": "apple",
|
||||
"service_name": "Apple Music",
|
||||
@@ -96,7 +121,10 @@ async def search_apple(query: str) -> Dict[str, List[Dict[str, Any]]]:
|
||||
"year": year,
|
||||
"duration": format_duration(duration_ms),
|
||||
"cover": cover,
|
||||
"url": r.get("trackViewUrl")
|
||||
"url": r.get("trackViewUrl"),
|
||||
"explicit_status": explicit_status,
|
||||
"version": None,
|
||||
"preview_url": r.get("previewUrl")
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"Apple search error: {e}")
|
||||
@@ -122,17 +150,30 @@ def _search_youtube_sync(query: str) -> Dict[str, List[Dict[str, Any]]]:
|
||||
if not entry:
|
||||
continue
|
||||
sec = entry.get("duration", 0)
|
||||
title_raw = entry.get("title") or ""
|
||||
title_lower = title_raw.lower()
|
||||
|
||||
if any(w in title_lower for w in ["explicit", "uncensored", "18+"]):
|
||||
explicit_status = "explicit"
|
||||
elif any(w in title_lower for w in ["clean", "censored", "radio edit", "радиоверсия"]):
|
||||
explicit_status = "clean"
|
||||
else:
|
||||
explicit_status = "neutral"
|
||||
|
||||
tracks.append({
|
||||
"service": "youtube",
|
||||
"service_name": "YouTube",
|
||||
"id": entry.get("id"),
|
||||
"title": entry.get("title"),
|
||||
"title": title_raw,
|
||||
"artist": entry.get("uploader") or entry.get("channel") or "Unknown",
|
||||
"album": "YouTube Audio",
|
||||
"year": None,
|
||||
"duration": f"{sec // 60:02d}:{sec % 60:02d}" if sec else "00:00",
|
||||
"cover": entry.get("thumbnail"),
|
||||
"url": f"https://www.youtube.com/watch?v={entry.get('id')}"
|
||||
"url": f"https://www.youtube.com/watch?v={entry.get('id')}",
|
||||
"explicit_status": explicit_status,
|
||||
"version": None,
|
||||
"preview_url": None
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"YouTube search error: {e}")
|
||||
|
||||
Reference in new issue
Block a user