3

我们有shoutcast/icecast 音频流。我希望能够在我们的网站上提供一个链接,例如 mobiledroid.php,该链接将使用默认播放器打开。我在另一个网站上看到过这个,所以我知道这是可能的。

我假设它通过 php 文件使用 php 标头和流作为流?


使用 Brad 的说明,android 实际上提供了使用声音播放器打开的选项。好一个。

它也可以通过 PC 在 WMP 上播放,但不能在 android 上播放上述链接的播放方式

header("Content-type: audio/mpeg"); 
header("Transfer-Encoding: chunked"); 
header("Connection: close");

$sock = fsockopen($streamname,$port); //$streamname is the IP

fputs($sock, "GET $path HTTP/1.0\r\n"); //path in my case is /;stream.mp3
fputs($sock, "Host: $ip\r\n"); 
fputs($sock, "User-Agent: WinampMPEG/2.8\r\n"); 
fputs($sock, "Accept: */*\r\n"); 
fputs($sock, "Icy-MetaData:1\r\n"); 
fputs($sock, "Connection: close\r\n\r\n"); 


fpassthru($sock); 

fclose($sock);

在android上,它说“对不起,这个播放器不支持这种类型的音频文件”


更新 2:

删除"Transfer-Encoding"将在 android 上播放,但由于直播流没有“Content-Length”,因此像往常一样需要很长时间才能以“Preparing”状态开始流式传输

header("Transfer-Encoding: none");也从上面的代码中删除:

引用布拉德:

Android 2.3 及更高版本存在将 Transfer-Encoding 设置为“none”的问题。删除该硬设置的标头会将流放回分块传输编码。这适用于 Android 2.3+。最初我禁用了分块编码,因为 VLC 不支持它。Android 2.2 及更早版本似乎也不支持分块编码。

请注意,尽管它适用于 android,但大多数直播流需要很长时间才能开始。

4

1 回答 1

5

问题

传统上,您将提供一个播放列表文件,该文件将由您的浏览器保存,然后在任何配置为打开此类播放列表的播放器软件中打开。然后播放器将读取流的 URL,连接到它并开始流式传输。

在 Android 上,他们(出于某种疯狂的原因)选择不支持播放列表文件作为支持的媒体。因此,使用传统方法无法直接启动播放器。

解决方案

在 Android 上,如果您直接链接到 MP3 文件/流,而不是下载文件,默认操作似乎是打开媒体播放器并尝试流式传输。这意味着您可以轻松地直接链接到流的 URL(完全绕过播放列表步骤)。

有一个问题……使用 SHOUTcast 提供的流并不完全符合 HTTP。它们很接近,但并不完美。这里真正的挂断似乎是内容长度之一。通常,HTTP 服务器会发送Content-Length响应标头。对于流媒体,长度是未知的。有两种方法可以解决这个问题:

  1. 使用分块传输编码。您可以通过设置以下标头来做到这一点:
    Transfer-Encoding: chunked
    然后,对流使用分块编码,一切顺利。
  2. 不使用传输编码,并指定在资源传输完成时将关闭连接,并带有以下标头:
    Transfer-Encoding: none
    Connection: close

您的示例链接使用方法一。我也成功地使用了方法二。

一旦您的服务器正在使用有效的 HTTP,在 Android 上播放似乎是一件轻而易举的事。

执行

有几种方法可以实现此修复。您提到了一个 PHP 解决方案。如果 cURL 不起作用,您可以随时fsockopen()stream_socket_client()直接建立 TCP 连接,并自己处理传入的流数据。从那里,您只需发送正确的响应标头并在数据进入时中继数据。请记住,每个连接的客户端都将运行一个 PHP 实例,并且每个实例也会连接到您的服务器。这并不理想,但取决于你有什么可用的,可能是你唯一的方法。

于 2012-07-15T16:08:22.557 回答