【问题标题】:Calling MediaPlayer.PrepareAsync from VideoView从 VideoView 调用 MediaPlayer.PrepareAsync
【发布时间】:2013-09-03 18:01:29
【问题描述】:
我正在尝试实现一个视频播放列表,以便它们能够从一个视频平滑过渡到下一个视频。 mediaPlayer 对象有一个 prepareasync() 方法,该方法似乎可以预缓冲视频,以便可以播放。如何从 VideoView 对象调用 prepareasync 方法?我为 mediaPlayer 找到的示例要么不使用 VideoView,而且似乎是从头开始创建表面的。或者这些示例使用 mediaPlayer 作为 videoview 事件侦听器的返回参数,这似乎只在 videoview.play() 之后发生。我想在调用 play 方法之前访问 videoview 的媒体播放器,这样我就可以调用 prepareasync(),然后再调用 play()。
【问题讨论】:
标签:
android
android-videoview
【解决方案1】:
正如user1023110 提到的,VideoView 是 MediaPlayer 的包装器。深入研究源代码(因为文档根本没有用),我确认它在其私有方法 openVideo() 中内部调用了 prepareAsync():
private void openVideo() {
if (mUri == null || mSurfaceHolder == null) {
// not ready for playback just yet, will try again later
return;
}
// Tell the music playback service to pause
// TODO: these constants need to be published somewhere in the framework.
Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
mContext.sendBroadcast(i);
// we shouldn't clear the target state, because somebody might have
// called start() previously
release(false);
try {
mMediaPlayer = new MediaPlayer();
if (mAudioSession != 0) {
mMediaPlayer.setAudioSessionId(mAudioSession);
} else {
mAudioSession = mMediaPlayer.getAudioSessionId();
}
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnInfoListener(mOnInfoListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
// we don't set the target state here either, but preserve the
// target state that was there before.
mCurrentState = STATE_PREPARING;
attachMediaController();
} catch (IOException ex) {
Log.w(TAG, "Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
} catch (IllegalArgumentException ex) {
Log.w(TAG, "Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
}
}
【解决方案2】:
VideoView 是 MediaPlayer 和 SurfaceView 的封装,因此您不必自己动手。我相信包装器会在您调用 setVideoURI 时进行准备。
有可能通过 onPrepared 事件处理程序在 VideoView 中获取媒体播放器,一旦你得到它,我想你可以在第一次之后自己调用准备,但我认为内部是棘手的并且没有很好的记录所以事情可能没有按预期工作。