ijkplayer自适应旋转

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;

你可能感兴趣的:(ijkplayer自适应旋转)