【问题标题】:php streaming wav in firefox vs chromephp在firefox vs chrome中流式传输wav
【发布时间】:2014-06-17 11:51:17
【问题描述】:

我在页面中有一个隐藏的音频元素,我正在动态设置源。我将其设置为带有 GET 请求的 php 页面,该请求根据 GET 参数查找文件。

但是,音频元素在 Chrome 中可以很好地获取 wav 文件,但在 Firefox 中却不行。这是查询和html

    <html>
<audio id = "play_wav" controls>
<span id = "set_source">set source</span>

<script>
$('#set_source').on('click', function(){
    $('#play_wav').attr('src', 'get_wav.php?fname=playme.wav');
    document.getElementById('play_wav').play();
});

</script>

</html>

这里是 get_wav.php

if(isset($_GET['fname])){
    $fname = $_GET['fname'];
    readfile($fname);
}

因此,这可以在 chrome 中播放流式音频,但不能在 Firefox 中播放。源仍在设置中,只是没有加载。有什么建议吗?

【问题讨论】:

  • sidenote 您可以使用当前的 php 代码进行攻击,例如 get_wav.php?fname=index.php 将回显 index.php 文件的源代码。
  • another sidenote 你在get_waw.php 附近的isset() 中有语法错误。
  • 我知道参数实际上是数据库中的别名。不过谢谢你。这只是为了演示一个问题

标签: javascript php google-chrome firefox audio


【解决方案1】:

首先,您不应该将音频文件与您的 php 文件存储在同一目录中,因为它很容易通过使用 basename() 函数来隔离文件名来防止有人加载您的 PHP 文件,否则您必须 进一步检查它不是传递给 $_GET['fname'] 参数的 php 或系统文件路径,您还应该在包含 deny from all 的媒体文件夹中放置一个 .htaccess,这将停止直接访问,如果您如果希望能够使用可搜索功能进行流式传输,那么您需要处理 HTTP_RANGE 标头。

<?php
if(!empty($_GET['fname'])){
    $file_name = './wav_files/'.basename($_GET['fname']);
    stream($file_name, 'audio/wav');
}

/**
 * Streamable file handler
 *
 * @param String $file_location
 * @param Header|String $content_type
 * @return content
 */
function stream($file, $content_type = 'application/octet-stream') {

    // Make sure the files exists
    if (!file_exists($file)) {
        header("HTTP/1.1 404 Not Found");
        exit;
    }

    // Get file size
    $filesize = sprintf("%u", filesize($file));

    // Handle 'Range' header
    if(isset($_SERVER['HTTP_RANGE'])){
        $range = $_SERVER['HTTP_RANGE'];
    }elseif($apache = apache_request_headers()){
        $headers = array();
        foreach ($apache as $header => $val){
            $headers[strtolower($header)] = $val;
        }
        if(isset($headers['range'])){
            $range = $headers['range'];
        }
        else $range = FALSE;
    } else $range = FALSE;

    //Is range
    if($range){
        $partial = true;
        list($param, $range) = explode('=',$range);
        // Bad request - range unit is not 'bytes'
        if(strtolower(trim($param)) != 'bytes'){
            header("HTTP/1.1 400 Invalid Request");
            exit;
        }
        // Get range values
        $range = explode(',',$range);
        $range = explode('-',$range[0]);
        // Deal with range values
        if ($range[0] === ''){
            $end = $filesize - 1;
            $start = $end - intval($range[0]);
        } else if ($range[1] === '') {
            $start = intval($range[0]);
            $end = $filesize - 1;
        }else{
            // Both numbers present, return specific range
            $start = intval($range[0]);
            $end = intval($range[1]);
            if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) $partial = false;
        }
        $length = $end - $start + 1;
    }
    // No range requested
    else {
        $partial = false;
        $length = $filesize;
    }

    // Send standard headers
    header("Content-Type: $content_type");
    header("Content-Length: $length");
    header('Accept-Ranges: bytes');

    // send extra headers for range handling...
    if ($partial) {
        header('HTTP/1.1 206 Partial Content');
        header("Content-Range: bytes $start-$end/$filesize");
        if (!$fp = fopen($file, 'rb')) { // Error out if we can't read the file
            header("HTTP/1.1 500 Internal Server Error");
            exit;
        }
        if ($start) fseek($fp,$start);
        while($length){
            set_time_limit(0);
            $read = ($length > 8192) ? 8192 : $length;
            $length -= $read;
            print(fread($fp,$read));
        }
        fclose($fp);
    }
    //just send the whole file
    else readfile($file);
    exit;
}
?>

【讨论】:

  • 我刚试过这个,无法让它在 firefox 或 chrome 上工作。 apache 日志中没有错误
  • 我刚刚通过添加 header('Content-type:audio/wav) 让它工作,firefox 没有问题
猜你喜欢
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 2011-08-18
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多