Android MediaPlayer在网络变化时停止流媒体播放

16

我正在使用Android上的MediaPlayer流式传输音频。

当设备从Wi-Fi切换到蜂窝网络或反之亦然时,MediaPlayer会停止播放。

通常缓冲区中有几秒钟的音频,所以播放不会立即停止。

理想情况下,我希望能够继续播放流以实现不间断播放,但我不知道该如何实现。

我同时处理托管在服务器上的mp3文件和实时广播流。


如果您需要使用MediaPlayer进行帮助,侧边栏中有很多示例,但它非常简单:MediaPlayer mMediaPlayer = MediaPlayer.create(context, Uri.parse(url));mMediaPlayer.prepare();mMediaPlayer.start();这将让您开始。如果您连接到Wi-Fi并具有3G覆盖范围,请在流式传输时关闭Wi-Fi,播放将停止。 - lightversusdark
2
是的,我知道如何使用媒体播放器。我只是想问一下你是否在这方面尝试了什么并且想要分享你的进展,以便我们可以在这方面进行改进。 - Erol
你能和我们分享一个示例网址吗?它是否包含文件指针,在连接丢失/恢复后可以恢复流? - Vidar Vestnes
1
baba和Vidar所说的是,“你尝试过什么?”(http://whathaveyoutried.com) - Justin ᚅᚔᚈᚄᚒᚔ
4个回答

14

从服务器的角度来看,将网络模式从WiFi切换到3G(反之亦然),将看起来像是来自不同IP的新连接。

如果您正在下载的服务器不支持跟踪流(例如秒数、序列、字节)(如媒体服务器),它将不得不从0字节开始重新为您提供mp3。

如果您的URL指向位于标准HTTP服务器上的MP3文件,则您的情况将符合预期。 您应该考虑使用媒体流服务器,以便您可以在选择时恢复下载/流式传输。 当您收到连接丢失/恢复的意图时,您可以将mediaplayer指向具有URL中的文件位置的新URL(例如seconds = 19,bytes = 57365)。

不确定这是否对您有所帮助,但它解释了一些“幕后”发生的事情。


1

尝试设置您的setOnCompletionListenersetOnErrorListener。在使用实时流的on complete中,您可以再次调用prepareAsync(),这将重新启动流。除非编写自己的媒体框架,否则没有优雅的方法来实现这一点。

您还可以在onError()中监听MEDIA_ERROR_SERVER_DIED,然后再次触发prepareAsync()

您会发现MediaPlayer要么出错要么完成。如果您处理这两个回调,最起码可以在网络更改时重新启动流,至于平稳播放...那需要自定义媒体框架,因为Android的媒体框架相当糟糕。


0

我不知道为什么你的媒体播放器会停止,但也许你可以添加一个onReceive方法,并在该方法中加入"mp.start()"来重新开始播放。
Android, 如何在轮询数据时处理网络变化(从GPRS到Wi-Fi和反之)

你可能需要创建一个单独的类,但这应该解释了如何创建一个在切换网络时调用的方法,在此时你可以调用"mp.start()"来恢复播放(假设mp是你的MediaPlayer)。
当然,这假定你的MediaPlayer只是在切换网络时被暂停,而不是停止。


0

正如Vidar所说,重新建立连接将被服务器视为新连接。

看来我必须双缓冲音频播放,这意味着要构建一个自定义媒体播放器。这可以提供连续的音频,但在听取实时流时仍会跳过。

MP3文件稍微容易一些,因为我可以知道播放位置。但是实时流不行。

正如gmaster所说,当网络发生变化时,我需要一个广播接收器来建立新连接。前一个网络连接的音频缓冲应该继续播放,同时通过新连接填充新的音频缓冲。

当新缓冲区足够满时开始播放,我可以切换到它进行播放。如果我正在流式传输文件,并且有服务器支持和一点工作,我可以确保当前播放位置数据在两个缓冲区中,并无缝切换。

由于实时流缓冲区无法同步,它们切换时必然会出现故障。

更大的缓冲区将避免音频中断,如果连接需要一段时间才能建立,但会延迟播放的第一次启动。 MP3文件可以下载并以比实时更快的速度填充缓冲区,但实时流将实时缓冲。

Chris.Jenkins提到了一些可以帮助的MediaPlayer方法,但指出这似乎需要一个自定义框架。它将需要处理他提到的条件和其他条件。

如果我能让它看起来漂亮,我会在这里发布它。我将保持问题开放。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接