Skip to content

旋转横屏和竖屏全屏

changsanjiang edited this page Jul 11, 2022 · 8 revisions

In this page


准备工作

功能定义

主要三个概念, 分别如下:

  • 横屏旋转(rotation): 播放器可以从竖屏旋转至横屏, 也可以从横屏旋转至竖屏.
  • 竖屏全屏(fitOnScreen): 播放器从小屏直接撑满屏幕, 并不旋转.
  • 自动选择rotationfitOnScreen
在实际应用中, 我们可能希望播放器能够如下自动选择: 

 当播放竖屏拍摄的视频时(Width < Height), 在点击全屏按钮之后, 选择竖屏全屏(fitOnScreen)而不触发旋转. 
 当播放横屏拍摄的视频时(Width > Height), 在点击全屏按钮之后, 选择横屏旋转(rotation). 

我们将从介绍rotation开始, 接着介绍fitOnScreen, 最后介绍自动选择(默认情况下为自动选择)

Rotation

旋转之自动旋转

正常情况下播放器内部封装的旋转管理类将会随着设备方向改变而触发自动旋转. 配置好旋转后, 开发者在创建好播放器时, 无需进行其他操作即可自带旋转功能.

以下是自动旋转相关的自定义设置:

1. 设置是否可以触发自动旋转

在触发自动旋转之前, 播放器内部已经判断了各种状态, 这足以应付大多数的使用场景. 不过在某些情况下, 我们可能需要加入自己的业务判断来决定是否可以触发旋转, 此时可如下进行操作:

    __weak typeof(self) _self = self;
    _player.shouldTriggerRotation = ^BOOL(__kindof SJBaseVideoPlayer * _Nonnull player) {
        __strong typeof(_self) self = _self;
        if ( !self ) return NO;
        // 此处添加逻辑, 如果可以旋转, 则返回YES, 否之
        // ...
        // ...
        return YES;
    };

2. 禁止自动旋转

自动旋转默认为开启状态, 当需要禁止时, 可如下操作:

    _player.rotationManager.disabledAutorotation = YES;

3. 设置自动旋转时所支持的方向

自动旋转支持的方向默认值为SJOrientationMaskAll, 当需要指定时, 可以如下操作:

    _player.rotationManager.autorotationSupportedOrientations = SJOrientationMaskAll;
//
//    可选值如下:
//    typedef enum : NSUInteger {
//        // 竖屏
//        SJOrientationMaskPortrait = 1 << SJOrientation_Portrait,
//        // 横屏, Home键在右侧
//        SJOrientationMaskLandscapeLeft = 1 << SJOrientation_LandscapeLeft,
//        // 横屏, Home键在左侧
//        SJOrientationMaskLandscapeRight = 1 << SJOrientation_LandscapeRight,
//        // 以上所有方向
//        SJOrientationMaskAll = SJOrientationMaskPortrait | SJOrientationMaskLandscapeLeft | SJOrientationMaskLandscapeRight,
//    } SJOrientationMask;

旋转之如何主动调用旋转

在UI层我们可能会添加旋转按钮, 当点击之后需要主动调用旋转, 此时可能遇到的场景如下:

  • 旋转至当前的设备方向
  • 旋转至指定方向
  • 旋转至指定方向, 并设置完成后的回调

请看以下方法, 分别对应以上三点, 根据场景, 直接调用对应方法即可. 需要注意的是, 和自动旋转不同, 该方法为强制旋转, 调用之后播放器可能会强制修改设备方向, 并触发旋转, 不过它们同样受到_player.shouldTriggerRotation的限制, 当返回NO时, 将不会触发旋转.

- (void)rotate;
- (void)rotate:(SJOrientation)orientation animated:(BOOL)animated;
- (void)rotate:(SJOrientation)orientation animated:(BOOL)animated completion:(void (^ _Nullable)(__kindof SJBaseVideoPlayer *player))block;

旋转之如何监听旋转

播放器提供了旋转之前和旋转完成之后的回调, 具体设置如下:

    __weak typeof(self) _self = self;
    _player.rotationObserver.onRotatingChanged = ^(id<SJRotationManager>  _Nonnull mgr, BOOL isRotating) {
        __strong typeof(_self) self = _self;
        if ( !self ) return ;
        
        // 可根据 mgr.isFullscreen 来判断是否将要旋转至横屏

        if ( isRotating ) { 
            // 旋转开始
        }
        else {
            // 旋转结束
        }
    };

FitOnScreen

竖屏全屏之如何直接全屏及恢复小屏

这块功能比较简单, 主要接口如下:

///
/// 是否已充满屏幕
///
@property (nonatomic, getter=isFitOnScreen) BOOL fitOnScreen;
- (void)setFitOnScreen:(BOOL)fitOnScreen animated:(BOOL)animated;
- (void)setFitOnScreen:(BOOL)fitOnScreen animated:(BOOL)animated completionHandler:(nullable void(^)(id<SJFitOnScreenManager> mgr))completionHandler;

设置为NO, 即为恢复小屏; 设置为YES, 即为全屏, 整个过程并不会触发旋转:

_player.fitOnScreen = YES;

[_player setFitOnScreen:NO animated:NO];

[_player setFitOnScreen:YES animated:YES completionHandler:^(__kindof SJBaseVideoPlayer * _Nonnull player) {
/// ...
}];

竖屏全屏之如何监听状态

播放器提供了设置之前和完成之后的回调, 具体设置如下:

    // 设置之前
    _player.fitOnScreenObserver.fitOnScreenWillBeginExeBlock = ^(id<SJFitOnScreenManager>  _Nonnull mgr) {
       // 可根据 mgr.isFitOnScreen 来判断是否将要全屏
    };
    
    // 完成之后
    _player.rotationObserver.fitOnScreenDidEndExeBlock = ^(id<SJFitOnScreenManager>  _Nonnull mgr) {
        
    };

自动选择

最后是自动选择. 在默认情况下, 播放器将会根据视频资源的宽高自动选择其中一种方式来管理. 也就是一开始介绍的.

这里需要注意的是, 由于默认为自动选择, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.

关闭自动选择

  • 如果仅使用旋转功能, 可如下设置:
    _player.automaticallyPerformRotationOrFitOnScreen = NO;

仅使用竖屏全屏功能, 可如下设置:

该方法将会关闭自动选择, 仅使用竖屏相关功能.

    _player.onlyFitOnScreen = YES;

注意事项

重要的事情说三遍!

  • 由于默认为自动选择, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.
  • 由于默认为自动选择, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.
  • 由于默认为自动选择, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.

补充

竖屏全屏后, 如何允许旋转:

    _player.allowsRotationInFitOnScreen = YES;