在EasyPlayerPro上实现一键平稳切换视频源的功能

经常会遇到这样的需求,播放器支持动态切换视频源.典型的应用就是在电视上切换频道了.

市面上的播放器,在切换视频源时,可能需要将当前播放器release,再创建新的来进行加载,这样基本都存在闪一下黑屏的问题,个人感觉不是很好.那如何使得这两个视频平稳过度呢,比如在先一个视频未渲染之前,先停留在前一段视频的最后一帧画面(或许再加上个磨砂效果),会不会更好些?

下面就简单介绍一下实现原理与方法.

原理就是给视频播放界面加一个ImageView遮罩,在平时隐藏,切换的过程显示,并把视频最后一针画面保存到bitmap,然后在遮罩上显示这个bitmap;等后一个视频出来时候,在把遮罩隐藏之~

代码片段如下,不再详说,请参考注释:

  • 切换视频源
        if (mRenderView != null) {// 不为null,表示之前有渲染过视频,表示这里是视频切换而不是初始播放.
        //这里是切换视频源时的逻辑.切换视频源的时候,需新建一个player实例进行播放
            if (mRenderView instanceof TextureView){
                // 获取最后一针图像,并且保存成bitmap,以供遮罩显示.
                Bitmap bmp = ((TextureView) mRenderView).getBitmap();
                // 遮罩显示最后一针画面,并且设置为可见
                mCover.setImageBitmap(bmp);
                mCover.setVisibility(VISIBLE);

            }
//            if (mMediaPlayer != null)
//                mMediaPlayer.setDisplay(null);

            // 反初始化一些东东
            mRenderView.removeRenderCallback(mSHCallback);
            mRenderView = null;
        }

        if (renderView == null)
            return;

        // 在新的view上进行渲染哦.
        mRenderView = renderView;
  • 情况一,新的Surface 准备好了(视频在Surface准备好之前就开始渲染)
@Override
        public void onSurfaceCreated(SurfaceHolder holder, int width, int height) {
            if (mCurrentState == STATE_PLAYING) {   // 视频已经渲染了,尝试隐藏遮罩.
            // 遮罩的显示是有个动画效果的,先停止之前的动画,再渐渐渐隐遮罩,最终设置不可见.
                mCover.animate().cancel();
                mCover.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        mCover.setVisibility(GONE);
                        mCover.setAlpha(1.0f);
                    }
                });
            }
            // 这里表示初次播放或者切换视频源了.如果是后者,则动画显示遮罩.
            mSurfaceHolder = holder;
            if (mMediaPlayer != null) {
                bindSurfaceHolder(mMediaPlayer, holder);
            }
            else
                openVideo();
        }
  • 情况二,视频在Surface准备好之前后再渲染:

    public void onInfo(MediaPlayer mp, int arg1, int arg2) {
        switch (arg1) {
            case INFO_VIDEO_RENDERING_START:
                if (mSurfaceHolder == null) return;
                mCover.animate().cancel();
                mCover.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        mCover.setVisibility(GONE);
                        mCover.setAlpha(1.0f);
                    }
                }
        }
    }

关于EasyPlayerPro

EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP、RTMP、HTTP、HLS、UDP、RTP等多种流媒体协议播放、支持本地文件播放,支持本地抓拍、本地录像、播放旋转、多屏播放等多种功能特性,稳定、高效、可靠,支持Windows、Android、iOS三个平台,目前在多家教育、安防、行业型公司,都得到的应用,广受好评!

EasyPlayerPro:https://github.com/EasyDSS/EasyPlayerPro

点击链接加入群【EasyPlayer & EasyPlayerPro】:544917793

获取更多信息

邮件:[email protected]

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2017

EasyDarwin

猜你喜欢

转载自blog.csdn.net/jyt0551/article/details/78004591