逐步通过php文件流式传输mp4 [英] Streaming an mp4 through a php file progressively

查看:2045
本文介绍了逐步通过php文件流式传输mp4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我们的视频播放器开发更安全的流媒体方法。因为每个文件都需要特殊的令牌认证,并且只允许每个令牌加载一次,所以我通过php容器运行MP4。这在HTML5视频代码中完美运行,可防止用户轻松下载源代码。

I'm working on a more secure streaming method for our video player. Because each file requires special token authentication and also only allows each token to be loaded once, I'm running MP4 through a php container. This works perfectly inside a HTML5 video tag and prevents users from easily downloading the source.

我正在调整一些代码这里

<?php
include('...'); //include site functions

/*
   Here I connect to the database, and retrieve the
   location of the video which is returned as
   $video = "http://domain.tld/folder/file.mp4"

   This has been removed for this SO example.
*/

$file = $video;
$fp = @fopen($file, 'rb');

$head = array_change_key_case(get_headers($file, TRUE));
$size = $head['content-length'];


//$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");
header("Accept-Ranges: bytes");
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();
?>

现在出现问题,因为我希望能够进入视频。跳到视频中尚未加载的区域会导致< video> 标记(和chrome)崩溃。

Problems now arise as I'd like to be able to seek into the video. Skipping to an area in the video which has not been loaded crashes the <video> tag (and chrome).

我认为既然HTML5播放器在几秒钟内寻找并且PHP以字节为单位加载,那就无法做到这一点。这就是我在这里问的原因。

I'd assume that since the HTML5 player is seeking in seconds and the PHP is loading in bytes, that this cannot be done. Which is why I'm asking here.

我可以做什么(如果有的话)允许渐进式流式传输?

是否有更合适的容器我可以使用哪种格式用于同一目的?

What can I do (if anything) to allow progressive streaming?
Is there a more appropriate container format I could use which would serve the same purpose?

推荐答案

我认为你有一个概念上的失败。您正在将mp4文件视为原始数据文件。我试着解释一下自己。

I think that you have a conceptual failure. You are treating the mp4 file like if it were a "raw data file". I try to explain myself.

想象一下你有一个文本文件,你想从位置X获取字符。你可以打开文件,将光标指向正确的位置,然后逐字节读取您的文本。这样可以正常工作。

Imagine that you have a text file, and you want to get the chars from position X. You can open the file, point the cursor to the correct position and then read byte by byte your text. This will work fine.

但现在想要使用文本处理器文件执行相同操作的图像。你会期待同样的结果吗?不,因为文件中有很多元数据阻止你这样做。

But now image that you want to do the same but with a text processor file. Would you expect the same results? No, because you have a lot of metadata in the file that prevents you from doing that.

你的问题基本相同。您需要考虑文件的格式,使用为其设计的库来管理文件,或者自己完成。

Your problem is basically the same. You need to take in consideration the format of the file, managing the file with libraries designed for it, or doing by yourself.

另一个选项是使用raw数据文件,但在视频文件的情况下,这些将是非常大的文件。

The other option will be to work with raw data files, but in the case of video files, these are going to be really big files.

我希望我帮助过你。

这篇关于逐步通过php文件流式传输mp4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆