我有一个node.js服务器转换和流式播放mp3。 我正在使用HTML5音频标签来使用这个流,我遇到的问题是音频元素不知道mp3的持续时间,直到它完成播放整个事情(显然)。 有没有办法,因为我的服务器在发送之前知道mp3的持续时间,我可以在服务器的响应标题中包含持续时间,所以消费它的客户知道持续时间?
由于
答案 0 :(得分:4)
一岁半,但我上周刚刚遇到这个......
为您的http服务器实现添加 206部分内容支持,这个问题就消失了。在内容中寻找也开始工作..
音频和视频html5代码正在制作范围请求:
Range: bytes=0- or..
Range: bytes=0-12345
来自spec的正确回复的重要部分:
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;
当然,您必须通过为请求的内容提供适当的字节范围来兑现请求 客户端通常也会“停止”下载以匹配播放速度,因此适当的事件驱动服务器(如Mojolicious,AnyEvent或Node.js)将缩放,而每个连接模型为1个线程比如PHP没有。 (好吧,我认为Ratchet会有一些黑客行为,或使用Xsendfile)
顺便提一下,大多数范围请求最终只是:
Range: bytes=0-
只要他们不能寻找并且禁用缓存(并且浏览器实际上是为了尊重它......),那么转换为实际上只需重写正常的标题< em> HTTP / 1.1 200 响应 HTTP / 1.1 206 响应的重要位,它适用于某些内容。具体来说,这似乎适用于在文件的 end 处没有所需元数据的内容。对于那些文件类型,我已经看到范围请求寻找到最后,然后在文件的开头重新启动。 出于这个原因,最好只是实施实际的搜索,但上面确实有效...使用你自己的危险。
答案 1 :(得分:2)
我认为就目前而言,就广泛支持的解决方案而言,您无法通过单独的请求(或者在某种类型的链接清单中发送内容) - 包含在您使用的播放列表中例如,指向适当的URI。当然,这可以由您的服务器动态地在首次添加歌曲时生成,然后从那时开始静态地提供。
在我正在构建的媒体播放器中,我正在做类似的事情 - 下载一个json文件,其中包含通常在.mp3元数据中的内容(这也将支持非mp3版本,等等) )。
这远非理想,但同样是html5音频/视频在第一次迭代中无法解决的问题之一。
答案 2 :(得分:0)
看看这里: Similar question
我认为这就是你要找的东西。