美文网首页ijkplayer视频音频
ijkplayer自适应旋转

ijkplayer自适应旋转

作者: 南风无影 | 来源:发表于2016-11-29 11:46 被阅读194次
    UIViewContentModeScaleAspectFit
    这种模式,限制宽高的某一方, 会有黑边。
    如果是竖屏,那就固定宽度, 如果是横屏,那就固定高度。
    
    UIViewContentModeScaleAspectFill
    这种是填充模式,不会拉伸,但是如果不是等比的宽高(手机16:9)可能会切割。
    

    要实现自适应旋转,需要重写layoutSubviews方法

    iOS layout机制相关方法

    - (CGSize)sizeThatFits:(CGSize)size
    - (void)sizeToFit
    ——————-
    
    - (void)layoutSubviews
    - (void)layoutIfNeeded
    - (void)setNeedsLayout
    ——————–
    
    - (void)setNeedsDisplay
    - (void)drawRect
    

    layoutSubviews在以下情况下会被调用:

    1. init初始化不会触发layoutSubviews

      但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时,也会触发

    2. addSubview会触发layoutSubviews

    3. 设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化

    4. 滚动一个UIScrollView会触发layoutSubviews

    5. 旋转Screen会触发父UIView上的layoutSubviews事件

    6. 改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

    在苹果的官方文档中强调:

      You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.
    

    layoutSubviews, 当我们在某个类的内部调整子视图位置时,需要调用。

    反过来的意思就是说:如果你想要在外部设置subviews的位置,就不要重写。

    刷新子对象布局

    -layoutSubviews方法:
    这个方法,默认没有做任何事情,需要子类进行重写
    
    -setNeedsLayout方法: 
    标记为需要重新布局,异步调用layoutIfNeeded刷新布局,
    不立即刷新,但layoutSubviews一定会被调用
    
    -layoutIfNeeded方法:
    如果有需要刷新的标记,立即调用layoutSubviews进行布局
    (如果没有标记,不会调用layoutSubviews)
    

    如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局

    在视图第一次显示之前,标记总是“需要刷新”的,可以直接调用[view layoutIfNeeded]

    从5可以看出,旋转会调layoutSubviews,
    所以,需要重写方法,在旋转的时候进入处理代码:

    - (void)layoutSubviews {
        [super layoutSubviews];
    
        //屏幕的整个空间
        CGRect rect = [UIScreen mainScreen].bounds;
        self.frame = rect;
        
       //从父视图的view中取出子视图OpenGL的view
        UIView *openglView = [self viewWithTag:11001];
        if (openglView) {
                openglView.frame = rect;
        }
    }
    
    注:[UIScreen mainScreen].bounds方法,
    在不同iPhone设备各个屏幕分辨率:
      4/4S : 320*480    1.5
      5/5S : 320*568     568/320 = 1.775
            6    : 750*1334                          1.77866667
            6+   : 1080*1920                       1.77777778
    
    16/9 = 1.77777778
    所以可能会有黑边
    

    另外,如果横竖屏切换的时候,可能Fit和Fill模式需要动态变化,
    这时候就要在ijk SDL模块取修改opengl的渲染了。

    防止屏幕黑边的办法:正常的竖屏直播用fill,竖屏不做旋转。
    如果是宽大于高的源,用fit模式。

    IJKSDLGLView.m
    
    - (id) initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            _tryLockErrorCount = 0;
            self.glActiveLock = [[NSRecursiveLock alloc] init];
            _registeredNotifications = [[NSMutableArray alloc] init];
            [self registerApplicationObservers];
             [self registerApplicationObservers];
             _didSetupGL = NO;
    +       //gongjia modify.  refresh for fit/fill mode
    +       //[self setupGLOnce];
       }
    
        return self;
    }
    
     
    
    
    - (void)display: (SDL_VoutOverlay *) overlay
    {
         if (overlay == NULL)
             return;
     +   if (overlay->w > overlay->h) {
     +       [self setContentMode:UIViewContentModeScaleAspectFit];
     +   }
         if (![self setupGLOnce])
             return;
    
        ......
    

    添加自适应模式代码:

        self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        self.view.frame = aview.bounds;
        aview.autoresizesSubviews = YES;
    
    

    相关文章

      网友评论

      • 暴走大牙:UIViewContentModeScaleAspectFit
        这种模式,限制宽高的某一方, 会有黑边。
        如果是竖屏,那就固定宽度, 如果是横屏,那就固定高度。

        这样子说不对,没有说固定哪个的,看下面代码:

        float dH = view_height / video_height;
        float dW = view_width / video_width;
        float dd = MIN(dH, dW); // UIViewContentModeScaleAspectFit 模式取最小
        // fload dd = MAX(dH, dW); // UIViewContentModeScaleAspectFill模式取最大
        float h = (video_height * dd / view_height);
        float w = (video_width * dd / view_width);
        接着用 w,h构造vertices
        vertices[0] = -w;
        vertices[1] = -h;
        vertices[2] = -w;
        vertices[3] = h;
        vertices[4] = w;
        vertices[5] = -h;
        vertices[6] = w;
        vertices[7] = h;
        一般都是通过vertices 来实现,也可以通过vertices 和 texturecor 配合来实现。

      本文标题:ijkplayer自适应旋转

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