32 в23цыфв фывфывф


<?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);


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

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


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

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


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

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


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


Комментариев 6
malfed4ik
выавыаываываыва
malfed4ik
выаыв аываыв
malfed4ik
впвпвпв
malfed4ik
авпвапвпв
malfed4ik
авпвапвпв
malfed4ik
павапв авапва ва
Привет, оставишь комментарий?
Имя:*
E-Mail:


МЫ ВКонтакте

Подписывайся на нашу группу в ВК.
Узнай многое в мире кода!
Только все самое интересное.
Поддержи нашу группу!

Подписатся
НАШ Видео АРХИВ

Посетите наш видео архив.
Видео на все случаи жизни!
Изучай, развивайся, отдыхай!

Смотреть
Обновления new
MTA: Установка сервера в три дыхания
malfed4ik Все для MTA

Три шага к свободе: как поставить Multi Theft Auto и зайти на сервер, не читая форумов. Короткий гайд для тех, кто хочет играть, а не возиться с настройками. От скачивания до первого коннекта через F8.

MTA: Установка сервера в три дыхания
malfed4ik Все для MTA

Три шага к свободе: как поставить Multi Theft Auto и зайти на сервер, не читая форумов. Короткий гайд для тех, кто хочет играть, а не возиться с настройками. От скачивания до первого коннекта через F8.

MTA: Установка сервера в три дыхания
malfed4ik Все для MTA

Три шага к свободе: как поставить Multi Theft Auto и зайти на сервер, не читая форумов. Короткий гайд для тех, кто хочет играть, а не возиться с настройками. От скачивания до первого коннекта через F8.

MTA: Установка сервера в три дыхания
malfed4ik Все для MTA

Три шага к свободе: как поставить Multi Theft Auto и зайти на сервер, не читая форумов. Короткий гайд для тех, кто хочет играть, а не возиться с настройками. От скачивания до первого коннекта через F8.

Как добавить замену модели на сервер MTA: пошаговая инструкция
malfed4ik Все для MTA

Как добавить замену модели на сервер MTA: пошаговая инструкция

МИНИ ЧАТ

Соблюдайте правила.

ЧИТАЙ ПРАВИЛА
Статистика