使用PHP在浏览器中播放AIFF文件的正确HTTP标头

时间:2016-11-07 16:13:20

标签: php audio http-headers aiff

我试图将一些AIFF音频文件放在PHP网站的登录墙后面(即不在网络根目录下)。第一个挑战是所有浏览器都不支持AIFF,但是预期 - 请参阅http://www.jplayer.org/HTML5.Audio.Support/目前我使用Safari进行测试,因为它支持AIFF。

我无法弄清楚为什么Safari会以不同方式处理同一文件的2个版本。对于直接文件,它会提示播放器并且它可以正常工作。对于流式文件,播放器无法正常工作。

定期下载

以下是我直接下载文件时的标题(例如,如果我暂时将文件放入web根目录进行测试):

curl -v http://audio.app/Morse.aiff -o /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 192.168.10.10...
* Connected to audio.app (192.168.10.10) port 80 (#0)
> GET /Morse.aiff HTTP/1.1
> Host: audio.app
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.8.0
< Date: Sun, 06 Nov 2016 03:19:03 GMT
< Content-Type: application/octet-stream
< Content-Length: 55530
< Last-Modified: Sat, 05 Nov 2016 21:51:02 GMT
< Connection: keep-alive
< ETag: "581e5446-d8ea"
< Accept-Ranges: bytes
<
{ [5537 bytes data]
100 55530  100 55530    0     0  8991k      0 --:--:-- --:--:-- --:--:-- 10.5M
* Connection #0 to host audio.app left intact

通过PHP

以下是我通过PHP脚本(名为source.php)传输文件时的标题:

curl -v http://audio.app/source.php?file=Morse.aiff -o /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 192.168.10.10...
* Connected to audio.app (192.168.10.10) port 80 (#0)
> GET /source.php?file=Morse.aiff HTTP/1.1
> Host: audio.app
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.8.0
< Date: Sun, 06 Nov 2016 03:36:46 GMT
< Content-Type: application/octet-stream
< Content-Length: 55530
< Connection: keep-alive
< Last-Modified: Sat, 05 Nov 2016 21:51:02 GMT
< ETag: "581e5446T-d8eaO"
< Accept-Ranges: bytes
<
{ [8431 bytes data]
100 55530  100 55530    0     0  4915k      0 --:--:-- --:--:-- --:--:-- 5422k
* Connection #0 to host audio.app left intact

标题几乎完全相同 - 我能说出的唯一区别是它们的顺序以及我的本地开发框用于ETag值的散列算法。

以下是我用来流式传输相同文件(位于webroot上方)的测试PHP脚本(名为source.php):

// Adapted from http://php.net/manual/en/function.readfile.php
$filename = (isset($_GET['file'])) ? $_GET['file'] : null;
// <do sanitization here>
$file = dirname(dirname(__FILE__)).'/audio/' . $filename;

// Mimicking AIFF headers from curl headers (does not work!)
$content_length = filesize($file);
$last_modified = date("D, d M Y H:i:s", filemtime($filename)). ' GMT';
header("HTTP/1.1 200 OK");
header("Content-type: application/octet-stream");
header('Content-Length: ' . $content_length);
header('Last-Modified: ' .$last_modified);
// attempts to do the same thing as NGINX... md5_file() would probably work
$etag = sprintf("\"%xT-%xO\"", filemtime($filename), $content_length);
header("ETag: $etag"); // quoting it exactly
header("Accept-Ranges: bytes");

// Output the file
readfile($file);

预期的行为是浏览器会将两个版本视为相同。在我的示例HTML页面(改编自http://www.w3schools.com/html/html5_audio.asp)中,只有直接下载有效 - 通过PHP发送的文件版本无法播放。当我直接在浏览器中同时点击两个文件时,会发生相同的行为。

<!DOCTYPE html>
<html>
<body>
<h2>From Stream</h2>
<audio controls>
  <source src="/source.php?file=Morse.aiff&breakcache=<?php print uniqid(); ?>" type="audio/x-aiff">
    Your browser does not support the audio element.
</audio>
<hr/>
<h2>Direct Downloads</h2>
<audio controls>
  <source src="/Morse.aiff" type="audio/x-aiff">
  Your browser does not support the audio element.
</audio>
</body>
</html>

同样的方法可以播放mp3(但标题略有不同)。有谁知道我在这里做错了什么,或者有谁知道为什么这种方法不适用于AIFF?我还没有尝试使用另一种服务器端语言进行同样的测试,但我怀疑这不是一个PHP问题,并且有一些关于AIFF的事情。有人能说清楚这个吗?

0 个答案:

没有答案