这个播放的坑实在是多
其实网上也有很多这种demo,但是我运行之后,点击home,在回到应用发现播放异常,针对此现象,才决定写这篇文章,并重写了一个demo。
得自己控制好视频播放的声明周期
先上一张官网的生命周期图片
1、带单箭头的表示同步方法,双箭头的代表异步方法。
2、当一个MediaPlayer对象刚刚使用new创建,或者reset()被调用后,它处于Idle状态; 在release()被调用后,它处于End状态。
3、reset()方法调用后,新构造的MediaPlayer对象和MediaPlayer对象之间存在细微但重要的区别。
getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioAttributes(AudioAttributes), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(long, int), prepare() or prepareAsync()
在空闲状态下(Idle),对于一个新的MediaPlayer构造对象,如果您监听了OnErrorListener.onError()方法,那么将不会回调。但是对于一个调用了reset方法后的MediaPlayer对象(此时也属于Idle状态),当调用了上面的方法,就会在OnErrorListener.onError()方法回调。
4、一旦MediaPlayer对象不再被使用,立即调用release(),一旦MediaPlayer对象处于End状态,就不能再使用它,并且无法将其返回到任何其他状态。
每当应用程序的Activity暂停(onPause()或停止它的onStop()方法被调用)时,应该调用此方法来释放MediaPlayer对象。
5、使用new MediaPlayer时,处于Idle状态,而使用create这个重载方法创建对象时,直接处于Prepared状态。
6、可以创建setOnErrorListener监听观察播放期间的一切错误。
7、当进入错误状态可以调用reset,重新回复Idle状态。
8、调用
setDataSource(FileDescriptor)或setDataSource(String)或setDataSource(Context,Uri)或setDataSource(FileDescriptor,long,long)setDataSource(MediaDataSource)
将处于空闲状态的MediaPlayer对象转换为Initialized状态。
如果在任何其他状态下调用setDataSource(),则会引发IllegalStateException。
9、可以调用prepare()方法,该方法返回就进入Prepared状态。或者调用prepareAsync,当设置了setOnPreparedListener监听时,在onPrepared方法中,会将MediaPlayer置为Prepared状态。
10、要开始播放,必须调用start()。在start()成功返回后,MediaPlayer对象处于Started状态。可以调用isPlaying()来测试MediaPlayer对象是否处于Started状态。
调用start()对已处于Started状态的MediaPlayer对象没有影响。
调用start()以恢复已暂停的MediaPlayer对象的播放,并且恢复的播放位置与暂停的位置相同。当对start()的调用返回时,暂停的MediaPlayer对象将返回到Started状态。
11、可以调用pause()方法对处于paused状态
调用pause()对已处于暂停状态的MediaPlayer对象没有影响。
12、调用stop()将停止播放,并使MediaPlayer处于Started,Paused,Prepared或PlaybackCompleted状态进入停止状态。
一旦处于停止状态,直到调用prepare()或prepareAsync()以再次将MediaPlayer对象设置为Prepared状态,才能开始播放。
13、seekTo(long,int)可以在其他状态下调用,例如Prepared,Paused和PlaybackCompleted状态。当在这些状态下调用seekTo(long,int)时,如果流有视频并且请求的位置有效,则将显示一个视频帧。
此外,可以通过调用getCurrentPosition()来获取当前的实际播放位置,这对于需要跟踪播放进度的音乐播放器等应用程序很有帮助。
14、当播放到达流尾时,播放完成。
如果使用setLooping(boolean)将循环模式设置为true,则MediaPlayer对象应保持在Started状态。
如果循环模式设置为false,则如果通过setOnCompletionListener(OnCompletionListener)事先注册了OnCompletionListener,则播放器引擎将调用用户提供的回调方法OnCompletion.onCompletion()。调用回调信号表明对象现在处于PlaybackCompleted状态。
在PlaybackCompleted状态下,调用start()可以从音频/视频源的开头重新开始播放。
其实网上也有很多这种demo,但是我运行之后,点击home,在回到应用发现播放异常,针对此现象,才决定写这篇文章。
Demo:
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener, MediaPlayer.OnSeekCompleteListener, View.OnClickListener<