97 lines
2.9 KiB
PHP
97 lines
2.9 KiB
PHP
<?php
|
|
/**
|
|
* GridTV — proxy.php (Apache + cURL)
|
|
*/
|
|
|
|
$url = $_GET['url'] ?? '';
|
|
if (empty($url) || !preg_match('#^https?://#i', $url)) {
|
|
http_response_code(400); die('Invalid URL');
|
|
}
|
|
|
|
$base = preg_replace('#[^/]*(\?.*)?$#', '', $url);
|
|
$path = parse_url($url, PHP_URL_PATH) ?? '';
|
|
$is_segment = preg_match('#\.(ts|aac|mp4|m4s|fmp4)(\?|$)#i', $path);
|
|
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Cache-Control: no-cache');
|
|
|
|
$ua = $_SERVER['HTTP_USER_AGENT'] ?? 'Mozilla/5.0';
|
|
|
|
if ($is_segment) {
|
|
// Segment binaire — stream via cURL chunk par chunk
|
|
header('Content-Type: video/MP2T');
|
|
header('X-Content-Type-Options: nosniff');
|
|
|
|
if (ob_get_level()) ob_end_clean();
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_TIMEOUT => 30,
|
|
CURLOPT_USERAGENT => $ua,
|
|
CURLOPT_HTTPHEADER => ['Accept: */*'],
|
|
CURLOPT_RETURNTRANSFER => false,
|
|
CURLOPT_WRITEFUNCTION => function($ch, $data) {
|
|
echo $data;
|
|
flush();
|
|
return strlen($data);
|
|
},
|
|
CURLOPT_HEADERFUNCTION => function($ch, $header) {
|
|
$h = trim($header);
|
|
if (preg_match('/^Content-Type:/i', $h)) {
|
|
header($h);
|
|
}
|
|
return strlen($header);
|
|
},
|
|
]);
|
|
|
|
$ok = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
if (!$ok || $code >= 400) {
|
|
http_response_code($code ?: 502);
|
|
}
|
|
curl_close($ch);
|
|
|
|
} else {
|
|
// Playlist .m3u8 — fetch + réécriture URLs
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_TIMEOUT => 15,
|
|
CURLOPT_USERAGENT => $ua,
|
|
CURLOPT_HTTPHEADER => ['Accept: */*'],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
]);
|
|
$body = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($body === false || $code >= 400) {
|
|
http_response_code($code ?: 502);
|
|
die("Upstream error $code");
|
|
}
|
|
|
|
header('Content-Type: application/vnd.apple.mpegurl');
|
|
|
|
$proxy_base = (isset($_SERVER['HTTPS']) ? 'https' : 'http')
|
|
. '://' . $_SERVER['HTTP_HOST']
|
|
. strtok($_SERVER['REQUEST_URI'], '?')
|
|
. '?url=';
|
|
|
|
$out = [];
|
|
foreach (explode("\n", $body) as $line) {
|
|
$line = rtrim($line);
|
|
if ($line === '' || $line[0] === '#') {
|
|
$line = preg_replace_callback('/URI="([^"]+)"/', function($m) use ($base, $proxy_base) {
|
|
$seg = strpos($m[1], 'http') === 0 ? $m[1] : $base . $m[1];
|
|
return 'URI="' . $proxy_base . urlencode($seg) . '"';
|
|
}, $line);
|
|
$out[] = $line;
|
|
} else {
|
|
$seg = strpos($line, 'http') === 0 ? $line : $base . $line;
|
|
$out[] = $proxy_base . urlencode($seg);
|
|
}
|
|
}
|
|
echo implode("\n", $out);
|
|
}
|