Android视频播放的工具类

在Android中音视频播放都可以使用MediaPlayer来进行处理。我使用的是SurfaceView 作为载体进行播放视频,还有其他的VideoView也是可以播放的,区别我就不说啦,网络上有很多。简单的来说播放音视频文件只需要两步

第一步

首先创建MediaPlayer实例,设置SurfaceView的管理类SurfaceHolder,为视频播放做准备,


    mPlayer = new MediaPlayer();

    mPlayer.setDataSource(url);

    mPlayer.prepare();

    mHolder = mSurface.getHolder();

    mHolder.addCallback(callback);

    mHolder.setFormat(PixelFormat.RGBA_8888);                    

setDataSource这个方法是设置视频播放的地址,可以是本地地址,也可以是网络地址,当然了,项目中的资源也可以使用这个,只是写法不同,


AssetFileDescriptor afd = this.getResource().openRawResourceFd  (R.raw.avchat_ring);      

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

                playerAudio.setDataSource(afd);

            }

关于setDataSource方法还有其他几种,不怎么常用,如果不使用setDataSource,可以直接在MediaPlayer实例化中实现


 MediaPlayer player = MediaPlayer.create(PlayVideoActivity.this, R.raw.video);

在第一步中有一个重要的接口实现mHolder.addCallback(callback);这个接口才是能在SurfaceView控件上面显示的图像的关键;

private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
     @Override
     public void surfaceCreated(SurfaceHolder holder) {

         mPlayer.setDisplay(holder);
     }

     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

     }

     @Override
     public void surfaceDestroyed(SurfaceHolder holder) {

     }
 };

当上面的初始化准备好了之后会调用surfaceCreated这个函数,在这里我们调用setDisplay将SurfaceHolder设置到媒体播放器中。这样就将播放器和我们的显示载体连接到了一起。

第二步

播放设置好的视频源和显示载体,我们就开始播放,调用MediaPlayer的start()函数直接播放。最好是在使用mPlayer 之前,先判断一下,防止出现空指针异常。

if (mPlayer != null) {
     mPlayer.start();
 }

暂停和停止

暂停播放和停止播放是两个不同的台概念,暂停之后可以直接再次调用start()函数播放视频,停止播放则不能直接调用start()函数播放,必须在播放之前重新准备MediaPlayer才能播放,具体原因就是在Stop的状态下不能直接转到Start的状态,需要先进入Prepare状态。

  • 暂停
 if (mPlayer != null) {
     mPlayer.pause();
 }
  • 停止
if (mPlayer != null) {
    mPlayer.stop();
    mPlayer.prepare();
}
  • 释放

release()调用该方法之后想要再次播放视频,需要重新实例化MediaPlayer。

if (mPlayer != null) {
   mPlayer.release();
   mPlayer = null;
}

全部代码

/**
 * @介绍: 音频工具类
 * @作者: sunset
 * @日期: 2018/1/16
 */
public class MediaUtil {


    private String TAG = "MediaUtil";
    private SurfaceHolder mHolder;
    private MediaPlayer mPlayer;

    private SurfaceView mSurface;
    private ImageView mThumbnail;
    private ImageView mPlay;


    private OnMediaListener listener;

    /**
     * 构造函数
     *
     * @param surface   播放视频的载体,必须传
     * @param thumbnail 视频缩略图(可选)
     * @param play      视频播放按钮(可选)
     */
    public MediaUtil(SurfaceView surface, ImageView thumbnail, ImageView play) {
        this.mSurface = surface;
        this.mThumbnail = thumbnail;
        this.mPlay = play;

    }

    /**
     * 初始化MediaPlayer
     *
     * @param url 播放源
     */
    public void initVideo(String url) {
        if (url == null) {
            return;
        }
        try {
            mPlayer = new MediaPlayer();
            mPlayer.setDataSource(url);
            mPlayer.prepare();
            mPlayer.setOnCompletionListener(completionListener);
            mPlayer.setOnPreparedListener(preparedListener);
            mPlayer.setOnVideoSizeChangedListener(sizeChangedListener);
            mHolder = mSurface.getHolder();
            mHolder.addCallback(callback);
            mHolder.setFormat(PixelFormat.RGBA_8888);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
    }

    /**
     * SurfaceView 准备好之后触发该接口,一般用来播放
     */
    private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            mPlayer.setDisplay(holder);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }
    };


    /**
     * 是否显示缩略图和播放按钮
     *
     * @param visible {@link Boolean}
     */
    public void isVisible(boolean visible) {
        if (mThumbnail != null && mPlay != null) {
            if (visible) {
                mThumbnail.setVisibility(View.VISIBLE);
                mPlay.setVisibility(View.VISIBLE);
            } else {
                mThumbnail.setVisibility(View.GONE);
                mPlay.setVisibility(View.GONE);
            }
        } else {
            Log.d(TAG, "不需要缩略图和播放按钮");
        }

    }


    /**
     * 开始播放
     */
    public void onStartPlay() {
        if (mPlayer != null) {
            isVisible(false);
            mPlayer.start();
        }
    }

    /**
     * 判断视频是否正在播放
     *
     * @return {@link Boolean}
     */
    public boolean isPlaying() {
        return mPlayer.isPlaying();
    }

    /**
     * 暂停播放
     */
    public void onPause() {
        if (mPlayer != null) {
            mPlayer.pause();
        }
    }


    /**
     * 停止播放
     */
    public void onStop() {
        if (mPlayer != null) {
            try {
                mPlayer.stop();
                mPlayer.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 释放MediaPlayer
     */
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
    }


    private MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            if (listener!=null){
                listener.onCompletion(mp);
            }
        }
    };

    private MediaPlayer.OnPreparedListener preparedListener = new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            if (listener!=null){
                listener.onPrepared(mp);
            }

        }
    };
    MediaPlayer.OnVideoSizeChangedListener sizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
            if (listener!=null){
                listener.onVideoSizeChanged(mp, width, height);
            }

        }
    };


    public void setOnMediaListener(OnMediaListener listener) {
        this.listener = listener;
    }


    public interface OnMediaListener {
        void onPrepared(MediaPlayer mp);

        void onVideoSizeChanged(MediaPlayer mp, int width, int height);

        void onCompletion(MediaPlayer mp);
    }


    /**
     * 适应控件的高度显示视频的大小
     */
    public void onAdaptiveSize() {
        if (mPlayer != null && mSurface != null) {
            int videoWidth = mPlayer.getVideoWidth();
            int videoHeight = mPlayer.getVideoHeight();

            int mSurfaceViewWidth = mSurface.getWidth();
            int mSurfaceViewHeight = mSurface.getHeight();

            LogUtil.logd(mSurfaceViewHeight + "-----------" + mSurfaceViewWidth);
//        mHolder.setFixedSize(mSurfaceViewWidth, mSurfaceViewHeight);
            int w = mSurfaceViewHeight * videoWidth / videoHeight;
            int margin = (mSurfaceViewWidth - w) / 2;
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            lp.setMargins(margin, 0, margin, 0);
            lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
            mSurface.setLayoutParams(lp);
        }

    }

    /**
     * 全屏控件的高度显示视频的大小
     */
    public void onFullScreenSize() {
        if (mPlayer != null && mSurface != null) {
            int videoWidth = mPlayer.getVideoWidth();
            int videoHeight = mPlayer.getVideoHeight();
            int mSurfaceViewWidth = ScreenUtil.getDisplayWidth();
            int mSurfaceViewHeight = ScreenUtil.getDisplayHeight();
            LogUtil.logd(mSurfaceViewHeight + "-----------" + mSurfaceViewWidth);
//            mHolder.setFixedSize(mSurfaceViewWidth, mSurfaceViewHeight);
            int w = mSurfaceViewHeight * videoWidth / videoHeight;
            int margin = (mSurfaceViewWidth - w) / 2;
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            lp.setMargins(margin, 0, margin, 0);
            mSurface.setLayoutParams(lp);
        }

    }


    /**
     * 获取视频缩略图
     *
     * @param filePath
     * @param kind
     * @return
     */
    public Bitmap getVideoThumbnail(String filePath, int kind) {
        Bitmap bitmap = null;
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            if (filePath.startsWith("http://")
                    || filePath.startsWith("https://")
                    || filePath.startsWith("widevine://")) {
                retriever.setDataSource(filePath, new Hashtable<String, String>());
            } else {
                retriever.setDataSource(filePath);
            }
            bitmap = retriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); //retriever.getFrameAtTime(-1);
        } catch (IllegalArgumentException ex) {
            // Assume this is a corrupt video file
            ex.printStackTrace();
        } catch (RuntimeException ex) {
            // Assume this is a corrupt video file.
            ex.printStackTrace();
        } finally {
            try {
                retriever.release();
            } catch (RuntimeException ex) {
                // Ignore failures while cleaning up.
                ex.printStackTrace();
            }
        }
        if (bitmap == null) {
            return null;
        }
        if (kind == MediaStore.Images.Thumbnails.MINI_KIND) {//压缩图片 开始处
            // Scale down the bitmap if it's too large.
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int max = Math.max(width, height);
            if (max > 512) {
                float scale = 512f / max;
                int w = Math.round(scale * width);
                int h = Math.round(scale * height);
                bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
            }//压缩图片 结束处
        } else if (kind == MediaStore.Images.Thumbnails.MICRO_KIND) {
            bitmap = ThumbnailUtils.extractThumbnail(bitmap,
                    96,
                    96,
                    ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        }
        return bitmap;
    }
}

OnMediaListener 这个接口是对MediaPlayer类的接口进行管理的作用。

猜你喜欢

转载自blog.csdn.net/sinat_32089827/article/details/79131829