Android - ICS 4.0 中的 MediaPlayer 缓冲区大小 [英] Android - MediaPlayer Buffer Size in ICS 4.0

查看:36
本文介绍了Android - ICS 4.0 中的 MediaPlayer 缓冲区大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用套接字作为 MediaPlayer 的代理,因此我可以在将其写入套接字之前下载和解密 mp3 音频.这类似于 NPR 新闻应用程序中显示的示例,但是我将它用于所有 Android 版本 2.1 - 4 atm.

I'm using a socket as a proxy to the MediaPlayer so I can download and decrypt mp3 audio before writing it to the socket. This is similar to the example shown in the NPR news app however I'm using this for all Android version 2.1 - 4 atm.

NPR StreamProxy 代码 - http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java

NPR StreamProxy code - http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java

我的问题是 2.1 - 2.3 的播放速度很快,但在 Android 4.0 ICS 中,MediaPlayer 在触发 onPrepared 侦听器之前缓冲了太多数据.

My issue is that playback is fast for 2.1 - 2.3, but in Android 4.0 ICS the MediaPlayer buffers too much data before firing the onPrepared listener.

在 onPrepared() 之前写入 Socket OutputStream 的示例数据量:

An example amount of data written to the Socket OutputStream before onPrepared():

在 2.3.4 的 SGS2 上 - onPrepared() 大约 133920 字节后

On SGS2 with 2.3.4 - onPrepared() after ~ 133920 bytes

在 4.0.4 的 Nexus S 上 - 约 961930 字节后的 onPrepared()

On Nexus S with 4.0.4 - onPrepared() after ~ 961930 bytes

这也发生在 Galaxy Nexus 上.

This also occurs on the Galaxy Nexus.

奇怪的是,4.0 模拟器缓存的数据没有 4.0 设备那么多.有人在使用 ICS 上的 MediaPlayer 时遇到过类似问题吗?

Weirdly the 4.0 emulator doesn't buffer as much data as 4.0 devices. Anyone experience a similar issue with the MediaPlayer on ICS?

编辑

这是代理写入套接字的方式.在此示例中,它来自从文件加载的 CipherInputStream,但从 HttpResponse 加载时也会发生同样的情况.

Here's how the proxy is writing to the socket. In this example it's from a CipherInputStream loaded from a file, but the same occurs when it's loaded from the HttpResponse.

final Socket client = (setup above)

// encrypted file input stream
final CipherInputStream inputStream = getInputStream(file);

// setup the socket output stream
final OutputStream output =  client.getOutputStream();

// Writing the header
final String httpHeader = buildHttpHeader(file.length());
final byte[] buffer = httpHeader.getBytes("UTF-8");
output.write(buffer, 0, buffer.length);

int writtenBytes = 0;
int readBytes;
final byte[] buff = new byte[1024 * 12]; // 12 KB

while (mIsRunning && (readBytes = inputStream.read(buff)) != -1) {
    output.write(buff, 0, readBytes);
    writtenBytes += readBytes;
}

output.flush();
output.close();

在音频之前写入 MediaPlayer 的 HTTP 标头..

The HTTP Headers that are written to the MediaPlayer before the audio..

private String buildHttpHeader(final int contentLength) {
    final StringBuilder sb = new StringBuilder();

    sb.append("HTTP/1.1 200 OK
");
    sb.append("Content-Length: ").append(contentLength).append("
");
    sb.append("Accept-Ranges: bytes
" );
    sb.append("Content-Type: audio/mpeg
");
    sb.append("Connection: close
" );
    sb.append("
");

    return sb.toString();
}

我四处寻找替代实现,但由于我已经加密了音频并且 MediaPlayer 不支持 InputStreams 作为数据源,我唯一的选择(我认为..)是使用这样的代理.

I've looked around for alternate implementations but as I have encrypted audio and the MediaPlayer does not support InputStreams as a data source my only option (I think..) is to use a proxy such as this.

同样,这在 Android 2.1 - 2.3 上运行良好,但在 ICS 中,MediaPlayer 在播放之前缓冲了大量此类数据.

Again, this is working fairly well Android 2.1 - 2.3 but in ICS the MediaPlayer is buffering a huge amount of this data before playing.

编辑 2:

进一步的测试表明,一旦升级到 Android 4.0.3,这也是 SGS2 上的问题.所以看起来 MediaPlayer 的缓冲实现在 4.0 中发生了显着变化.这令人沮丧,因为 API 无法改变行为.

Further testing is showing that this is also an issue on the SGS2 once upgraded to Android 4.0.3. So it seems like the MediaPlayer's buffering implementation has changed significantly in 4.0. This is frustrating as the API provides no way to alter the behaviour.

编辑 3:

Android 错误已创建.请添加评论并在那里加星标http://code.google.com/p/android/issues/detail?id=29870

Android bug created. Please add comments and star there as well http://code.google.com/p/android/issues/detail?id=29870

编辑 4:

我的播放代码相当标准.我在 onPrepared() 方法中对 MediaPlayer 进行了 start() 调用.

My playback code is fairly standard.. I have the start() call on the MediaPlayer in my onPrepared() method.

mCurrentPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mCurrentPlayer.setDataSource(url);
mCurrentPlayer.prepareAsync();

仅使用 prepare() 和 ajacian81 推荐的方法尝试过,但无济于事.

Have tried it using just prepare() and also ajacian81's recommended way but to no avail.

我应该补充一点,最近一位 Google 员工就我的问题回复了我,并确认在 ICS(对于高清内容)中有意增加了缓冲区大小.已要求 API 开发人员添加在 MediaPlayer 上设置缓冲区大小的功能.

I should add that recently a Google employee got back to me about my question and confirmed that the buffer size was intentionally increased in ICS (for HD content). It has been requested to the API developers to add the ability to set a buffer size on MediaPlayer.

虽然我认为这个 API 更改请求在我出现之前就已经存在,所以我不建议任何人屏住呼吸.

Though I think this API change request had been around before I came along so I wouldn't advise anyone to hold their breath.

推荐答案

是否可以看到您开始()处理 MediaPlayer 的代码?

Would it be possible to see the code where you're start()ing the MediaPlayer?

您使用的是 STREAM_MUSIC 音频流类型吗?

Are you using the STREAM_MUSIC audio stream type?

player.setAudioStreamType(AudioManager.STREAM_MUSIC);

你是否也尝试过 player.prepareAsync();和 player.prepare();?

Have you also experimented between player.prepareAsync(); and player.prepare();?

我记得去年有一个类似的问题,解决方法是:启动、暂停然后 onPrepared to start():

There was a similar issue last year I remember, where the solution was to: start, pause and then onPrepared to start():

player.setAudioStreamType(AudioManager.STREAM_MUSIC); 
player.setDataSource(src); 
player.prepare(); 
player.start(); 
player.pause(); 
player.setOnPreparedListener(new OnPreparedListener() {     
@Override
                public void onPrepared(MediaPlayer mp) {
                    player.start();                
                }
          });

在这种情况下不太可能解决问题,但是当您转动车轮时,这可能值得一试.

Unlikely to be the fix in this case, but while you're spinning your wheels this might be worth a shot.

这篇关于Android - ICS 4.0 中的 MediaPlayer 缓冲区大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆