Using php to output an mp4 video

ぐ巨炮叔叔 提交于 2019-11-26 19:46:50

Iphones use something called byte-ranges for audio and video requests. See this link for a solution. It's in Appendix A.

http://mobiforge.com/developing/story/content-delivery-mobile-devices

cmc

Here is a code snipped that will do what you want (from this question). The PHP solution seems more elegant, and it adds a more efficient solution that might work that uses the web server to serve the content.

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

More Performance

Note that this is not the most efficient way to do it, because the whole file needs to go through PHP, so you will just need to try how it goes for you.

Assuming the reason you want to do this is to restrict access, and you need more efficiency later, you can use a flag for the web server.

Apache with X-Sendfile module or lightty (nginx info here)

$path = 'file.mp4';
header("X-Sendfile: $path");
die();

This is a bit more advanced and you should only use it if you need it, but it is relaxing to know you have an upgrade option when you start out with something that is rather easy but has mediocre performance.

jefftimesten

This code was very handy for me, but I ran into trouble because I am using session vars, and PHP queues access to sessions. If a video was loading, all AJAX requests were impossible, etc. So make sure to call session_write_close() before you start output.

WebAdmin at dekho-ji.com

Yes, its easy to do. No need to set those headers manually. Let the server do it automatically.

Heres a working 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);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!