- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我使用套接字作为 MediaPlayer 的代理,因此我可以在将 mp3 音频写入套接字之前下载和解密它。这类似于 NPR 新闻应用程序中显示的示例,但是我将其用于所有 Android 版本 2.1 - 4 atm。
NPR 流代理代码 - 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 监听器之前缓冲了太多数据。
在 onPrepared() 之前写入 Socket OutputStream 的数据量示例:
在带有 2.3.4 的 SGS2 上 - 约 133920 字节后的 onPrepared()
在带有 4.0.4 的 Nexus S 上 - 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 header 。
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 进行了 start() 调用。
mCurrentPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mCurrentPlayer.setDataSource(url);
mCurrentPlayer.prepareAsync();
仅使用 prepare() 以及 ajacian81 推荐的方式尝试过,但无济于事。
我应该补充一点,最近一位 Google 员工就我的问题回复了我,并确认 ICS(用于高清内容)中的缓冲区大小是故意增加的。已要求 API 开发人员添加在 MediaPlayer 上设置缓冲区大小的功能。
虽然我认为这个 API 更改请求在我出现之前就已经存在,所以我不建议任何人屏住呼吸。
最佳答案
是否可以在您开始()运行 MediaPlayer 时看到代码?
您使用的是 STREAM_MUSIC
音频流类型吗?
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
你是否也尝试过 player.prepareAsync();和 player.prepare();?
我记得去年有一个类似的问题,解决方法是:启动、暂停,然后 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();
}
});
在这种情况下不太可能是解决办法,但是当您转动车轮时,这可能值得一试。
关于Android - ICS 4.0 中的 MediaPlayer 缓冲区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10060165/
我在 logcat 中收到一条警告消息 W/MediaPlayer-JNI(16795): MediaPlayer finalized without being released 请告诉我我错在哪里
我有以下代码。 例如: if(player1 != null){ if(player1.isPlaying()){ //check if it playing //other
我在安卓系统工作。我正在创建一个正在运行音频文件的 mediaPlayer。我有 10 个按钮。我为每个按钮分配了不同的 url。因此,当我按下按钮 1 时,将播放与按钮 1 相关的 url 歌曲。然
我正在使用 MediaPlayer。我想制作在线流媒体广播。现在我有这个 mediaPlayer 对象(MediaPlayer 的),在 fragment 1 中说,当我在 fragment 1 上时
我使用了以下代码: mp = MediaPlayer.create(this, Uri.parse("file://"+filePath)); mp.start(); 这很好用。然后我想播放文件夹中的
我通过下载新文件来启动我的应用程序,如果有任何文件开始播放循环。然后我每 x 秒触发一个任务来寻找新媒体。调用任务后,视频将停止播放,并显示错误 MediaPlayer finalized witho
我的应用程序允许用户从多个音频流中进行选择,当用户点击其中一个播放按钮时,将调用以下代码: @Override public void onClick(View view) { mMediaP
我正在尝试在我的 ViewController 中播放视频。 Mediaplayer.framework 和所有 Headers 都在我的 Frameworks 文件夹中,包括 MediaPlayer
我正在使用 MediaPlayer 和 SurfaceView 播放本地视频文件。 SurfaceView 是 Activity 中的唯一控件,而我的视频文件是 QVGA 或其他。问题是视频被拉伸(s
我正在使用 JavaFX 的 MediaPlayer 播放 mp3 文件,getCurrentTime() 工作正常,但是当我在某个时候使用 seek() 方法时, getCurrentTime()
我将音量设置为 0.0,然后在 while 循环中一点一点地改变音量。然而,音量从 0.0 跳到 1.0?如何顺利改变音量?我试过了 public class EngineSound extends
我为“播放”和“暂停”按钮创建了两个 onClick 方法,但如果先点击“暂停”,然后点击“播放”按钮,则音乐不会播放。下面是代码 package com.example.myaudio; impor
我用 MediaPlayer 控件创建了一个绑定(bind)服务,它可以加载和播放音频。但碰巧的是,有时 mediaPlayer.prepare(); 速度不够快,并不总是准备好播放。 那么我怎样才能
我正在我的应用程序中播放从网络流式传输的 mp3 文件,一些 mp3 文件有奇怪的行为:mediaPlayer.getCurrentPosition() 大于 mediaPlayer.getDurat
我想制作广播播放器示例,但我有一些错误。我无法修复它。 我的源代码 String url = ""; //Shoutcast Radio URL mp = new MediaPlayer();
我知道有一些类似的问题,但没有一个回答我的问题。当我点击一个按钮时,媒体播放器被调用,并且它出现在日志中。 06-02 00:20:38.980 26035-26035/myapp.com.facad
我正在尝试从 URL 流式传输音频。该代码适用于其他 URL,但其中一个 URL 在 OnPrepared 方法中失败,返回此错误代码:(1, -2147483648)。我看过一些人说这是因为权限,但
我在我的 Android 应用程序中使用 MediaPlayer 来播放视频。当通过 mediaPlayer.pause() 方法暂停播放并调用 mediaPlayer.seekTo(msec) 时,
我的应用程序在 MediaPlayer 流媒体方面存在问题,特别是在 Nexus 5 上。我不确定这是 Nexus 5 还是 API 级别 19 导致的问题。基本上我的 MediaPlayer 准备好
不过,我正在使用 RingtoneManager 来获取 Ringtone。 此信息已包含在 this question and answer 中,但 Google 员工不太可能找到它,除非他们已经知
我是一名优秀的程序员,十分优秀!