我试图创建一个简单的Android应用程序,它预先 MediaPlayer2 ,而 MediaPlayer1 正在播放内容。我使用了两个VideoView实例。目标是在两种不同内容之间切换时最小化黑屏。
第一个视频在 MediaPlayer1 中效果很好。但是,完成后, MediaPlayer2 开始呈现。然后,在MediaPlayer2的onInfoListener()内,MediaPlayer1的reset()在调用时抛出IllegalStateException。我在此处查看了Google文档中的状态图:http://developer.android.com/reference/android/media/MediaPlayer.html。
基于文档,MediaPlayer似乎处于有效状态,允许它调用reset()。知道问题在这里吗?
代码
public class PrebufferingActivity extends Activity {
private VideoView player1;
private VideoView player2;
private MediaPlayer mediaPlayer1;
private MediaPlayer mediaPlayer2;
public static final String URL_1 = "https://www.example.com/video1.mp4";
public static final String URL_2 = "https://www.example.com/video2.mp4";
public static final String TAG = "PrebufferingActivity";
public boolean FIRST_TIME = true;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prebuffering);
player1 = (VideoView) findViewById(R.id.videoPlayer1);
player2 = (VideoView) findViewById(R.id.videoPlayer2);
player1.setOnPreparedListener(new OnPreparedListener(){
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer1 = mp;
if(FIRST_TIME == true)
{
mediaPlayer1.start();
player1.requestFocus();
FIRST_TIME = false;
}
}
});
player2.setOnPreparedListener(new OnPreparedListener(){
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer2 = mp;
}
});
player1.setOnInfoListener(new OnInfoListener(){
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START){
// Prepare Play 1
mediaPlayer2.reset();
try {
mediaPlayer2.setDataSource(PrebufferingActivity.this, Uri.parse(URL_2));
} catch (Exception e) {
e.printStackTrace();
}
mediaPlayer2.prepareAsync();
}
return false;
}
});
player2.setOnInfoListener(new OnInfoListener(){
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START){
// Prepare Player 2
mediaPlayer1.reset();
try {
mediaPlayer1.setDataSource(PrebufferingActivity.this, Uri.parse(URL_1));
} catch (Exception e) {
e.printStackTrace();
}
mediaPlayer1.prepareAsync();
}
return false;
}
});
player1.setOnCompletionListener(new OnCompletionListener(){
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer2.start();
player2.requestFocus();
// Toggle visibility
player2.setVisibility(View.VISIBLE);
player1.setVisibility(View.INVISIBLE);
}
});
player2.setOnCompletionListener(new OnCompletionListener(){
@Override
public void onCompletion(MediaPlayer mp)
{
mediaPlayer1.start();
player1.requestFocus();
// Toggle visibility
player1.setVisibility(View.VISIBLE);
player2.setVisibility(View.INVISIBLE);
}
});
player1.setOnErrorListener(new OnErrorListener(){
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
player2.setOnErrorListener(new OnErrorListener(){
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
// Player 1
player1.setMediaController(new MediaController(this));
player1.setVideoURI(Uri.parse(URL_1));
// Player 2
player2.setMediaController(new MediaController(this));
player2.setVideoURI(Uri.parse(URL_2));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.prebuffering, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
异常
01-19 17:35:12.810: E/AndroidRuntime(30674): FATAL EXCEPTION: main
01-19 17:35:12.810: E/AndroidRuntime(30674): Process: com.my_package, PID: 30674
01-19 17:35:12.810: E/AndroidRuntime(30674): java.lang.IllegalStateException
01-19 17:35:12.810: E/AndroidRuntime(30674): at android.media.MediaPlayer._reset(Native Method)
01-19 17:35:12.810: E/AndroidRuntime(30674): at android.media.MediaPlayer.reset(MediaPlayer.java:1763)
01-19 17:35:12.810: E/AndroidRuntime(30674): at com.test.PrebufferingActivity$4.onInfo(PrebufferingActivity.java:120)
01-19 17:35:12.810: E/AndroidRuntime(30674): at android.widget.VideoView$4.onInfo(VideoView.java:487)
01-19 17:35:12.810: E/AndroidRuntime(30674): at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2994)
01-19 17:35:12.810: E/AndroidRuntime(30674): at android.os.Handler.dispatchMessage(Handler.java:102)
01-19 17:35:12.810: E/AndroidRuntime(30674): at android.os.Looper.loop(Looper.java:157)
01-19 17:35:12.810: E/AndroidRuntime(30674): at android.app.ActivityThread.main(ActivityThread.java:5356)
01-19 17:35:12.810: E/AndroidRuntime(30674): at java.lang.reflect.Method.invokeNative(Native Method)
01-19 17:35:12.810: E/AndroidRuntime(30674): at java.lang.reflect.Method.invoke(Method.java:515)
01-19 17:35:12.810: E/AndroidRuntime(30674): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
01-19 17:35:12.810: E/AndroidRuntime(30674): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
01-19 17:35:12.810: E/AndroidRuntime(30674): at dalvik.system.NativeStart.main(Native Method)