为简化起见,我有一个带有两个网址的应用程序,一个用于视频文件,一个用于音频文件,并使用两个MediaPlayers播放它们,每个文件一个。
我的问题是视频在1-3秒后冻结(每次更改),同时音频继续正常。 我没有从MediaPlayer那里得到任何错误或例外,我甚至试图取消音频媒体播放器而只留下视频(因为我虽然是赛车问题),但它仍然有相同的行为。
以下是相关的代码段:
audioPlayer = new MediaPlayer(); // both media players declared outside
audioPlayer.setOnPreparedListener(this);
audioPlayer.setOnCompletionListener(this);
audioPlayer.setOnErrorListener(this);
audioPlayer.setScreenOnWhilePlaying(true);
videoPlayer = new MediaPlayer();
videoPlayer.setOnPreparedListener(this);
videoPlayer.setOnCompletionListener(this);
videoPlayer.setOnErrorListener(this);
videoPlayer.setScreenOnWhilePlaying(true);
try {
audioPlayer.setDataSource(audioPath);
Log.d(LOG_TAG, "audioPlayer.setDataSource(" + audioPath + ")");
videoPlayer.setDataSource(videoPath);
Log.d(LOG_TAG, "videoPlayer.setDataSource(" + videoPath + ")");
} catch (Exception e) {
Log.e(LOG_TAG, "setDataSource() - " + e.getMessage());
return;
}
try {
audioPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
float volume = Float.valueOf(options.getString("volume"));
Log.d(LOG_TAG, "setVolume: " + volume);
audioPlayer.setVolume(volume, volume);
} catch (Exception e) {
Log.e(LOG_TAG, "setVolume() - " + e.getMessage());
return;
}
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
try {
int scalingMode = options.getInt("scalingMode");
switch (scalingMode) {
case MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING:
videoPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
Log.d(LOG_TAG, "setVideoScalingMode VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING");
break;
default:
videoPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
Log.d(LOG_TAG, "setVideoScalingMode VIDEO_SCALING_MODE_SCALE_TO_FIT");
}
} catch (Exception e) {
Log.e(LOG_TAG, "setVideoScalingMode() - " + e.getMessage());
}
}
final SurfaceHolder mHolder = videoView.getHolder(); //videoview is another view in the display, but it does nothing
mHolder.setKeepScreenOn(true);
mHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(LOG_TAG, "Surface Created");
videoPlayer.setDisplay(holder);
try {
videoPlayer.prepareAsync();
audioPlayer.prepareAsync();
Log.d(LOG_TAG, "prepare()");
} catch (Exception e) {
Log.e(LOG_TAG, "prepare() - " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(LOG_TAG, "Surface Destroyed");
try {
audioPlayer.release();
}
catch(Exception e) {
// already released
}
try {
videoPlayer.release();
}
catch(Exception e) {
// already released
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(LOG_TAG, "Surface Changed");
}
});
@Override
public void onPrepared(MediaPlayer mp) {
Log.i(LOG_TAG, "MediaPlayer prepared");
if (mp.equals(videoPlayer)) {
mp.setWakeMode(cordova.getActivity(), PowerManager.PARTIAL_WAKE_LOCK);
mp.start();
mp.seekTo(0);
}
mp.start();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(LOG_TAG, "MediaPlayer.onError(" + what + ", " + extra + ")");
if (what == 100) { //reached end of stream, it's not really an error
this.onCompletion(mp);
}
if(mp != null && mp.isPlaying()) {
mp.stop();
}
if (mp != null) {
mp.setDisplay(null);
mp.release();
}
return false;
}
@Override
public void onCompletion(MediaPlayer mp) {
Log.i(LOG_TAG, "MediaPlayer completed");
try {
videoPlayer.setDisplay(null);
videoPlayer.release();
}
catch (Exception ex) {
// already released
}
try {
audioPlayer.release();
}
catch (Exception ex) {
// already released
}
}
有人知道为什么吗? 感谢。
修改
我注意到对于videoPlayer我收到701 \ 702的许多警告。也许这有关系?它似乎一直在缓冲数据,但从未恢复过来。