6

我有一个 node.js 服务器即时转换和流式传输 mp3。我正在使用 HTML5 音频标签来使用此流,而我遇到的问题是音频元素在播放完整个内容(显然)之前不知道 mp3 的持续时间。有什么办法,因为我的服务器在发送它之前知道 mp3 的持续时间,我可以在来自服务器的响应的标头中包含持续时间或其他东西,所以使用它的客户端知道持续时间?

谢谢

4

2 回答 2

4

一岁半了,但我上周刚遇到这个,所以......

206 Partial Content支持添加到您的 http 服务器实现中,这个问题就消失了。在内容中寻找也开始起作用了..

音频和视频 html5 标签正在发出Range请求:

Range: bytes=0-  or..
Range: bytes=0-12345

规范中正确响应的重要部分:

HTTP/1.1 206 PARTIAL CONTENT
Accept-Ranges: bytes
Content-Range: bytes 0-12345

如果没有 206 响应代码,您将获得您遇到的行为。

我在 Perl 中这样做,其中 $request 包含来自客户端的请求标头,已标准化。例如,SERVER_PROTOCOL 在大多数情况下包含“HTTP/1.1”

my $crlf = "\012";
if ( $request->{RANGE} && $request->{RANGE} =~ /bytes=(\d*)-(.*)$/ ) {
    $offset = $1;
    $end = $2 || $size; # end is optional in the spec.  Default to size.
    $header = $request->{SERVER_PROTOCOL} . ' 206 PARTIAL CONTENT' . $crlf .
    'Content-Range: bytes ' . $offset . '-' . $end . '/' . $size . $crlf;
} else {
    $header = $request->{SERVER_PROTOCOL} . ' 200 OK' . $crlf;
}
my $left = $end - $offset;
$header .= 'Server: ' . $SERVER_NAME . $crlf .
    'Accept-Ranges: bytes' . $crlf . 
    'Date: ' . $http_date . $crlf .
    'Content-Type: ' . ($self->simplemime($raw_path) || magic($fh)) . $crlf .
    'Last-Modified: ' . $http_date . $crlf .
    'Content-Length: ' . $size . $crlf .
    'Connection: Keep-Alive' . $crlf .
    'Cache-Control: max-age=' . $EXPIRE . $crlf . $crlf;

然后,您当然必须通过为请求的内容提供适当的字节范围来满足请求。
客户端通常还会“停止”下载以匹配播放速度,因此适当的事件驱动服务器(例如MojoliciousAnyEvent或 Node.js)可以扩展,而每个连接模型 1 个线程(例如 PHP)则不能。(好吧,我想Ratchet会进行一些黑客攻击,或者使用Xsendfile

顺便说一句,大多数Range 请求最终只是:

Range: bytes=0- 

这意味着只要他们无法搜索并且缓存被禁用(并且浏览器实际上尊重它..),您实际上可以通过将普通HTTP/1.1 200响应的标头重写为重要位HTTP/1.1 206响应,它适用于某些内容。具体来说,这似乎适用于文件末尾没有所需元数据的内容。对于那些文件类型,我已经看到 Range 请求寻求结束,然后在文件开头重新启动。出于这个原因,最好只实现实际的搜索,但上述方法确实有效……使用后果自负。

于 2014-02-26T04:36:00.820 回答
2

我认为就目前而言,就广泛支持的解决方案而言,您无法通过单独的请求(或以其他方式在您的链接的某种清单中发送这些内容 - 包含在您用来指向的播放列表中)例如,适当的 URI)。当然,这可以由您的服务器在首次添加歌曲时动态生成,然后从那时起静态提供。

在我正在构建的媒体播放器中,我正在做类似的事情——下载一个 json 文件,该文件包含通常包含在 .mp3 元数据中的内容(也将支持非 mp3 版本等)。

这远非理想,但这也是 html5 音频/视频在其第一次迭代中不打算解决的问题之一。

于 2012-08-27T04:15:26.330 回答