SDK 级别 8 (Froyo) 引入了 MediaPlayer 连接到流媒体源(如 Shoutcast)的 native 功能。以前的 SDK 版本能够解决问题,例如在设备上运行本地代理(请参阅 NPR)。
我采用与 NPR 相同的方法并使用 StreamProxy。但是,NPR 首先检查当前运行的 SDK 是否小于 8。如果是,则使用代理。否则,它直接连接。
My StreamProxy 从 Shoutcast 服务器请求元数据,因此它不会简单地将数据从 Shoutcast 路由到我的客户端。相反,它解析出元数据并相应地使用它,并且只路由音乐数据。
尝试在 SDK 级别 8 或更高级别使用 StreamProxy 时,MediaPlayer 无法准备。我的 StreamProxy 收到连接并接受它,但在成功将状态行和 header 写入客户端后,下一次写入会产生 java.net.SocketException: Connection reset by peer
。这会导致客户端的媒体播放器抛出一个 Error(1,-1007)
。
我想弄清楚为什么 MediaPlayer 无法连接到我的本地代理。它应该与在没有元数据的情况下连接到原始源相同,这确实有效。我正在通过我的代理转发来自外部源的所有 header ,其中包括内容类型。
我会继续研究它,但我觉得我已经走到了死胡同。如果需要更多详细信息,请告诉我。
最佳答案
编辑:好的,我现在相信我有答案了!
Stagefright 对 HTTP header 中的行结尾非常严格;它们必须是 CR、LF,而不仅仅是之前工作过的 LF。
因此,如果您构建自己的 header ,请将所有 "\n" 替换为 "\r\n",您应该没问题。
(如果您想自己检查一下,请查看 media/libstagefright/HTTPStream.cpp 中的 receive_line())
我现在可以在 2.2/Stagefright 手机上流式传输带有元数据的 shoutcast...
...
我遇到了同样的问题;
首先,我尝试将流式数据写入固定长度的文件并包装 - 然后使用 setLooping(true) 播放它。这会导致 MP3 循环时出现故障,即使我提取了整个 MP3 帧并尝试用 0xff 和 0x00 填充末尾的不均匀字节。如果您有足够大的文件,这可能仍然是一个可接受的解决方案。
然后我做了在我的 Samsung Galaxy S (v2.2) 上运行但在模拟器上不起作用并且显然在 Desire 上不起作用的代理操作(不工作 = 错误 -1007,如上所述)。 一个提示可能是 Galaxy S Mediaplayer 要求 HTTP1.0,而它在模拟器中是 1.1。
蛮力方法是并行打开 2 个流,从一个流中读取元数据并从另一个流中读取元数据;)
不管怎样,我也想听听有没有人有比我更幸运的...
关于android - 在 SDK 8 中使用 Android MediaPlayer 进行流式传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4209382/