Чтение файлов mp4 с помощью PHP
Я пытаюсь прочитать файл mp4 с помощью PHP, и сейчас я делаю так:
<?php
header("Content-Length: filesize");
readfile('file.mp4');
?>
но так я не могу пропустить или даже вернуться, пока видео не загрузится на 100%. Конечно, когда я читаю прямо из файла (video.mp4), все идет хорошо.
Благодарю.
2 ответа
Вам нужно самостоятельно реализовать функцию пропуска в PHP. Это фрагмент кода, который сделает это.
<?php
$path = 'file.mp4';
$size=filesize($path);
$fm=@fopen($path,'rb');
if(!$fm) {
// You can also redirect here
header ("HTTP/1.0 404 Not Found");
die();
}
$begin=0;
$end=$size;
if(isset($_SERVER['HTTP_RANGE'])) {
if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) {
$begin=intval($matches[0]);
if(!empty($matches[1])) {
$end=intval($matches[1]);
}
}
}
if($begin>0||$end<$size)
header('HTTP/1.0 206 Partial Content');
else
header('HTTP/1.0 200 OK');
header("Content-Type: video/mp4");
header('Accept-Ranges: bytes');
header('Content-Length:'.($end-$begin));
header("Content-Disposition: inline;");
header("Content-Range: bytes $begin-$end/$size");
header("Content-Transfer-Encoding: binary\n");
header('Connection: close');
$cur=$begin;
fseek($fm,$begin,0);
while(!feof($fm)&&$cur<$end&&(connection_status()==0))
{ print fread($fm,min(1024*16,$end-$cur));
$cur+=1024*16;
usleep(1000);
}
die();
Больше производительности
Обратите внимание, что это не самый эффективный способ сделать это, потому что весь файл должен проходить через PHP, поэтому вам просто нужно попробовать, как он работает для вас.
Предполагая, что причина, по которой вы хотите это сделать, заключается в том, чтобы ограничить доступ, и в дальнейшем вам потребуется больше эффективности, вы можете использовать флаг для веб-сервера.
Apache с модулем X-Sendfile или lightty ( информация о nginx здесь)
$path = 'file.mp4';
header("X-Sendfile: $path");
die();
Это немного сложнее, и вы должны использовать его только тогда, когда вам это нужно, но приятно знать, что у вас есть опция обновления, когда вы начинаете с чего-то, что довольно просто, но имеет посредственную производительность.
Я нашел гораздо более дешевый способ только на PHP, экспериментируя с принятым решением. Хотя я не проверял это на X-Sendfile, я подозреваю, что в целом производительность вашего сайта еще выше, поскольку это означает более короткий файл Apache.
Вам нужен только следующий код, чтобы создать доступное видео с расширением.mp4 из PHP (не тестировалось с.webm или другими типами):
$file='path/file.mp4';
header('Content-Type: video/mp4'); #Optional if you'll only load it from other pages
header('Accept-Ranges: bytes');
header('Content-Length:'.filesize($file));
readfile($file);
Намного чище и быстрее; Принятый код ответа привел к тому, что видео по какой-то причине загружалось очень долго, загрузка видео с этим кодом была мгновенной (оба теста были на локальном сервере с 7,25 МБ видеофайла).
Протестировано с Chrome, Firefox и видео проигрывателями Edge по умолчанию.
Редактировать: проверено без header('Content-Type: video/mp4');
, он все еще работает, если файл загружен с другой страницы! Если вы обращаетесь к URL напрямую, видеоплеер не будет; код будет просто распечатан.