在使用 Android 2.2 的 HTC Desire 上使用 Android MediaPlayer 进行流式传输时的奇怪行为

Posted

技术标签:

【中文标题】在使用 Android 2.2 的 HTC Desire 上使用 Android MediaPlayer 进行流式传输时的奇怪行为【英文标题】:Weird behavior when streaming using Android MediaPlayer on HTC Desire with Android 2.2 【发布时间】:2011-08-08 08:12:50 【问题描述】:

在我的一个项目中,我正在使用无休止的流实现直播电台。我可以毫无问题地使用 nativ android MediaPlayer,也可以在运行旧版本 Android 的设备上使用,因为流的类型是音频/mpeg。我已经在运行 1.6 的 HTC Magic 上对此进行了测试,它完美无瑕。即使在 WLAN 和 3G 之间切换时,它也只是缓冲,我只注意到一个小问题,然后它继续播放,好像什么都没发生一样。它也很少断开连接,因为我在工作日以及上下班途中一直在收听广播,以确保用户体验完全符合我的要求。我对运行 Android 2.1 的 HTC Legend、运行 2.2 的 HTC Wildfire 和运行 2.2 的三星 Galaxy Tab 等其他设备重复了相同的程序,结果相同。所有设备都能完美处理流。

但是,这就是我卡住的地方,在运行 2.2 的 HTC Desire 上,我在播放流时遇到了严重的问题。当使用 MediaPlayer 的标准实现时,即 setDataSource(String path),它会播放 10 - 30 秒,然后即使我在 WLAN 和 3G 上都完全接收,它也会失去连接。我尝试了不同的方法来解决这个问题,一种是使用NPR News 项目的StreamProxy,经过一些修改后实际上效果很好。然而,HTC Desire 仍然会时不时地断开连接,并且在某些情况下会尝试重新连接 4 到 5 次,直到它真正成功地保持稳定的连接。

我在使用代理时遇到的错误如下所示

08-08 09:35:17.810: ERROR/AwesomePlayer(67): Not sending buffering status because duration is unknown.
08-08 09:35:19.849: ERROR/HTTPStream(67): recv failed, errno = 11 (Try again)
08-08 09:35:19.849: INFO/HTTPDataSource(67): Retry ... 2 times left
08-08 09:35:19.849: WARN/HTTPStream(67): Calling connect()...
08-08 09:35:19.849: WARN/HTTPStream(67): Returned from connect()...
08-08 09:35:20.739: ERROR/(1576): Broken pipe
08-08 09:35:20.739: ERROR/(1576): java.net.SocketException: Broken pipe
08-08 09:35:20.739: ERROR/(1576):     at org.apache.harmony.luni.platform.OSNetworkSystem.writeSocketImpl(Native Method)
08-08 09:35:20.739: ERROR/(1576):     at org.apache.harmony.luni.platform.OSNetworkSystem.write(OSNetworkSystem.java:723)
08-08 09:35:20.739: ERROR/(1576):     at org.apache.harmony.luni.net.PlainSocketImpl.write(PlainSocketImpl.java:578)
08-08 09:35:20.739: ERROR/(1576):     at org.apache.harmony.luni.net.SocketOutputStream.write(SocketOutputStream.java:59)
08-08 09:35:20.739: ERROR/(1576):     at org.jmvo.radio.StreamProxy.processRequest(StreamProxy.java:263)
08-08 09:35:20.739: ERROR/(1576):     at org.jmvo.radio.StreamProxy.run(StreamProxy.java:138)
08-08 09:35:20.739: ERROR/(1576):     at java.lang.Thread.run(Thread.java:1102)

当直接使用 MediaPlayer 而不使用代理时

08-08 09:41:30.799: ERROR/AwesomePlayer(67): Not sending buffering status because duration is unknown.
08-08 09:41:32.849: ERROR/HTTPStream(67): recv failed, errno = 11 (Try again)
08-08 09:41:32.849: INFO/HTTPDataSource(67): Retry ... 2 times left
08-08 09:41:32.849: WARN/HTTPStream(67): Calling connect()...
08-08 09:41:32.870: WARN/HTTPStream(67): Returned from connect()...
08-08 09:41:33.160: INFO/HTTPDataSource(67): retrying connection succeeded.
08-08 09:41:34.839: VERBOSE/CacheingDataSource(67): partial readAt CachingDataSource::readAt(260221, 418):mSource->readAt(page<0xd0ff0>->mOffset 260416, mPageSize 1728)
08-08 09:41:36.839: ERROR/HTTPStream(67): recv failed, errno = 11 (Try again)
08-08 09:41:36.839: INFO/HTTPDataSource(67): Retry ... 1 times left
08-08 09:41:36.839: WARN/HTTPStream(67): Calling connect()...
08-08 09:41:36.859: WARN/HTTPStream(67): Returned from connect()...
08-08 09:41:37.361: INFO/HTTPDataSource(67): retrying connection succeeded.

还有一件事。为了让 NPR News 的 StreamProxy 能够正常工作,我必须修改以下几行

byte[] buff = new byte[1024 * 50];
while (isRunning && (readBytes = data.read(buff, 0, buff.length)) != -1) 
    client.getOutputStream().write(buff, 0, readBytes);

以这种方式使用它会导致流每 10 到 30 秒断开一次连接。但是,当我将缓冲区大小降低到 4 个字节甚至 1 个字节时,它的播放效果非常好,尽管在使用 3G 时经常会出现打嗝并且重新连接时会出现问题。

所以我的问题是,有人知道 HTC Desires 底层软件的交易是什么吗?我的意思是,它在运行相同版本操作系统的 HTC Wildfire 上完美运行。两个设备的软件应该没有太大区别吧?我还在多个 HTC Desires 上测试了这个应用程序,以确保它不仅仅是我的测试设备出了问题。但是在其他设备上也出现了与我的测试设备上相同的问题。

有什么想法吗?

【问题讨论】:

我有一个类似的项目,但目前我只使用来自 v2.2 的默认缓冲和 MediaPlayer。这不是您的意图,但您的帖子有助于证明使用 StreamProxy 是值得的。此外,您关于更改缓冲区大小的注释让我想到这里发生了什么。似乎 MediaPlayer-default 和 StreamProxy-default 都使用了太大的缓冲区并导致块出现问题。 ***.com/questions/8671479/… 【参考方案1】:

问题是不直接支持内容类型“audio/aacp”流。可以使用某些解码库来播放“aacp”,请看下面的解决方案:

Freeware Advanced Audio (AAC) Decoder for Android

How to use this library?

Consider legal issues while using it.

项目http://code.google.com/p/aacplayer-android/已授权 在 GPL 下,因此您可以在其之上创建商业应用程序 *,但是您 需要完成 GPL - 主要意味着将您的代码发布为 好。 * 如果你使用第二个项目 http://code.google.com/p/aacdecoder-android/ ,那么你不需要 发布您的 * 代码(该库在 LGPL 下获得许可)。

详情见this。

【讨论】:

【参考方案2】:

在 Android 2.2 中忘记流式传输。除了 Flash 流之外,它的效果并不好。

【讨论】:

以上是关于在使用 Android 2.2 的 HTC Desire 上使用 Android MediaPlayer 进行流式传输时的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

适用于 HTC One 手机的 Sencha Touch 2.X 解决方法

Android 5(HTC) EACCES(权限被拒绝)

错误:Android HTC 设备中的“所选设备不兼容”

Android HTC Flyer - 使用 MotionEvents 捕捉触控笔

HTC Thunderbolt 上的 Android 电子邮件多个附件问题

即使已连接,也看不到我的 Android HTC