我在 Android 上使用 MediaPlayer 流式传输音频。
当设备从 Wi-Fi 移动到蜂窝网络或反之亦然时,MediaPlayer 会停止播放。
通常缓冲区中有几秒钟的音频,因此播放不会立即停止。
理想情况下,我想获取流以进行不间断播放,但我不知道该怎么做。
我正在使用服务器上托管的 mp3 文件和直播流。
我在 Android 上使用 MediaPlayer 流式传输音频。
当设备从 Wi-Fi 移动到蜂窝网络或反之亦然时,MediaPlayer 会停止播放。
通常缓冲区中有几秒钟的音频,因此播放不会立即停止。
理想情况下,我想获取流以进行不间断播放,但我不知道该怎么做。
我正在使用服务器上托管的 mp3 文件和直播流。
从服务器的角度来看,将网络模式从 WiFi 更改为 3G(反之亦然),看起来就像来自单独 IP(客户端)的全新连接。
如果您正在下载的服务器不支持跟踪流(例如秒数、序列、字节)(与媒体服务器不同),它将不得不再次从 0 字节开始提供您的 mp3。
如果您的 URL 指向位于标准 HTTP 服务器上的 MP3 文件,您的情况将是预期的。您应该考虑使用媒体流服务器,以便您可以选择继续下载/流式传输。当您收到连接丢失/恢复的意图时,您可以将您的媒体播放器指向 URL 中带有文件位置的新 URL(例如 seconds=19,bytes=57365)。
不确定这是否对您有所帮助,但它解释了“幕后”发生的事情。
尝试设置你的setOnCompletionListener
和setOnErrorListener
。完成直播后,您只需prepareAsync()
再次拨打电话,这将再次启动直播。除非您编写自己的媒体框架,否则没有真正优雅的方法可以做到这一点。
你也可以听你onError()
的,MEDIA_ERROR_SERVER_DIED
然后你可以再次发射prepareAsync()
。
您会发现 MediaPlayer 将出现错误或完成。如果您处理这两个回调,那么您至少可以在网络更改时重新启动流,以实现流畅播放..这将需要自定义媒体框架,因为 android 非常粗制滥造。
我不知道您的媒体播放器为什么停止,但也许您可以添加一个 onReceive 方法并将“mp.start()”放入该方法中以使其重新开始播放。
Android,如何在轮询数据时处理网络变化(从 GPRS 到 Wi-fi,反之亦然)
您可能需要创建一个单独的类,但这应该解释如何创建一个在切换网络时调用的方法,此时您可以调用“mp.start()”来恢复播放(假设 mp 是您的 MediaPlayer)。
当然,这假设您的 MediaPlayer 仅在您切换网络时才暂停,而不是停止。
正如 Vidar 所说,重新建立连接将被服务器视为新连接。
看来我必须对音频播放进行双重缓冲,这意味着要构建一个自定义媒体播放器。这可以提供连续的音频,但在收听直播时仍会跳过。
MP3 文件更容易一些,因为我可以知道播放位置。直播不是这样。
正如 gmaster 所说,当网络发生变化时,我需要一个广播接收器来建立新的连接。来自先前网络连接的音频缓冲区应继续播放,同时通过新连接填充新的音频缓冲区。
当新缓冲区已满可以开始播放时,我可以将播放切换到它。如果我正在流式传输文件,借助服务器支持和一些工作,我可以确保当前播放位置数据在两个缓冲区中并无缝切换。
由于直播缓冲区无法同步,切换时难免会出现故障。
如果连接需要一段时间才能建立,较大的缓冲区将避免音频丢失,但会延迟第一次开始播放。可以比实时更快地下载 MP3 文件并填充缓冲区,但实时流将实时缓冲。
Chris.Jenkins 提到了一些可以提供帮助的 MediaPlayer 方法,但指出这似乎确实需要一个自定义框架。它将需要处理他提到的条件和其他条件。
如果我能让它看起来很漂亮,我会在这里发布。我将保持问题的开放性。