<?php
// resolve.php - Multi-Instance Audio Stream Resolver with Fallbacks
header('Content-Type: application/json');
$artist = $_GET['artist'] ?? '';
$title = $_GET['title'] ?? '';
if (empty($artist) && empty($title)) {
echo json_encode(['error' => 'Missing artist or title parameters']);
exit;
}
$query = urlencode(trim("{$artist} - {$title} audio"));
// Primary Invidious Instance Mirrors
$invidiousInstances = [
"https://inv.privacydev.net",
"https://yewtu.be",
"https://invidious.nerdvpn.de",
"https://invidious.drgns.space"
];
function httpGet(string $url): ?string {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 4,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
CURLOPT_SSL_VERIFYPEER => false
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ($code === 200 && $res) ? $res : null;
}
// Strategy 1: Loop through Invidious Instances
foreach ($invidiousInstances as $instance) {
$searchUrl = "{$instance}/api/v1/search?q={$query}&type=video";
$searchRes = httpGet($searchUrl);
if (!$searchRes) continue;
$searchResults = json_decode($searchRes, true);
if (empty($searchResults) || !isset($searchResults[0]['videoId'])) continue;
$videoId = $searchResults[0]['videoId'];
$videoUrl = "{$instance}/api/v1/videos/{$videoId}";
$videoRes = httpGet($videoUrl);
if (!$videoRes) continue;
$videoDetails = json_decode($videoRes, true);
$audioStreams = $videoDetails['audioStreams'] ?? [];
if (!empty($audioStreams)) {
// Sort streams by bitrate (ascending) for low-memory legacy playback
usort($audioStreams, function($a, $b) {
return ($a['bitrate'] ?? 0) <=> ($b['bitrate'] ?? 0);
});
echo json_encode([
'video_id' => $videoId,
'stream_url' => $audioStreams[0]['url'],
'engine' => 'invidious',
'instance' => $instance
]);
exit;
}
}
// Strategy 2: Fallback to Piped API Mirrors
$pipedInstances = [
"https://pipedapi.kavin.rocks",
"https://pipedapi.tokhmi.xyz"
];
foreach ($pipedInstances as $piped) {
$searchUrl = "{$piped}/search?q={$query}&filter=music_songs";
$searchRes = httpGet($searchUrl);
if (!$searchRes) continue;
$searchResults = json_decode($searchRes, true);
$items = $searchResults['items'] ?? [];
if (empty($items)) continue;
$urlPath = $items[0]['url'] ?? '';
preg_match('/v=([a-zA-Z0-9_-]+)/', $urlPath, $vMatch);
$videoId = $vMatch[1] ?? null;
if (!$videoId) continue;
$streamUrl = "{$piped}/streams/{$videoId}";
$streamRes = httpGet($streamUrl);
if (!$streamRes) continue;
$streamDetails = json_decode($streamRes, true);
$audioStreams = $streamDetails['audioStreams'] ?? [];
if (!empty($audioStreams)) {
echo json_encode([
'video_id' => $videoId,
'stream_url' => $audioStreams[0]['url'],
'engine' => 'piped',
'instance' => $piped
]);
exit;
}
}
echo json_encode(['error' => 'No matching stream found across all backend mirrors']);
4 views