我正在使用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秒。玩家被困在“准备”状态(不是缓冲,到目前为止我看到了这一点)。
修改
流的格式是AAC
修改
我测试了https://code.google.com/p/aacdecoder-android/,但这个库唯一的问题是缺乏对流暂停的支持。我的应用程序要求支持在线流的暂停。
答案 0 :(得分:8)
如果您的用例与GPL / LGPL许可证兼容,那么VLC应该是您所需要的。 VLC能够在3G网络上从您的URL流式传输,延迟时间仅为1秒。
第1步: 下载VLC源代码并根据instruction
进行编译 第2步:
最重要的课程是org.videolan.vlc.audio.AudioServiceController
,来自org.videolan.vlc.gui.MRLPanelFragement.processUri() --> org.videolan.vlc.util.Util.openStream(Context, String) --> AudioServiceController.load(String, boolean)
。除了AudioServiceController
及其支持类之外,您可以删除所有不必要的代码以缩小尺寸
答案 1 :(得分:2)
我可以建议从MediaPlayer切换到ExoPlayer。使用ExoPlayer可以设置缓冲参数如下:
public static ExoPlayer newInstance(int rendererCount, int minBufferMs, int minRebufferMs) {
return new ExoPlayerImpl(rendererCount, minBufferMs, minRebufferMs);
}
minBufferMS 表示必须缓冲的最小数据持续时间,以便在用户操作(如搜索)后开始或恢复播放。
minRebufferMs表示必须缓冲的数据的最小持续时间,以便在播放器调用rebuffer后重放缓存(即由于缓冲区耗尽而不是由于用户操作(如开始播放或搜索)而发生的缓冲区。)< / p>
默认值分别为500和5000.
答案 2 :(得分:1)
您应该避免使用媒体播放器播放实时广播流。
我使用了以下库,效果很好:https://code.google.com/p/aacdecoder-android/
答案 3 :(得分:0)
流式传输有两种延迟。是缓冲延迟,它是启动延迟和b。是广播延迟。
对于媒体播放器,流需要1分钟才能缓冲。因此,我们首先需要了解如何减少填充缓冲区所需的时间。我不确定在Android的媒体播放器代码中是否可以配置缓冲区大小。
但是如果我们尝试将AAC解码器库用于android(https://code.google.com/p/aacdecoder-android/downloads/detail?name=aacdecoder- android-0.8.zip),那么我们就可以填充输入缓冲区了。
PL。请参阅下面的代码片段,您可以根据您的要求填充输入缓冲区容量,然后就可以开始播放了。由于我们可以控制输入缓冲器容量,因此我们可以尝试减少开始播放的时间延迟。 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;
}
答案 4 :(得分:0)
我将发布我是如何做到这一点的并且锄头给出了不同。它不是一个实时声音项目(它是来自在线api的mp3,但它大约是4-6mb)所以它可能会有所不同,但加载我的genimotion虚拟机需要不到3-5秒。
我知道它和你的代码几乎一样。也许如果你可以分享网址或类似问题,我可以在我的应用程序中测试它。
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上进行测试,时间响应相似。
答案 5 :(得分:0)