10

我做了这个 PHP 脚本

    $file_name = 'sample.mp3';

    header('内容类型:音频/mpeg');

    $opts = 数组('http' =>
                      大批(
                          '方法' => 'GET',
                          'protocol_version' => 1.1,
                      )
    );
    $context = stream_context_create($opts);
    $stream = fopen($file_name, 'rb', FALSE, $context);
    $metadata = stream_get_meta_data($stream);
    $data = stream_get_contents($stream);
    打印($数据);
    fclose($流);

它可以成功流式传输 mp3 媒体,但我无法找到也在 html5video标签中播放的 mp3 文件无法从中提取元数据,请告诉我我做错了什么以及如何使这个过程正常工作,谢谢

4

2 回答 2

24

在这里试试这个,支持部分下载和寻找任何文件大小,现在也可以在 chrome 中正常工作:

<?php 
$file_name = './sample.mp3';
stream($file_name, 'audio/mpeg');

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

    // Make sure the files exists, otherwise we are wasting our time
    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; // Invalid range/whole file specified, return whole file
        }
        $length = $end - $start + 1;
    }
    // No range requested
    else $partial = false; 

    // Send standard headers
    header("Content-Type: $content_type");
    header("Content-Length: " . ($partial ? $length : $filesize));
    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')) {
            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;
}
?>
于 2012-07-05T09:46:16.540 回答
0

This should hopefully fix your problem, follow this method.

What you need to do is use readfile() and set file_exists() so that you can tell you're opening the correct file.

$extension = "mp3";
$mime_type = "audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3";

if(file_exists($file_name)){
    header('Content-type: ' . $mime_type);
    header('Content-length: ' . filesize($file_name));
    header('Content-Disposition: filename="' . $file_name);
    header('X-Pad: avoid browser bug');
    header('Cache-Control: no-cache');
    readfile($file_name);
}

Reference

于 2012-07-05T08:18:13.820 回答