我使用套接字作为MediaPlayer的代理,因此我可以在将它写入套接字之前下载和解密mp3音频。这与NPR新闻应用程序中显示的示例类似,但是我将其用于所有Android版本2.1 - 4 atm。Android - MediaSlayer缓冲区大小在ICS 4.0中
NPR StreamProxy码 - http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java
我的问题是,播放快2.1 - 2.3,但烧制onPrepared听众之前的Android 4.0 ICS的MediaPlayer的缓冲数据太多。
onPrepared(前写入到插座的OutputStream)的数据的示例量:
在SGS2与2.3.4 - onPrepared()之后〜133920个字节
在Nexus S采用4.0.4 - onPrepared ()之后〜961930字节
这也发生在Galaxy Nexus上。
奇怪的是,4.0仿真器没有像4.0设备那样缓冲数据。任何人在ICS上遇到与MediaPlayer类似的问题?
编辑
下面是代理如何写入套接字。在这个例子中,它来自一个从文件加载的CipherInputStream,但是当它从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头..
private String buildHttpHeader(final int contentLength) {
final StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 200 OK\r\n");
sb.append("Content-Length: ").append(contentLength).append("\r\n");
sb.append("Accept-Ranges: bytes\r\n");
sb.append("Content-Type: audio/mpeg\r\n");
sb.append("Connection: close\r\n");
sb.append("\r\n");
return sb.toString();
}
我环顾四周,可选的实施方式,但正如我所加密的音频和MediaPlayer的不支持InputStreams为一个数据源我唯一的选择(我想..)是使用这样的代理。
同样,这在Android 2.1 - 2.3中工作得相当好,但在ICS中,MediaPlayer在播放之前会缓冲大量的这些数据。
编辑2:
进一步测试显示,这也是一次升级至Android 4.0.3的SGS2的问题。所以看起来MediaPlayer的缓冲实现在4.0中发生了显着变化。这令人沮丧,因为API没有办法改变行为。
编辑3:
已创建Android错误。请添加注释和明星有作为 http://code.google.com/p/android/issues/detail?id=29870
编辑4:
我的播放代码是相当标准。我有我的onPrepared()方法的MediaPlayer的开始()调用。
mCurrentPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mCurrentPlayer.setDataSource(url);
mCurrentPlayer.prepareAsync();
已经试过它只使用prepare()和ajacian81的推荐方式,但无济于事。
我应该补充一点,Google员工最近回复了我的问题,并确认缓冲区大小在ICS(针对HD内容)中有意增加。已向API开发人员要求添加在MediaPlayer上设置缓冲区大小的功能。
虽然我认为这个API变更请求在我出现之前已经存在,所以我不会建议任何人屏住呼吸。
哇!同样的问题! Nexus S. MediaPlayer的缓冲区太大 – Alexis 2012-04-12 07:45:18
这可能是值得记录的,这是Android开发人员的一个错误。 – 2012-04-27 22:17:48
请明星我提交的Android错误以帮助获得一些可见性 - https://code.google.com/p/android/issues/detail?id=29870 – denizmveli 2012-05-01 14:17:17