2

我一直在为使用 cakephp 2.0.3 的教师开发一个网站。一项要求是教师能够上传只有给定班级的学生才能查看的文件(图像、文档、pdf 和视频)。我一直在使用 php fpassthrough 将二进制数据读取到 http 输出流。

这对除视频外的所有文档都有效,chrome 内置播放器、vlc firefox 插件或 jwplayer 将无法播放视频,视频将在实际网站上使用。但是,如果我保存文件,Windows 媒体播放器将正常播放该文件。从 cakephp webroot 目录播放文件也可以正常工作。这是文件查看代码:

加载和输出文件的控制器代码:

//cakephp find used to pull file information from database
$fileName = "/redacted/" . $File['File']['unit_id'] . "/" . $File['File']['id'];
$fp = fopen($fileName, 'rb');

header("Content-Type: " . $File['File']['type']);
header("Content-Length: " . filesize($fileName));

fpassthru($fp);

使用的布局:

<?php echo $this->fetch('content'); ?>

jwplayer加载代码:

<div style="width: 200px; height: 91px;" id="1">&nbsp;</div>
<script type="text/javascript">
    jwplayer("1").setup({
        file: "/Files/view/1/blah.m4v",
    });
</script>

视图文件为空,因为所有输出都在控制器中完成。我浏览了这个网站和谷歌,但找不到问题的原因或执行此功能的更好方法。我已经验证标题是正确的,并且之前或之后没有错误的换行符或数据。我还检查了是否不需要扩展名(在最后的代码块中,'1' 指定文件 ID,最后的文件名是虚拟的)。

我的问题,因此:

  1. fpassthru()、readfile() 或类似的 php 视频直通的正确方法是什么?
  2. 这个问题是我的代码特有的,还是 cakephp 处理 MVC 所固有的?有没有人成功实施过这样的解决方案?
  3. 是否有任何其他“跳出框框思考”的解决方案(使用 node.js 或其他语言,.htaccess 技巧)会更好。
  4. 我可以在 webroot 文件夹中使用非 cakephp 脚本,但我将如何传递用户会话数据?这只是一个愚蠢的想法吗?

[编辑] 在与 cakephp 分开的视频文件上测试 fpassthrough 后,我发现问题出在视频直通而不是 cakephp 上。此代码用于测试,在 app/webroot 目录中:

<?php
    $fileName = "/var/www/redacted/files/2/1";
    $fp = fopen($fileName, 'rb');
    header("Content-Type: video/mp4");
    header("Content-Length: 18485");
    fpassthru($fp);
?>

内容类型、路径和长度取自该文件的数据库条目。

4

1 回答 1

1

Cake 具有您想要内置的功能,请查看文档中的媒体视图。请注意,它在 Cake 2.3.0 中已被弃用,但由于您使用的是 2.0,它应该可以正常工作。我测试了以下代码,在 jwplayer 或 VLC 插件中播放示例 m4v 没有问题:

$this->viewClass = 'Media';

$fileName = WWW_ROOT . DS . 'sample_iPod.m4v';

$parts = pathinfo($fileName);

$params = array(
    'id' => $parts['basename'],
    'name' => $parts['filename'], // requires PHP >= 5.2.0
    'extension' => $parts['extension'],
    'download' => false,
    'path' => $parts['dirname'] . DS
);

$this->set($params);

请注意,Cake 会根据扩展名自动为您输出正确的内容类型/长度。

于 2013-02-20T21:00:23.360 回答