我正在使用Android上的MediaPlayer流式传输音频。
当设备从Wi-Fi切换到蜂窝网络或反之亦然时,MediaPlayer会停止播放。
通常缓冲区中有几秒钟的音频,所以播放不会立即停止。
理想情况下,我希望能够继续播放流以实现不间断播放,但我不知道该如何实现。
我同时处理托管在服务器上的mp3文件和实时广播流。
我正在使用Android上的MediaPlayer流式传输音频。
当设备从Wi-Fi切换到蜂窝网络或反之亦然时,MediaPlayer会停止播放。
通常缓冲区中有几秒钟的音频,所以播放不会立即停止。
理想情况下,我希望能够继续播放流以实现不间断播放,但我不知道该如何实现。
我同时处理托管在服务器上的mp3文件和实时广播流。
从服务器的角度来看,将网络模式从WiFi切换到3G(反之亦然),将看起来像是来自不同IP的新连接。
如果您正在下载的服务器不支持跟踪流(例如秒数、序列、字节)(如媒体服务器),它将不得不从0字节开始重新为您提供mp3。
如果您的URL指向位于标准HTTP服务器上的MP3文件,则您的情况将符合预期。 您应该考虑使用媒体流服务器,以便您可以在选择时恢复下载/流式传输。 当您收到连接丢失/恢复的意图时,您可以将mediaplayer指向具有URL中的文件位置的新URL(例如seconds = 19,bytes = 57365)。
不确定这是否对您有所帮助,但它解释了一些“幕后”发生的事情。
尝试设置您的setOnCompletionListener
和setOnErrorListener
。在使用实时流的on complete中,您可以再次调用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方法,但指出这似乎需要一个自定义框架。它将需要处理他提到的条件和其他条件。
如果我能让它看起来漂亮,我会在这里发布它。我将保持问题开放。
MediaPlayer mMediaPlayer = MediaPlayer.create(context, Uri.parse(url));
mMediaPlayer.prepare();
mMediaPlayer.start();
这将让您开始。如果您连接到Wi-Fi并具有3G覆盖范围,请在流式传输时关闭Wi-Fi,播放将停止。 - lightversusdark