32 в23цыфв фывфывф
[ · Скриншот ] 03.05.2026, 00:54
<?php
error_reporting(0);
ini_set('display_errors', 0);
set_time_limit(0);
ini_set('memory_limit', '256M');

// Отдача готового файла
if (isset($_GET['file'])) {
$filePath = __DIR__ . '/videos/' . basename($_GET['file']);

if (!file_exists($filePath)) {
http_response_code(404);
exit('Файл не найден');
}

$fileName = $_GET['name'] ?? 'video.mp4';
$fileSize = filesize($filePath);

header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . $fileSize);
header('Accept-Ranges: bytes');
header('Cache-Control: no-cache');

while (ob_get_level()) ob_end_clean();
readfile($filePath);
exit;
}

// Сборка видео
if (isset($_GET['download'])) {
$videoUrl = $_GET['video_url'] ?? '';
$title = $_GET['title'] ?? 'video';
if (!$videoUrl) exit('Нет URL');

$title = preg_replace('/[^\w\s\p{Cyrillic}\-]/ui', '', $title) ?: 'video';
$title = str_replace(['/', '\\', '"', "'", '?', '*', ':', '|', '<', '>'], '', $title);

// Папка videos рядом с downloader.php
$tmpDir = __DIR__ . '/videos/';
if (!is_dir($tmpDir)) mkdir($tmpDir, 0755, true);

// Защита от прямого доступа
if (!file_exists($tmpDir . '.htaccess')) {
file_put_contents($tmpDir . '.htaccess', "Require all denied\n");
}

// Удаляем старые файлы (старше 1 часа)
$oldFiles = glob($tmpDir . '*.mp4');
foreach ($oldFiles as $oldFile) {
if (filemtime($oldFile) < time() - 3600) {
@unlink($oldFile);
@unlink(str_replace('.mp4', '.json', $oldFile));
}
}

$fileHash = md5($videoUrl);
$tmpFile = $tmpDir . $fileHash . '.mp4';
$metaFile = $tmpDir . $fileHash . '.json';

// Если уже собран
if (file_exists($tmpFile) && filesize($tmpFile) > 0) {
echo json_encode([
'success' => true,
'file' => $fileHash . '.mp4',
'name' => $title . '.mp4',
'size' => filesize($tmpFile),
'cached' => true
]);
exit;
}

function getUrl($url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 60,
CURLOPT_CONNECTTIMEOUT => 15,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0',
CURLOPT_TCP_NODELAY => 1,
CURLOPT_BUFFERSIZE => 65536
]);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}

$m3u8 = getUrl($videoUrl);
if (!$m3u8) exit('Ошибка загрузки');

$lines = explode("\n", $m3u8);
$segments = [];
$base = dirname($videoUrl);

foreach ($lines as $line) {
$line = trim($line);
if ($line && $line[0] !== '#' && (stripos($line, '.ts') !== false || stripos($line, '.mp4') !== false)) {
if (!preg_match('/^https?:\/\//', $line)) $line = rtrim($base, '/') . '/' . ltrim($line, '/');
$segments[] = $line;
}
}

if (empty($segments)) {
for ($i = 0; $i < count($lines); $i++) {
if (strpos($lines[$i], '#EXT-X-STREAM-INF') !== false) {
$next = trim($lines[$i + 1] ?? '');
if ($next && $next[0] !== '#') {
if (!preg_match('/^https?:\/\//', $next)) $next = rtrim($base, '/') . '/' . ltrim($next, '/');
$sub = getUrl($next);
if ($sub) {
$subLines = explode("\n", $sub);
$subBase = dirname($next);
foreach ($subLines as $sl) {
$sl = trim($sl);
if ($sl && $sl[0] !== '#') {
if (!preg_match('/^https?:\/\//', $sl)) $sl = rtrim($subBase, '/') . '/' . ltrim($sl, '/');
$segments[] = $sl;
}
}
}
break;
}
}
}
}

if (empty($segments)) exit('Нет сегментов');

$fp = fopen($tmpFile, 'w+');
if (!$fp) exit('Не удалось создать файл');

foreach ($segments as $segUrl) {
$data = getUrl($segUrl);
if ($data) fwrite($fp, $data);
}
fclose($fp);

if (!file_exists($tmpFile) || filesize($tmpFile) === 0) exit('Не удалось сохранить');

file_put_contents($metaFile, json_encode(['title' => $title, 'created' => time()]));

echo json_encode([
'success' => true,
'file' => $fileHash . '.mp4',
'name' => $title . '.mp4',
'size' => filesize($tmpFile),
'cached' => false
]);
exit;
}

// API
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');

$url = $_GET['url'] ?? '';
if (!$url) die(json_encode(['s'=>false,'e'=>'Введите ссылку']));
if (!str_contains($url, 'rutube.ru')) die(json_encode(['s'=>false,'e'=>'Только RuTube']));

preg_match('/video\/([a-f0-9]+)/i', $url, $m);
if (!isset($m[1])) die(json_encode(['s'=>false,'e'=>'Неверная ссылка']));
$id = $m[1];

$ch = curl_init("https://rutube.ru/api/play/options/$id/?no_404=true");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_FOLLOWLOCATION=>true,CURLOPT_SSL_VERIFYPEER=>false,CURLOPT_TIMEOUT=>10,CURLOPT_USERAGENT=>'Mozilla/5.0']);
$j = curl_exec($ch); curl_close($ch);
if (!$j) die(json_encode(['s'=>false,'e'=>'API не отвечает']));
$d = json_decode($j, true);
if (!$d||isset($d['detail'])||empty($d['video_balancer']['m3u8'])) die(json_encode(['s'=>false,'e'=>'Видео недоступно']));

$title = $d['title']??'Видео'; $m3u8 = $d['video_balancer']['m3u8'];
$ch2 = curl_init($m3u8);
curl_setopt_array($ch2, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_FOLLOWLOCATION=>true,CURLOPT_SSL_VERIFYPEER=>false,CURLOPT_TIMEOUT=>10,CURLOPT_USERAGENT=>'Mozilla/5.0']);
$mc = curl_exec($ch2); curl_close($ch2);
$lines = explode("\n", $mc); $qualities = []; $base = dirname($m3u8);

for ($i=0;$i<count($lines);$i++) {
if (strpos($lines[$i],'#EXT-X-STREAM-INF')!==false) {
$res='';$bw='';$bwr=0;
if (preg_match('/RESOLUTION=(\d+x\d+)/',$lines[$i],$rm)) $res=$rm[1];
if (preg_match('/BANDWIDTH=(\d+)/',$lines[$i],$bm)){$bwr=(int)$bm[1];$bw=' ('.round($bwr/1000000,1).' Mbps)';}
$nxt=trim($lines[$i+1]??'');
if ($nxt&&$nxt[0]!=='#') {
if (!str_starts_with($nxt,'http')) $nxt=rtrim($base,'/').'/'.ltrim($nxt,'/');
$qualities[($res?:'Поток').$bw]=['url'=>$nxt,'resolution'=>$res,'bandwidth'=>$bwr];
}
}
}
if (empty($qualities)) $qualities['Стандартное']=['url'=>$m3u8,'resolution'=>'','bandwidth'=>0];
echo json_encode(['s'=>true,'d'=>['title'=>$title,'qualities'=>$qualities]],JSON_UNESCAPED_UNICODE);


вфывфывыф фывфывфы
фы
вфы
в
фывф

Цитата
ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва


ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва

ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва


ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва ывавы аыва ыва ываыв ыва

фывфывфвфывфы вфы
фывфывфывфывфывфывфы
фывфывфывфывфывфывфывффы вфыв фыв фв
фывфывфывфвф фвы фы вфы вфывф фвф вф


фывыфвы
фвфывфывфыв фыыфв фвфв
Категория: Серера | Добавил: malfed4ik
Просмотров: 80 | Загрузок: 0 | Комментарии: 6 | Рейтинг: 1.0/1


Всего комментариев: 6
avatar
1 malfed4ik • 01:33, 03.05.2026
0
выавыаываываыва
avatar
2 malfed4ik • 10:38, 03.05.2026
0
выаыв аываыв
avatar
3 malfed4ik • 02:15, 04.05.2026
0
впвпвпв
avatar
4 malfed4ik • 02:18, 04.05.2026
0
авпвапвпв
avatar
5 malfed4ik • 02:18, 04.05.2026
0
авпвапвпв
avatar
6 malfed4ik • 02:20, 04.05.2026
0
павапв авапва ва