流式传输音频时 MediaPlayer 缓冲时间问题
Issue with MediaPlayer buffering time when streaming audio
我正在使用 MediaPlayer
通过 HTTP 传输广播。在 Lollipop 上,我的流需要大约一分钟才能开始,这是不可接受的。在 Kitkat 上大概需要 20 秒,这本来就很痛苦,但现在变得无法使用了。
此组件有一个 well known problem 与缓冲相关:要缓冲的字节数已硬编码且无法更改。
我的代码真的很标准
player.reset();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(streamUrl);
player.prepareAsync();
我准备好了
player.start();
我听说过 GStreamer
的替代方案,但我无法在 Windows 上使用它。
我想知道是否有人有一个有效的解决方案来通过 HTTP 流式传输广播,并具有适当的启动延迟。
编辑
我测试了 ExoPlayer,但我得到的较低启动时间是 15 秒。播放器卡在 "preparing" 状态(没有缓冲,到目前为止我才看到)。
编辑
流的格式是 AAC
编辑
我测试了 https://code.google.com/p/aacdecoder-android/ 但这个库唯一的问题是不支持流暂停。我的应用程序要求支持在线流暂停。
我可以建议从 MediaPlayer 切换到 ExoPlayer。使用 ExoPlayer 可以设置缓冲参数如下:
public static ExoPlayer newInstance(int rendererCount, int minBufferMs, int minRebufferMs) {
return new ExoPlayerImpl(rendererCount, minBufferMs, minRebufferMs);
}
minBufferMS 表示必须缓冲的最短数据持续时间,以便在用户操作(例如搜索)后开始或恢复播放。
minRebufferMs 表示播放器调用 rebuffer 后必须缓冲以恢复播放的最短数据持续时间(即由于缓冲区耗尽而不是由于用户操作(例如开始播放或搜索)而发生的重新缓冲) .
默认值分别为 500 和 5000。
如果您的用例与 GPL/LGPL 许可证兼容,那么 VLC 应该正是您所需要的。 VLC 能够在 3G 网络上从您的 URL 流式传输,延迟仅约 1 秒。
第 1 步:
下载 VLC 源代码并根据 instruction
编译
第 2 步:
最重要的 class 是 org.videolan.vlc.audio.AudioServiceController
,它是从 org.videolan.vlc.gui.MRLPanelFragement.processUri() --> org.videolan.vlc.util.Util.openStream(Context, String) --> AudioServiceController.load(String, boolean)
调用的。您可以删除除 AudioServiceController
及其支持 class 之外的所有不必要的代码以缩小尺寸
您应该避免使用媒体播放器播放直播广播。
我使用了以下库并且效果很好:https://code.google.com/p/aacdecoder-android/
推流有2种延迟a。是缓冲延迟,它是启动延迟和 b。是广播延迟。
对于媒体播放器,流缓冲需要 1 分钟。所以我们首先需要看看如何减少填充缓冲区所花费的时间。我不确定 Android 的媒体播放器代码是否可以配置缓冲区大小。
然而,如果我们尝试为 android (https://code.google.com/p/aacdecoder-android/downloads/detail?name=aacdecoder- android-0.8.zip) 使用 AAC 解码器库,那么我们就可以填充输入缓冲区.
请问。参考下面的代码片段,你可以根据你的要求填充你的输入缓冲区容量,然后你就可以开始播放了。由于我们可以控制输入缓冲区容量,因此我们可以尝试减少开始播放的时间延迟。 PL。检查这是否可以帮助你。
/**
* Sets the audio buffer (AudioTrack) capacity.
* The capacity can be expressed in time of audio playing of such buffer.
* For example 1 second buffer capacity is 88100 samples for 44kHz stereo.
* By setting this the audio will start playing after the audio buffer
is first filled.
*
* NOTE: this should be set BEFORE any of the play methods are called.
*
* @param audioBufferCapacityMs the capacity of the buffer in milliseconds
*/
public void setAudioBufferCapacityMs( int audioBufferCapacityMs ) {
this.audioBufferCapacityMs = audioBufferCapacityMs;
}
我会 post 我是怎么做到的,并且会有所不同。它不是实时声音项目(它是来自在线 api 的 mp3,但大约 4-6mb)所以它可能会有所不同,但加载到我的 genimotion VM 上只需不到 3-5 秒。
我知道它和你的代码几乎一样。也许如果你可以分享 url 或类似的问题,我可以在我的应用程序中测试它。
runThread(url);//ran on the oncreate.
private void runThread(final String url) {
new Thread() {
public void run() {
mediaPlayer = new MediaPlayer();//mediaplayer is a global variable.
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try{
mediaPlayer.setDataSource(url);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
//audio did finish.
}
});
mediaPlayer.prepare(); // might take long! (for buffering, etc)
duration = mediaPlayer.getDuration();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//here you should start playing it.
}
});
}
});
}
catch(Exception e)
{
}
}
}.start();
}
在带果冻豆的 nexus 4 上测试,时间响应相似。
如果您愿意花一些钱买一个库,我推荐 Bass 它有一套完整的 API 可以集成的调用,还有可靠的文档。有一个共享软件版本,你可以测试。
如果你不愿意花$.我强烈推荐 @Kai 提到的 VLC,将来您也可以扩展您的应用程序以使用它流式传输视频。我之前与 API 合作,为我的水族馆进行现场直播。 @Kai 为您提供了必要的链接。
查看此 link 了解更多信息。
我正在使用 MediaPlayer
通过 HTTP 传输广播。在 Lollipop 上,我的流需要大约一分钟才能开始,这是不可接受的。在 Kitkat 上大概需要 20 秒,这本来就很痛苦,但现在变得无法使用了。
此组件有一个 well known problem 与缓冲相关:要缓冲的字节数已硬编码且无法更改。
我的代码真的很标准
player.reset();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(streamUrl);
player.prepareAsync();
我准备好了
player.start();
我听说过 GStreamer
的替代方案,但我无法在 Windows 上使用它。
我想知道是否有人有一个有效的解决方案来通过 HTTP 流式传输广播,并具有适当的启动延迟。
编辑
我测试了 ExoPlayer,但我得到的较低启动时间是 15 秒。播放器卡在 "preparing" 状态(没有缓冲,到目前为止我才看到)。
编辑
流的格式是 AAC
编辑
我测试了 https://code.google.com/p/aacdecoder-android/ 但这个库唯一的问题是不支持流暂停。我的应用程序要求支持在线流暂停。
我可以建议从 MediaPlayer 切换到 ExoPlayer。使用 ExoPlayer 可以设置缓冲参数如下:
public static ExoPlayer newInstance(int rendererCount, int minBufferMs, int minRebufferMs) {
return new ExoPlayerImpl(rendererCount, minBufferMs, minRebufferMs);
}
minBufferMS 表示必须缓冲的最短数据持续时间,以便在用户操作(例如搜索)后开始或恢复播放。
minRebufferMs 表示播放器调用 rebuffer 后必须缓冲以恢复播放的最短数据持续时间(即由于缓冲区耗尽而不是由于用户操作(例如开始播放或搜索)而发生的重新缓冲) .
默认值分别为 500 和 5000。
如果您的用例与 GPL/LGPL 许可证兼容,那么 VLC 应该正是您所需要的。 VLC 能够在 3G 网络上从您的 URL 流式传输,延迟仅约 1 秒。
第 1 步: 下载 VLC 源代码并根据 instruction
编译第 2 步:
最重要的 class 是 org.videolan.vlc.audio.AudioServiceController
,它是从 org.videolan.vlc.gui.MRLPanelFragement.processUri() --> org.videolan.vlc.util.Util.openStream(Context, String) --> AudioServiceController.load(String, boolean)
调用的。您可以删除除 AudioServiceController
及其支持 class 之外的所有不必要的代码以缩小尺寸
您应该避免使用媒体播放器播放直播广播。
我使用了以下库并且效果很好:https://code.google.com/p/aacdecoder-android/
推流有2种延迟a。是缓冲延迟,它是启动延迟和 b。是广播延迟。
对于媒体播放器,流缓冲需要 1 分钟。所以我们首先需要看看如何减少填充缓冲区所花费的时间。我不确定 Android 的媒体播放器代码是否可以配置缓冲区大小。
然而,如果我们尝试为 android (https://code.google.com/p/aacdecoder-android/downloads/detail?name=aacdecoder- android-0.8.zip) 使用 AAC 解码器库,那么我们就可以填充输入缓冲区.
请问。参考下面的代码片段,你可以根据你的要求填充你的输入缓冲区容量,然后你就可以开始播放了。由于我们可以控制输入缓冲区容量,因此我们可以尝试减少开始播放的时间延迟。 PL。检查这是否可以帮助你。
/**
* Sets the audio buffer (AudioTrack) capacity.
* The capacity can be expressed in time of audio playing of such buffer.
* For example 1 second buffer capacity is 88100 samples for 44kHz stereo.
* By setting this the audio will start playing after the audio buffer
is first filled.
*
* NOTE: this should be set BEFORE any of the play methods are called.
*
* @param audioBufferCapacityMs the capacity of the buffer in milliseconds
*/
public void setAudioBufferCapacityMs( int audioBufferCapacityMs ) {
this.audioBufferCapacityMs = audioBufferCapacityMs;
}
我会 post 我是怎么做到的,并且会有所不同。它不是实时声音项目(它是来自在线 api 的 mp3,但大约 4-6mb)所以它可能会有所不同,但加载到我的 genimotion VM 上只需不到 3-5 秒。
我知道它和你的代码几乎一样。也许如果你可以分享 url 或类似的问题,我可以在我的应用程序中测试它。
runThread(url);//ran on the oncreate.
private void runThread(final String url) {
new Thread() {
public void run() {
mediaPlayer = new MediaPlayer();//mediaplayer is a global variable.
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try{
mediaPlayer.setDataSource(url);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
//audio did finish.
}
});
mediaPlayer.prepare(); // might take long! (for buffering, etc)
duration = mediaPlayer.getDuration();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//here you should start playing it.
}
});
}
});
}
catch(Exception e)
{
}
}
}.start();
}
在带果冻豆的 nexus 4 上测试,时间响应相似。
如果您愿意花一些钱买一个库,我推荐 Bass 它有一套完整的 API 可以集成的调用,还有可靠的文档。有一个共享软件版本,你可以测试。
如果你不愿意花$.我强烈推荐 @Kai 提到的 VLC,将来您也可以扩展您的应用程序以使用它流式传输视频。我之前与 API 合作,为我的水族馆进行现场直播。 @Kai 为您提供了必要的链接。
查看此 link 了解更多信息。