搜索
热搜: 活动 交友 discuz
查看: 3889|回复: 0
打印 上一主题 下一主题

GsyVideoPlayer视频播放器使用

[复制链接]

160

主题

165

帖子

814

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
814
跳转到指定楼层
楼主
发表于 2018-10-18 09:23:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://github.com/CarGuo/GSYVideoPlayer

1.GSYVideoPlayer的初始化

2.视频播放实现

3.全屏实现

4.滑动时,小窗口出现和消失实现逻辑

5.小窗口视频创建

6.小窗口视频恢复为列表视频

7.边缓存边播放实现

8.弹幕效果实现



一.初始化分析

1.初始化主要是构造了一个StandardGSYVideoPlayer

2.设置全屏布局的容器

代码如下:

listVideoUtil = new ListVideoUtil(this);
listVideoUtil.setFullViewContainer(videoFullContainer);



public ListVideoUtil(Context context) {
        gsyVideoPlayer = new StandardGSYVideoPlayer(context);
        this.context = context;
}

StandardGSYVideoPlayer的初始化化主要是加载R.layout.video_layout_standard这个布局,并且实例化一些组件,为组件设置监听事件;

初始化组件包括:播放/暂停按钮,播放时长,总时长,播放进度条,返回按钮,全屏按钮和视频标题,

初始化组件不包括:用于显示视频的TextureView,这个TextureView是动态添加的,放在下片文章中讲述;

初始化内容比较简单;



思考以下几个问题:

1.视频窗口的大小和位置是如何匹配ListView的item大小和位置的?

2.视频播放画面是如何显示出来的?

3.视频播放的声音如何显示出来的?



通过代码分析;


@Override
  public View getView(final int position, View convertView, ViewGroup parent) {

      ....

      ....

     listVideoUtil.addVideoPlayer(position, holder.imageView, TAG, holder.videoContainer, holder.playerBtn);

     holder.playerBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                notifyDataSetChanged();
                //listVideoUtil.setLoop(true);
                listVideoUtil.setPlayPositionAndTag(position, TAG);
//                final String url = "https://tv.miguvideo.com/?from=singlemessage&isappinstalled=0#video/live/761358370/room201706301600304971_R1";
                //listVideoUtil.setCachePath(new File(FileUtils.getPath()));
                final String url = "http://baobab.wdjcdn.com/14564977406580.mp4";
                listVideoUtil.startPlay(url);
            }
        });

       ........

      .......

}

listview的adapter的getview方法每次都会走一次listVideoUtil.addVideoPlayer(position, holder.imageView, TAG, holder.videoContainer, holder.playerBtn);

/**
     * 动态添加视频播放
     *
     * @param position  位置
     * @param imgView   封面
     * @param tag       TAG类型
     * @param container player的容器
     * @param playBtn   播放按键
     */
    public void addVideoPlayer(final int position, View imgView, String tag,
                               ViewGroup container, View playBtn) {
        container.removeAllViews();
        if (isCurrentViewPlaying(position, tag)) {
            if (!isFull) {
                ViewGroup viewGroup = (ViewGroup) gsyVideoPlayer.getParent();
                if (viewGroup != null)
                    viewGroup.removeAllViews();
                container.addView(gsyVideoPlayer);
                playBtn.setVisibility(View.INVISIBLE);
            }
        } else {
            playBtn.setVisibility(View.VISIBLE);
            container.removeAllViews();   //增加封面
            container.addView(imgView);
        }
    }

代码可以看出addVideoPlayer方法的意思是,如果当前的position等于listVideoUtil中获取到的position,videoContainer中就显示gsyVideoPlayer,否则显示视频封面;

点击播放按钮的作用:

1.向listVideoUtil中设置position,并通过notifyDataSetChanged方法使重新走getview(),重新走getview方法时,会重新进入addVideoPlayer方法判断;

   至此第一个疑问已经解决:视频显示在哪个item就是这个position决定的;视频窗口的大小由videoContainer的大小决定;

2.执行代码listVideoUtil.startPlay(url);



下面开始分析startPlay(url)中做了哪些操作?

  /**
     * 开始播放
     *
     * @param url 播放的URL
     */
    public void startPlay(String url) {

        if (isSmall()) {
            smallVideoToNormal();//如果是小窗口,就转为正常窗口播放,这个问题后面再说
        }

        this.url = url;

        gsyVideoPlayer.release();

        gsyVideoPlayer.setLooping(isLoop);//视频是否循环播放

        gsyVideoPlayer.setSpeed(speed);//视频播放速度

        gsyVideoPlayer.setNeedShowWifiTip(needShowWifiTip);//非wifi环境下,显示流量提醒

        gsyVideoPlayer.setNeedLockFull(needLockFull);//是否需要全屏锁屏

        gsyVideoPlayer.setUp(url, true, cachePath, mapHeadData, objects);//设置边缓存边播放

        //增加title
        gsyVideoPlayer.getTitleTextView().setVisibility(View.GONE);

        //设置返回键
        gsyVideoPlayer.getBackButton().setVisibility(View.GONE);

        //设置全屏按键功能
        gsyVideoPlayer.getFullscreenButton().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resolveFullBtn();
            }
        });

        gsyVideoPlayer.startPlayLogic();
    }



就是一些简单设置项,其中gsyVideoPlayer.setUp(url, true, cachePath, mapHeadData, objects);会把url改为全局的mUrl;



    @Override
    public void startPlayLogic() {
        if (mStandardVideoAllCallBack != null) {
            Debuger.printfLog("onClickStartThumb");
            mStandardVideoAllCallBack.onClickStartThumb(mUrl, mObjects);
        }
        prepareVideo();
        startDismissControlViewTimer();
    }





    /**
     * 开始状态视频播放
     */
    protected void prepareVideo() {
        if (GSYVideoManager.instance().listener() != null) {
            GSYVideoManager.instance().listener().onCompletion();
        }
        GSYVideoManager.instance().setListener(this);
        GSYVideoManager.instance().setPlayTag(mPlayTag);
        GSYVideoManager.instance().setPlayPosition(mPlayPosition);
        addTextureView();//动态添加TextureView
        mAudioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);//暂时获取音频焦点
        ((Activity) getContext()).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//保持屏幕常亮不灭屏
        GSYVideoManager.instance().prepare(mUrl, mMapHeadData, mLooping, mSpeed);
        setStateAndUi(CURRENT_STATE_PREPAREING);
    }

    科普1,音频焦点分类:

    AudioManager.AUDIOFOCUS_REQUEST_GRANTED------------永久获取音频焦点

    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT-------------暂时获取音频焦点,比如音乐后台播放,当前视频播放会抢夺音频焦点,视频播放完成,音乐自动播放;

   AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK--------提示类型获取音频焦点,比如听音乐的时候来短信,音乐声音降低



   /**
     * 添加播放的view
     */
    protected void addTextureView() {
        if (mTextureViewContainer.getChildCount() > 0) {
            mTextureViewContainer.removeAllViews();
        }
        mTextureView = null;
        mTextureView = new GSYTextureView(getContext());
        mTextureView.setSurfaceTextureListener(this);
        mTextureView.setRotation(mRotate);

        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        mTextureViewContainer.addView(mTextureView, layoutParams);
    }

    构造了一个TextureView,并添加到gsyVideoPlayer布局中。

    TextureView设置了SurfaceTextureListener;

     科普2:SurfaceTextureListener回调方法:

1.onSurfaceTextureAvailable(SurfaceTexture arg0, int arg1, int arg2)-------------TextureView可用时调用

2.onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)

3.onSurfaceTextureDestroyed(SurfaceTexture surface)------------TextureView销毁时调用

4.onSurfaceTextureUpdated(SurfaceTexture surface)

   回到代码:

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mSurface = new Surface(surface);
        GSYVideoManager.instance().setDisplay(mSurface);
        //显示暂停切换显示的图片
        showPauseCover();
    }

    意思是:在TextureView可以使用时,将surface交给GSYVideoManager,用于显示视频的画面,至此第二个问题已经解决,当然此时还没有开始播放视频, 真正播放视频是在

GSYVideoManager.instance().prepare(mUrl, mMapHeadData, mLooping, mSpeed)中,此处的mUrl就是上面保存的url;

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|安卓论坛  

GMT+8, 2024-5-6 06:58 , Processed in 0.062040 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Design S!|ƽ̶

快速回复 返回顶部 返回列表