用 PHP 读取 mp4 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15797762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading mp4 files with PHP
提问by user2221276
I'm trying to read mp4 file with PHP and what I'm doing now is this:
我正在尝试用 PHP 读取 mp4 文件,我现在正在做的是:
<?php
header("Content-Length: filesize");
readfile('file.mp4');
?>
but this way I can't skip or even go back until the video is not loaded 100%. Of course when I read directly from the file (video.mp4) everything goes well.
但是这样我就无法跳过甚至返回,直到视频未 100% 加载。当然,当我直接从文件 (video.mp4) 中读取时,一切顺利。
Thanks.
谢谢。
回答by cmc
You need to implement the skipping functionality yourself in PHP. This is a code snippet that will do that.
您需要自己在 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();
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.
请注意,这不是最有效的方法,因为整个文件都需要通过 PHP,所以您只需要尝试一下它是如何进行的。
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.
假设您要这样做的原因是限制访问,并且您以后需要更高的效率,则可以为 Web 服务器使用一个标志。
Apache with X-Sendfile module or lightty (nginx info here)
带有 X-Sendfile 模块或 lightty 的 Apache(此处为 nginx 信息)
$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.
这有点高级,您应该只在需要时使用它,但是当您开始使用相当简单但性能平庸的东西时,知道您有升级选项是令人放松的。
回答by Josh Powlison
I found a much cheaper PHP-only way by experimenting with the accepted solution. Although I haven't tested this against X-Sendfile, I suspect the performance is even better overall for your site, since it means a shorter Apache file.
通过试验公认的解决方案,我找到了一种更便宜的仅 PHP 方法。虽然我没有针对 X-Sendfile 测试过这个,但我怀疑您的站点的整体性能甚至更好,因为它意味着更短的 Apache 文件。
You only need the following code to be put out seekable .mp4 videos from PHP (haven't tested with .webm or other types):
您只需要以下代码即可从 PHP 中导出可搜索的 .mp4 视频(尚未使用 .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);
Much cleaner and faster; the accepted answer's code resulted in the video taking a very long time to load for some reason, loading the video with this code was instantaneous (both tests were on a local server with a 7.25 MB video file).
更干净、更快;接受的答案的代码导致视频由于某种原因需要很长时间才能加载,使用此代码加载视频是即时的(两个测试都在具有 7.25 MB 视频文件的本地服务器上)。
Tested with Chrome, Firefox, and Edge's default video players.
使用 Chrome、Firefox 和 Edge 的默认视频播放器进行测试。
Edit: tested without header('Content-Type: video/mp4');
, it still works if the file's loaded from another page! If you directly access the URL, there will be no video player; the code will just be printed out.
编辑:没有测试header('Content-Type: video/mp4');
,如果文件是从另一个页面加载的,它仍然有效!如果直接访问网址,则没有视频播放器;代码只会被打印出来。