【问题标题】:HTML5 Audio Pushed through PHP Not Cached通过 PHP 推送的 HTML5 音频未缓存
【发布时间】:2012-05-23 23:26:48
【问题描述】:

我正在编写一个网络音频播放器,但我遇到了缓存相当不可靠的问题,唯一想到的是我正在服务的标题。

由于一般的复杂性和安全性,我必须通过 PHP 解析文件,这很好,因为这意味着我可以动态创建它们,但出现的问题是浏览器似乎没有缓存音轨除了在极少数情况下,其他时候他们可能只缓存曲目的前 1/4。我无法可靠地弄清楚它正在缓存什么或为什么。

提供该文件的代码如下。仅供参考,“EncodeTrack”函数仅对尚未创建的轨道进行编码,如果文件已存在则不执行任何操作。

    ## Track Decoder and Streamer
if($_GET['playtrack']) {
    error_log("Dec Start");
    $dectimer = microtime(1);
    ini_set('display_errors', 0);
    $track = trim($_GET['playtrack']);
    preg_match('%^(\w+)\-(\w+)\.(\w+)$%', $track, $trackbits);
    $trackid = $trackbits[1];
    $trackquality = $trackbits[2];
    $trackformat = $trackbits[3];

    $trackarr = mysql_fetch_array(mysql_query("SELECT * FROM `tracks` NATURAL JOIN `artists` NATURAL JOIN `albums` WHERE `track_hash` = '$trackid' LIMIT 1"));
    $file = "$musicfolder/$trackarr[artist_folder]/$trackarr[album_folder]/$trackarr[track_path]";
    $trackpath = escapeshellarg($file);

    EncodeTrack($trackid, $trackformat, $trackpath, $trackquality);
    $transfile = "tmp/$trackid-$trackquality.$trackformat";

    if(file_exists($transfile)) {
        $filesize = filesize($transfile);
        $file = fopen($transfile, 'r');

        if($_SERVER['HTTP_RANGE']) {
            $partial = 1;

            $range = str_replace('bytes=', '', $_SERVER['HTTP_RANGE']);
            $range = explode(',', $range);
            $range = explode('-', $range[0]);

            if($range[0] === '') {
                $end = $filesize - 1;
                $start = $end - intval($range[0]);
            }elseif($range[1] === '') {
                $start = intval($range[0]);
                $end = $filesize - 1;
            }else{
                $start = intval($range[0]);
                $end = intval($range[1]);
                if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) $partial = false; // Invalid range/whole file specified, return whole file
            }      
            $length = $end - $start;

            header("HTTP/1.1 206 Partial Content", 1, 206);
            header("Content-Range: bytes $start-$end/$filesize");
            fseek($file, $start);
        }else{
            $length = $filesize;
        }

        $data = fread($file, $filesize);
        fclose($file);

        header("Content-Length: $length");
        header("Content-Type: audio/$trackformat");
        header("Accept-Ranges: bytes");
        header("Expires: Tue, 23 May 2062 10:00:00 GMT");
        header("ETag: $length");
        header("Cache-Control: public");

        echo($data);
    }else{
        header("HTTP/1.1 404 Not Found", 1, 404);
    }

    error_log("Dec Complete - ".round((microtime(1) - $dectimer)*100));
    exit;
}

我不知道我在这里缺少什么。就部分内容处理而言,这也可能是我做错的事情,但据我所知,这是理智的。

【问题讨论】:

  • 我在视频文件中遇到了类似的问题,在我的情况下,问题不是代码而是公司的内部网络阻止了字节范围请求被正确处理(我猜是因为一些防火墙设置)。也许您也有同样的痛苦——如果不是,请记住这一点,因为流式传输可能是一种真正的痛苦,而且主要问题不是代码而是网络传输。

标签: php html5-audio


【解决方案1】:

如果您怀疑部分内容处理有问题,让pecl_http 发送正确的标头和字节。

if(file_exists($transfile)) 块替换为http_send_file(),如下所示:

http_send_file($transfile);

您的代码更轻松,更不容易出错...此外,pecl_http 为您提供免费的奖励功能,例如http_throttle()

希望这会有所帮助!

【讨论】:

  • 这个问题是它依赖于第三方模块并且(对我来说现在)该模块无法编译。
  • @Enverex:你试图编译什么?有时你需要 php headers 包。在 Ubuntu 上查看这篇文章以获取所需的命令:php.net/manual/en/http.install.php#81371
  • 我正在尝试在 Arch AUR 中使用 pecl-http 包。我收到了 - http_message_object.c:517:2: error: ‘zend_class_entry’ 没有名为 ‘default_properties’ 的成员 - 据我所知,它是最新的稳定版本 (1.7.1)。
  • 看起来版本 1(实际上还没有发布 2)与 PHP 5.4 不兼容,这就是我无法编译它的原因。
  • @Enverex 你试过 v1.7.2,他们说它现在兼容:pecl.php.net/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多