feat(player): add explicit detection, inline audio preview, seeking scrubber, and stream endpoint

This commit is contained in:
Antigravity committed 2026-10-12 14:03:57 +03:00
1 parent 49bd123a03
commit 30ba67c707
5 files changed
+382 -20

No files matched your search

+46 -5
View File
@@ -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}")