zoukankan      html  css  js  c++  java
  • EasyPlayer RTSP 安卓Android播放器显示模式设置方法

    一般对于一个播放器,应该支持如下几种显示模式:

    • 等比例,最大化区域显示,不裁剪
    • 等比例,最大区域显示,裁剪
    • 拉伸显示,铺满全屏

    要实现这几种显示模式,其实只要对播放控件的布局进行些许调整即可.那EasyPlayer是怎么实现的呢?
    EasyPlayer使用一个PlayFragment进行视频播放.该类实现了一个setScaleType的方法来进行显示模式设定(或切换).

    public void setScaleType(@IntRange(from = ASPACT_RATIO_INSIDE, to = FILL_WINDOW) int type){
      mRatioType = type;
      if (mWidth != 0 && mHeight != 0){
        onVideoSizeChange();
      }
    }

    这里的逻辑很简单,首先保存一下type的状态,并判断视频的宽高是否已经获取到了,如果是,则立马对view的尺寸进行计算,否则等获取到了后再计算.

    其参数支持如下几种:

    /**
         * 等比例,最大化区域显示,不裁剪
         */
    public static final int ASPACT_RATIO_INSIDE =  1;
    /**
         * 等比例,裁剪,裁剪区域可以通过拖拽展示隐藏
         */
    public static final int ASPACT_RATIO_CROPE_MATRIX =  2;
    /**
         * 等比例,最大区域显示,裁剪
         */
    public static final int ASPACT_RATIO_CENTER_CROPE =  3;
    /**
         * 拉伸显示,铺满全屏
         */
    public static final int FILL_WINDOW =  4;

    我们结合代码与注释,看看onVideoSizeChange()函数主要做了什么:

    private void onVideoSizeChange() {
      // 视频尺寸未获取成功,直接返回.
      if (mWidth == 0 || mHeight == 0) return;
      if (mAttacher != null){   // 如果之前的模式是ASPACT_RATIO_CROPE_MATRIX,先释放attacher.
        mAttacher.cleanup();
        mAttacher = null;
      }
      if (mRatioType == ASPACT_RATIO_CROPE_MATRIX) {
        // ...
        // 这种情况下,需要将显示区域铺满父窗口.并使用matrix和手势进行显示控制.
        // 具体的控制方法,参考文章:http://blog.csdn.net/jyt0551/article/details/56063869
        mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
        mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
        // 初始化新的Attacher进行显示控制.
        // ...
        // 使用一个角度控件来显示当前的拖动角度.
        mAngleView.setVisibility(View.VISIBLE);
      }else {
        // 重置matrix为默认(不做显示形变)
        mSurfaceView.setTransform(new Matrix());
        mAngleView.setVisibility(View.GONE);
        // 分别计算出显示控件的宽高比和视频的宽高比
        float ratioView = getView().getWidth() * 1.0f/getView().getHeight();
        float ratio = mWidth * 1.0f/mHeight;
    
        switch (mRatioType){
          case ASPACT_RATIO_INSIDE: {               
            if (ratioView - ratio < 0){    // 屏幕宽高比相比视频的宽高比更小.表示视频是过于宽了.
              // 那就以宽为基准.宽最大化
              mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
              // 高进行等比例缩放
              mSurfaceView.getLayoutParams().height = (int) (getView().getWidth() / ratio + 0.5f);
            }else{                          // 视频是竖屏了.
              // 以高为基准,高最大化
              mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
              // 宽进行等比例缩放
              mSurfaceView.getLayoutParams().width = (int) (getView().getHeight() * ratio + 0.5f);
            }
          }
            break;
          case ASPACT_RATIO_CENTER_CROPE: {
            // 以更短的为基准
            if (ratioView - ratio < 0){    // 屏幕宽高比相比视频的宽高比更小.表示视频是过于宽了.横向裁剪
              // 以高为基准.高铺满全屏
              mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
              // 等比例计算出横向区域..多出父控件的范围将被裁剪
              mSurfaceView.getLayoutParams().width = (int) (getView().getHeight() * ratio+ 0.5f);
            }else{                          // 视频是竖屏了.
              // 那就以宽为基准.宽铺满屏幕
              mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
              // 等比例计算出纵向区域,超出父控件的范围将被裁剪
              mSurfaceView.getLayoutParams().height = (int) (getView().getWidth() / ratio+ 0.5f);
            }
          }
            break;
          case FILL_WINDOW:{
            // 铺满父控件即可...
            mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
            mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
          }
            break;
        }
      }
      // 布局更改,刷新下.
      mSurfaceView.requestLayout();
    }

    onVideoSizeChange函数,除了在手动设置显示模式的时候调用外,在成功获取到了视频宽高,或者视频宽高更改之后,也会调用.如下:

    if (resultCode == EasyRTSPClient.RESULT_VIDEO_DISPLAYED) {
      // 视频开始显示了.
      onVideoDisplayed();
    } else if (resultCode == EasyRTSPClient.RESULT_VIDEO_SIZE) {
      // 视频分辨率获取到,或者更改了
      mWidth = resultData.getInt(EasyRTSPClient.EXTRA_VIDEO_WIDTH);
      mHeight = resultData.getInt(EasyRTSPClient.EXTRA_VIDEO_HEIGHT);
      onVideoSizeChange();
    }

    在EasyPlayer工程的demo事例里面,调用方法如下:

        public void onToggleAspectRatio(View view) {
            PlayFragment f =mRenderFragment;
            if (f == null) return;
            f.setScaleType(++i);
            switch (i){
                case PlayFragment.ASPACT_RATIO_INSIDE: {
                    Toast.makeText(this,"等比例居中",Toast.LENGTH_SHORT).show();
                }
                break;
                case PlayFragment.ASPACT_RATIO_CENTER_CROPE: {
                    Toast.makeText(this,"等比例居中裁剪视频",Toast.LENGTH_SHORT).show();
                }
                break;
                case PlayFragment.FILL_WINDOW:{
                    Toast.makeText(this,"拉伸视频,铺满区域",Toast.LENGTH_SHORT).show();
                }
                break;
                case PlayFragment.ASPACT_RATIO_CROPE_MATRIX:{
                    Toast.makeText(this,"等比例显示视频,可拖拽显示隐藏区域.",Toast.LENGTH_SHORT).show();
                }
                break;
            }
            if (i == PlayFragment.FILL_WINDOW){
                i = 0;
            }
        }

    让我们看看展示效果:

    EasyPlayer RTSP Android安卓播放器

    关于EasyPlayer流媒体播放器

    An elegant, simple, fast android RTSP/RTMP/HLS/HTTP Player.EasyPlayer support RTSP(RTP over TCP/UDP)version & Pro version,cover all kinds of streaming media!EasyPlayer是一款精炼、高效、稳定的流媒体播放器,分为RTSP版、RTMP版和Pro版三个版本,支持各种各样的流媒体音视频协议和文件的播放,在安防、互联网、教育、录播、IPTV等多个领域大放异彩,广泛应用!

    EasyPlayer:https://github.com/EasyDSS/EasyPlayer

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

    获取更多信息

    邮件:support@easydarwin.org

    EasyDarwin开源流媒体服务器:www.EasyDarwin.org

    EasyDSS商用流媒体解决方案:www.EasyDSS.com

    EasyNVR无插件直播方案:www.EasyNVR.com

    Copyright © EasyDarwin Team 2012-2017

    EasyDarwin

  • 相关阅读:
    Junit使用教程(四)
    《数据通信与网络》笔记--TCP中的拥塞控制
    Android Apps开发环境搭建
    quick-cocos2d-x教程10:实现血条效果。
    spring实战笔记6---springMVC的请求过程
    LINQ体验(1)——Visual Studio 2008新特性
    eclipse maven 插件的安装和配置
    [LeetCode][Java] Remove Duplicates from Sorted List II
    C++对象模型——解构语意学(第五章)
    SQL SERVER之数据查询
  • 原文地址:https://www.cnblogs.com/babosa/p/8206953.html
Copyright © 2011-2022 走看看