Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用PHP读取mp4文件_Php_Mp4_Readfile - Fatal编程技术网

用PHP读取mp4文件

用PHP读取mp4文件,php,mp4,readfile,Php,Mp4,Readfile,我正在尝试用PHP读取mp4文件,现在我要做的是: <?php header("Content-Length: filesize"); readfile('file.mp4'); ?> 但这样我就不能跳过甚至返回,直到视频没有100%加载。当然,当我直接从文件(video.mp4)中读取时,一切都很顺利 谢谢。您需要自己在PHP中实现跳过功能。这是一个可以实现这一点的代码片段 <?php $path = 'file.mp4'; $size=filesize($path

我正在尝试用PHP读取mp4文件,现在我要做的是:

<?php
header("Content-Length: filesize");
readfile('file.mp4');
?>

但这样我就不能跳过甚至返回,直到视频没有100%加载。当然,当我直接从文件(video.mp4)中读取时,一切都很顺利


谢谢。

您需要自己在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专用方法。虽然我还没有对X-Sendfile进行测试,但我怀疑对于您的站点来说,总体性能更好,因为这意味着Apache文件更短

您只需要以下代码就可以从PHP中发布seekable.mp4视频(尚未使用.webm或其他类型进行测试):

更干净、更快;由于某种原因,接受答案的代码导致加载视频花费了很长时间,使用此代码加载视频是瞬时的(两个测试都是在本地服务器上进行的,视频文件为7.25 MB)

使用Chrome、Firefox和Edge的默认视频播放器进行测试


编辑:测试时没有
标题(“内容类型:视频/mp4”),如果文件是从另一个页面加载的,它仍然有效!如果直接访问URL,则不会有视频播放器;代码将被打印出来。

您的问题是:
内容长度
标题无效。另外,您是否发送了一个好的
内容类型
标题?我的问题是如何正确读取文件,以便在直接访问文件时能够来回切换。谢谢那些反对票是怎么回事?这是一个完全合理的问题。您是否尝试使用http链接作为视频源在播放器中播放视频?你的问题不是很清楚,也许你想编辑以更清楚地表达你的意图。还有,你用的是哪个播放器?你的命令行是什么(如果有的话)?非常有效。非常感谢你!这对我来说非常有效,但我注意到当我点击URL时,它总是加载相同的文件。为了强制它获取一个新的URL,我必须添加一个get参数。这没关系,因为我的所有文件都将作为file.php?path/to/file加载,但我想知道是什么原因导致了这种情况。它是缓存在服务器端还是客户端?重置我的浏览器似乎无法解决这个问题。不过主要是好奇。加载文件在生产代码中运行良好。@StevenSokulski虽然您可以添加标题以防止缓存,但中间缓存可能会忽略它们,因此最安全的方法是继续更改URL。这样,你就可以反方向使用遥远未来的报头来节省带宽。这看起来像吗?@ViktorJoras已经有一段时间了,但在我的测试中,一切都正常。如果不是,请尝试添加上面提到的内容类型,它应该可以工作。
$path = 'file.mp4';
header("X-Sendfile: $path");
die();
$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);