为什么 PHP 会干扰我的 HTML5 MP4 视频?

发布于 2024-09-08 15:45:34 字数 430 浏览 1 评论 0原文

我正在编写一个提供 H.264 编码 MP4 视频的 Web 应用程序。在 Chrome 和 Safari 中,它通过 HTML5 视频标签来实现这一点。

为了控制对这些视频的访问,它们的内容通过 PHP 使用一种非常简单的机制提供:

header('Content-type: video/mp4');
readfile($filename);
exit;

无论我做什么,视频都不会流式传输。另外:

  • 如果我更改源代码以直接提供文件,使用相同的视频标签但链接到 Apache 提供的视频副本,没有 PHP 传递,则流式传输工作正常。
  • 即使流式传输不起作用,我也可以右键单击灰显的 HTML5 播放器并通过 PHP 传递下载文件 - 而且离线播放效果非常好。

有什么想法吗?我要拔头发了!

I'm writing a web app that serves H.264 encoded MP4 video. In Chrome and Safari, it does this via an HTML5 video tag.

In order to control access to these videos, their contents are served via PHP using a really simply mechanism:

header('Content-type: video/mp4');
readfile($filename);
exit;

No matter what I do, the videos will not stream. Additionally:

  • If I change the source code to serve the files directly, using the same video tag but linking to an Apache-served copy of the video with no PHP pass-through, streaming works fine.
  • Even when streaming doesn't work, I can always right click on the greyed-out HTML5 player and download the file through the PHP pass-through - and it plays great offline.

Any ideas? I'm pulling my hair out!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ぃ双果 2024-09-15 15:45:34

或许。尝试添加内容长度标头:

header('Content-length: '.filesize($filename));

如果这仍然不起作用,请检查 readfile 之前的任何输出(echo)。还要检查 ?> 后面没有空格,或者只是省略 ?> (如果后面没有任何内容,则不是强制性的)。

正如 Bruno 提到的,要支持流式传输,您还需要遵守 Range 标头。这是一个仅考虑左边界的简化示例:

if (empty($_SERVER["HTTP_RANGE"])) {
    //do your current stuff...
}
else { //violes rfc2616, which requires ignoring  the header if it's invalid
    preg_match("/^bytes=(\d+)-/i",$_SERVER["HTTP_RANGE"], $matches);
         $offset = (int) $matches[1];
    if ($offset < $filesize && $offset >= 0) {
        if (@fseek($fp, $offset, SEEK_SET) != 0)
            die("err");
        header("HTTP/1.1 206 Partial Content");
        header("Content-Range: bytes $offset-".($filesize - 1)."/$filesize");
    }
    else {
        header("HTTP/1.1 416 Requested Range Not Satisfiable");
        die();
    }
        //fread in loop here
}

Maybe. Try adding also the content length header:

header('Content-length: '.filesize($filename));

If this still doesn't work, check for any output before readfile (echo's or whitespace before <?php). Check also that you don't have whitespace after ?> or simply omit ?> (it's not mandatory if you have nothing after).

As Bruno mentioned, to support streaming, you also need to obey the Range header. Here's a simplified example that respects only the left bound:

if (empty($_SERVER["HTTP_RANGE"])) {
    //do your current stuff...
}
else { //violes rfc2616, which requires ignoring  the header if it's invalid
    preg_match("/^bytes=(\d+)-/i",$_SERVER["HTTP_RANGE"], $matches);
         $offset = (int) $matches[1];
    if ($offset < $filesize && $offset >= 0) {
        if (@fseek($fp, $offset, SEEK_SET) != 0)
            die("err");
        header("HTTP/1.1 206 Partial Content");
        header("Content-Range: bytes $offset-".($filesize - 1)."/$filesize");
    }
    else {
        header("HTTP/1.1 416 Requested Range Not Satisfiable");
        die();
    }
        //fread in loop here
}
过期情话 2024-09-15 15:45:34

将文件流式传输到 HTML5 嵌入式视频播放器时,您仍然需要添加标头,以通知播放器有关视频的信息。

你不能只指望运行一个 read readfile() 命令,事情就会神奇地工作,对不起,伙计,但编程并不那么容易。 (希望如此)。

这是一个小应用程序,您可以使用它来正确地进行流式传输或只是学习。

http://stream.xmoov.com/download/xmoov-php/

When streaming files to HTML5 Embedded video player you still have to add headers that inform the player with information about the video.

you can't just expect to run a read readfile() command and things will magically work, sorry bud, but programming is not that easy. (Wish it was).

heres a small application you can use to stream properly or just learn from.

http://stream.xmoov.com/download/xmoov-php/

岁吢 2024-09-15 15:45:34

查看评论!

不建议使用 readfile 来流式传输视频文件,因为它会在输出之前将整个文件加载到内存中。这会导致内存耗尽的严重问题。

尝试逐块读取并输出文件。

See comments!

Using readfile is not recommended for streaming video files since it loads the whole file into memory before outputting. This causes serious problems with memory running out.

Try reading and outputting the file chunk by chunk.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文