美文网首页
MediaPlayer

MediaPlayer

作者: DarcyZhou | 来源:发表于2022-09-23 15:28 被阅读0次

    1.MediaPlayer.java类

    (1)Android MediaPlayer类 (2)Android MediaCodec类

    MediaPlayer是Android中的一个多媒体播放类,通过它可以控制音视频流或本地音视频资源的播放过程。

    1.1 MediaPlayer创建

    可以直接调用构造函数创建,然后利用setDataSource()方法设置资源。

    MediaPlayer mp = new MediaPlayer();
    // path可以是本地路径,也可以是网络地址
    mp.setDataSource(String path);
    

    也可以调用create()方法,create()方法会直接调用prepare()方法。

    MediaPlayer.create(Context context, int resid)
    MediaPlayer.create(Context context, Uri uri)
    
    public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder,
            AudioAttributes audioAttributes, int audioSessionId) {
    
        try {
            MediaPlayer mp = new MediaPlayer(); // 创建实例
            final AudioAttributes aa = audioAttributes != null ? audioAttributes :
                new AudioAttributes.Builder().build();
            mp.setAudioAttributes(aa); // 设置音频参数
            mp.setAudioSessionId(audioSessionId);
            mp.setDataSource(context, uri); // 设置资源
            if (holder != null) {
                mp.setDisplay(holder);
            }
            mp.prepare(); // 调用prepare()
            return mp;
        }
        ...
        return null;
    }
    

    1.2 MediaPlayer的控制方法

    • prepare()/prepareAsync():提供了同步和异步两种方式设置播放器进入prepare状态
    • start():启动播放器播放
    • pause():暂停播放器播放
    • stop():停止播放器播放
    • getCurrentPosition():当前播放器的时间
    • seekTo(int):从指定位置开始播放
    • release():释放播放器暂用资源
    • reset():是播放器重回到Idle状态
    • setLooping(boolean):设置是否循环播放

    1.3 MediaPlayer的监听器

    • OnPreparedListener,prepare/prepareAsync:结束时调用
    • OnCompletionListener:播放结束时调用
    • OnSeekCompleteListener,seekTo(int):结束时调用

    1.4 MediaPlayer状态间的转换

    MediaPlayer用于控制视频/音频文件及流的播放,由状态机进行管理,如下为MediaPlayer状态调用。

    状态图.png
    • 椭圆:驻留状态;
    • 弧线:播放控制且驱动MediaPlayer状体进行过度;

    其中单箭头表示的是同步函数调用,双箭头表示的是异步函数调用。

    2.MediaPlayer播放音视频

    2.1 MediaPlayer播放音频

    在onCreate(Bundle)方法中创建MediaPlayer,在onDestroy()方法中销毁。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ... ...
    
        mMediaPlayer = new MediaPlayer();
        MediaPlayerListener listener = new MediaPlayerListener();
        mMediaPlayer.setOnPreparedListener(listener);
        mMediaPlayer.setOnCompletionListener(listener);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
    
    private void createMediaPlayer() {
        mMediaPlayer.reset();
    
        try {
            AssetFileDescriptor fd = getAssets().openFd("demo.mp3");
            mMediaPlayer.setDataSource(fd.getFileDescriptor(),
                    fd.getStartOffset(), fd.getLength());
            mMediaPlayer.prepare();
            mMediaPlayer.start();
        } catch (IOException e) {
            LogTool.loge(LOG_TAG, e);
        }
    }
    
    private void startMediaPlayer() {
        try {
            mMediaPlayer.start();
        } catch (IllegalStateException e) {
            LogTool.loge(LOG_TAG, e);
        }
    }
    
    private void pauseMediaPlayer() {
        try  {
            mMediaPlayer.pause();
        } catch (IllegalStateException e) {
            LogTool.loge(LOG_TAG, e);
        }
    }
    
    public void stopMediaPlayer() {
        try {
            mMediaPlayer.stop();
        } catch (IllegalStateException e) {
            LogTool.loge(LOG_TAG, e);
        }
    }
    
    private class MediaPlayerListener implements MediaPlayer.OnPreparedListener,
            MediaPlayer.OnCompletionListener {
    
        @Override
        public void onPrepared(MediaPlayer mp) {
        }
    
        @Override
        public void onCompletion(MediaPlayer mp) {
        }
    
    }
    

    2.2 MediaPlayer播放视频

    MediaPlayer要和SurfaceView配合播放视频,控制的方法和音频相同。在SurfaceView的SurfaceHolder中添加一个回调类Callback,在Callback.surfaceCreated(SurfaceHolder)方法中调用MediaPlayer的setDisplay(SurfaceHolder)方法。
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ... ...
    
        SurfaceHolder holder = mSurfaceView.getHolder();
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                // createMediaPlayer方法必须要等待Surface被创建以后调用
                createMediaPlayer();
            }
    
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            }
    
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
            }
        });
    
        mMediaPlayer = new MediaPlayer();
        MediaPlayerListener listener = new MediaPlayerListener();
        mMediaPlayer.setOnPreparedListener(listener);
        mMediaPlayer.setOnCompletionListener(listener);
    }
    
    private void createMediaPlayer() {
        mMediaPlayer.reset();
    
        try {
            AssetFileDescriptor fd = getAssets().openFd("video.3gp");
            mMediaPlayer.setDataSource(fd.getFileDescriptor(),
                    fd.getStartOffset(), fd.getLength());
            mMediaPlayer.prepare();
            mMediaPlayer.setDisplay(mSurfaceView.getHolder());
            mMediaPlayer.start();
        } catch (IOException e) {
        }
    }
    

    3.MediaPlayer源码解析

    安卓MediaPlayer源码跟读解析

    MediaPlayer框架的层次架构图如下:

    架构图.png

    4.seekTo()

    时序图.png

    相关文章

      网友评论

          本文标题:MediaPlayer

          本文链接:https://www.haomeiwen.com/subject/cwsnortx.html