Ответ 1
Iphones используют так называемые байтовые диапазоны для аудио и видео запросов. См. Эту ссылку для решения. Это в Приложении А.
http://mobiforge.com/developing/story/content-delivery-mobile-devices
Хорошо, в основном у меня есть проект, который требует, чтобы видео были скрыты от пользователей, хотя они все еще могли их видеть (используя php). вот что я получил до сих пор:
В файле video.php есть следующее:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'path/to/movie.mp4');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$out = curl_exec($ch);
curl_close($ch);
header('Content-type: video/mp4');
header('Content-type: video/mpeg');
header('Content-disposition: inline');
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($out));
echo $out;
exit();
?>
и html файл, который должен отображать это, использует html5, как и ожидалось. теперь вот вещь.. когда я прямо вставляю это (нет), это работает. но он не работает на моем iPhone и не работает в теге... если я использую прямой файл вместо php-обертки, все работает отлично, на моем iPhone тоже...
поэтому я думаю, что мой вопрос для этого заключается в следующем: какова правильная информация header() для полной репликации mp4, которая может транслироваться через iPhone и HMTL5?
Решение, полученное из: http://mobiforge.com/developing/story/content-delivery-mobile-devices
video.php файл:
<?php
$file = 'path/to/videofile.mp4';
$fp = @fopen($file, 'rb');
$size = filesize($file); // File size
$length = $size; // Content length
$start = 0; // Start byte
$end = $size - 1; // End byte
header('Content-type: video/mp4');
header("Accept-Ranges: 0-$length");
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $start;
$c_end = $end;
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if (strpos($range, ',') !== false) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
if ($range == '-') {
$c_start = $size - substr($range, 1);
}else{
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
}
$c_end = ($c_end > $end) ? $end : $c_end;
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
fseek($fp, $start);
header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: ".$length);
$buffer = 1024 * 8;
while(!feof($fp) && ($p = ftell($fp)) <= $end) {
if ($p + $buffer > $end) {
$buffer = $end - $p + 1;
}
set_time_limit(0);
echo fread($fp, $buffer);
flush();
}
fclose($fp);
exit();
?>
Iphones используют так называемые байтовые диапазоны для аудио и видео запросов. См. Эту ссылку для решения. Это в Приложении А.
http://mobiforge.com/developing/story/content-delivery-mobile-devices
Вот фрагмент кода, который сделает то, что вы хотите (из этого вопроса). Решение PHP кажется более элегантным, и оно добавляет более эффективное решение, которое может работать, которое использует веб-сервер для обслуживания содержимого.
<?php
$path = 'file.mp4';
$size=filesize($path);
[email protected]($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 - доступ к сеансам. Если видео загружалось, все запросы AJAX были невозможны и т.д. Поэтому перед тем, как начать вывод, обязательно вызовите session_write_close()
.
Да, это легко сделать. Не нужно устанавливать эти заголовки вручную. Пусть сервер сделает это автоматически.
Здесь работает script -
ob_start();
if( isset($_SERVER['HTTP_RANGE']) )
$opts['http']['header']="Range: ".$_SERVER['HTTP_RANGE'];
$opts['http']['method']= "HEAD";
$conh=stream_context_create($opts);
$opts['http']['method']= "GET";
$cong= stream_context_create($opts);
$out[]= file_get_contents($real_file_location_path_or_url,false,$conh);
$out[]= $http_response_header;
ob_end_clean();
array_map("header",$http_response_header);
readfile($real_file_location_path_or_url,false,$cong);