美文网首页
Android MediaPlayer使用

Android MediaPlayer使用

作者: yunhen | 来源:发表于2018-11-13 15:45 被阅读4次

    状态图


    mediastatu.jpg

    需要注意的是和camera的释放类似,调用release()后没法直接进入idle状态,所以mediaplayer的状态是有问题的,要置null

    自己的一个栗子:

    package yunhen.yunjia.aiservice.camera;
    
    import android.content.res.AssetFileDescriptor;
    import android.graphics.Matrix;
    import android.media.AudioManager;
    import android.media.MediaPlayer;
    import android.util.Log;
    import android.view.Surface;
    import android.view.TextureView;
    
    import java.io.IOException;
    import java.lang.ref.WeakReference;
    
    import yunhen.yunjia.aiservice.utils.Logs;
    import yunhen.yunjia.aiservice.utils.SPConfig;
    
    public class MediaPlayUtils {
        private static final String TAG = MediaPlayUtils.class.getSimpleName();
        private MediaPlayer mMediaPlayer;
        private static MediaPlayUtils m;
        private WeakReference<TextureView> weak ;
    
        private String filaHelloName = "1.mp4";
        private String filaSpeakNameMirror = "2Left.mp4";
        private String filaSpeakName = "3Right.mp4";
        private AssetFileDescriptor afdHello;
        private AssetFileDescriptor afd;
        private AssetFileDescriptor afdMirror;
        private boolean isMirror = true;
        MediaPlayer.OnCompletionListener mCompletionListener;
    
        public static MediaPlayUtils instance() {
            synchronized (MediaPlayUtils.class) {
                if (null == m) {
                    synchronized (MediaPlayUtils.class) {
                        m = new MediaPlayUtils();
                    }
                }
            }
            return m;
        }
        private MediaPlayUtils() {
    
        }
    
        /**
         * 当前播放的视频
         * <p>{@link MediaPlayUtils#currStatu}</p>
         * @return
         */
        public Statu currStatu() {
            return currStatu;
        }
    
        public void init(TextureView surfaceView) {
            if (null == mMediaPlayer) {
                mMediaPlayer = new MediaPlayer();
            } else {
    
            }
            weak = new WeakReference<>(surfaceView);
    //        pathDef = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath()
    //                    + File.separator+ filaHelloName;
    //        pathSpeak = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath()
    //                    + File.separator + filaSpeakName;
            try {
                afdHello = weak.get().getContext().getAssets().openFd(filaHelloName);
                afd = weak.get().getContext().getAssets().openFd(filaSpeakName);
                afdMirror = weak.get().getContext().getAssets().openFd(filaSpeakNameMirror);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    
        public void setCompletionListener(MediaPlayer.OnCompletionListener completionListener) {
            mCompletionListener = completionListener;
        }
    
    
        public void play(Statu statu) {
            currStatu = statu;
            if (null == mMediaPlayer) {
                mMediaPlayer = new MediaPlayer();
            }
            else if (isPlaying()){
                pause();
    //            stop();
    //            release();
            }
            resetDate(statu);
            Logs.instance().e(TAG,"weak.get() is null "+ (weak.get() == null));
            Logs.instance().e(TAG,"weak.getSurfaceTexture is null "+ (weak.get().getSurfaceTexture() == null));
            Surface s = new Surface(weak.get().getSurfaceTexture());
            mMediaPlayer.setSurface(s);//设置video影片以surfaceviewholder播放
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mMediaPlayer.setVolume(0f, 0f);
    
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    updateSizeCenterCrop();
                    mediaPlayer.start();
                }
            });
            mMediaPlayer.setOnCompletionListener(mCompletionListener);
            mMediaPlayer.prepareAsync();
        }
    
        public enum Statu{
            /**
             * 问好嘴动循环
             */
            hello_speaking_loop,
            /**
             * 问好嘴不动循环
             */
            hellow_not_speak_loop,
            /**
             * 向上抬手
             */
            tai_shou_one,
            /**
             * 抬手不动循环
             */
            tai_shou_loop,
            /**
             * 向下放手
             */
            fang_shou_one;
        }
        public void reset() {
            if (null != mMediaPlayer) {
                try {
                    mMediaPlayer.reset();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }
        }
        public void pause() {
            if (null != mMediaPlayer) {
                try {
                    mMediaPlayer.pause();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public boolean isPlaying() {
            if (null != mMediaPlayer) {
                try {
                    return mMediaPlayer.isPlaying();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
        Statu currStatu;
    
        public void resetDate(Statu statu) {
            reset();
    
            try {
                if (Statu.hello_speaking_loop == statu) {
    
                    String path = SPConfig.instance(weak.get().getContext())
                            .getVideoPathHellow();
                    if (null == path || "".equals(path)) {
                        mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength());
                    } else {
                        mMediaPlayer.setDataSource(path);
                    }
                } else if (Statu.hellow_not_speak_loop == statu) {
                    String path = SPConfig.instance(weak.get().getContext())
                            .getVideoPathHellowLoop();
                    if (null == path || "".equals(path)) {
                        mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength());
                    } else {
                        mMediaPlayer.setDataSource(path);
                    }
                } else if (Statu.tai_shou_one == statu) {
                    String path = "";
                    if (isMirror) {
                        path = SPConfig.instance(weak.get().getContext())
                                .getVideoPathLeftTaiShou();
                        if (null == path || "".equals(path)) {
                            mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength());
                        } else {
                            mMediaPlayer.setDataSource(path);
                        }
                    }else {
                        path = SPConfig.instance(weak.get().getContext())
                                .getVideoPathRightTaiShou();
                        if (null == path || "".equals(path)) {
                            mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength());
                        } else {
                            mMediaPlayer.setDataSource(path);
                        }
                    }
    
                } else if (Statu.tai_shou_loop == statu) {
    //                mMediaPlayer.setDataSource(pathSpeak);
                    if (isMirror) {//镜像模式下向左
                        String pathLeft = SPConfig.instance(weak.get().getContext()).getVideoPathLeftTaiShouLoop();
                        if (null == pathLeft || "".equals(pathLeft)) {
                            mMediaPlayer.setDataSource(afdMirror.getFileDescriptor(),afdMirror.getStartOffset(),afdMirror.getLength());
                        } else {
                            mMediaPlayer.setDataSource(pathLeft);
                        }
                    } else {
                        String pathRight = SPConfig.instance(weak.get().getContext()).getVideoPathRightTaiShouLoop();
                        if (null == pathRight || "".equals(pathRight)) {
                            mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
                        } else {
                            mMediaPlayer.setDataSource(pathRight);
                        }
                    }
                } else if (Statu.fang_shou_one == statu) {
                    if (isMirror) {//镜像模式下向左
                        String pathLeft = SPConfig.instance(weak.get().getContext()).getVideoPathLeftFangShou();
                        if (null == pathLeft || "".equals(pathLeft)) {
                            mMediaPlayer.setDataSource(afdMirror.getFileDescriptor(),afdMirror.getStartOffset(),afdMirror.getLength());
                        } else {
                            mMediaPlayer.setDataSource(pathLeft);
                        }
                    } else {
                        String pathRight = SPConfig.instance(weak.get().getContext()).getVideoPathRightFangShou();
                        if (null == pathRight || "".equals(pathRight)) {
                            mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
                        } else {
                            mMediaPlayer.setDataSource(pathRight);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG,"IOException "+e.getMessage());
            }
        }
        public void stop() {
            if (null != mMediaPlayer) {
                try {
                    mMediaPlayer.stop();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void release() {
            if (null != mMediaPlayer) {
                try {
                    mMediaPlayer.release();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
                mMediaPlayer = null;
            }
        }
    
        public void destroy() {
            stop();
            release();
        }
        public void setMirror(boolean mirror) {
            this.isMirror = mirror;
        }
    
        //重新计算video的显示位置,让其全部显示并据中
        public void updateSizeCenter(){
            int mVideoWidth = mMediaPlayer.getVideoWidth();
            int  mVideoHeight = mMediaPlayer.getVideoHeight();
            float sx = (float) weak.get().getWidth() / (float) mVideoWidth;
            float sy = (float) weak.get().getHeight() / (float) mVideoHeight;
    
            Matrix matrix = new Matrix();
    
            //第1步:把视频区移动到View区,使两者中心点重合.
            matrix.preTranslate((weak.get().getWidth() - mVideoWidth) / 2, (weak.get().getHeight() - mVideoHeight) / 2);
    
            //第2步:因为默认视频是fitXY的形式显示的,所以首先要缩放还原回来.
            matrix.preScale(mVideoWidth / (float) weak.get().getWidth(), mVideoHeight / (float) weak.get().getHeight());
    
            //第3步,等比例放大或缩小,直到视频区的一边和View一边相等.如果另一边和view的一边不相等,则留下空隙
            if (sx >= sy){
                matrix.postScale(sy, sy, weak.get().getWidth() / 2, weak.get().getHeight() / 2);
            }else{
                matrix.postScale(sx, sx, weak.get().getWidth() / 2, weak.get().getHeight() / 2);
            }
    
            weak.get().setTransform(matrix);
            weak.get().postInvalidate();
        }
    
        //重新计算video的显示位置,裁剪后全屏显示
        public void updateSizeCenterCrop(){
            int mVideoWidth = mMediaPlayer.getVideoWidth();
            int  mVideoHeight = mMediaPlayer.getVideoHeight();
            float sx = (float) weak.get().getWidth() / (float) mVideoWidth;
            float sy = (float) weak.get().getHeight() / (float) mVideoHeight;
    
            Matrix matrix = new Matrix();
            float maxScale = Math.max(sx, sy);
    
            //第1步:把视频区移动到View区,使两者中心点重合.
            matrix.preTranslate((weak.get().getWidth() - mVideoWidth) / 2, (weak.get().getHeight() - mVideoHeight) / 2);
    
            //第2步:因为默认视频是fitXY的形式显示的,所以首先要缩放还原回来.
            matrix.preScale(mVideoWidth / (float)weak.get(). getWidth(), mVideoHeight / (float) weak.get().getHeight());
    
            //第3步,等比例放大或缩小,直到视频区的一边超过View一边, 另一边与View的另一边相等. 因为超过的部分超出了View的范围,所以是不会显示的,相当于裁剪了.
            matrix.postScale(maxScale, maxScale, weak.get().getWidth() / 2, weak.get().getHeight() / 2);//后两个参数坐标是以整个View的坐标系以参考的
    
            weak.get().setTransform(matrix);
            weak.get().postInvalidate();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Android MediaPlayer使用

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