hadss_adaptive_video

简介

为视频播放场景提供自适应规则,包括:

  1. 自适应视频沉浸式规则:用于布局视频页面沉浸式体验,针对不同尺寸的窗口和不同尺寸的视频,本规则会为视频的非全屏页面提供沉浸建议。
  2. 自适应视频旋转规则:用于布局视频页面旋转体验,针对不同尺寸的窗口和不同尺寸的视频,本规则会自动设置视频的旋转属性。

工程目录

├─example                            // example工程
│  └─lib
│     ├── full_screen_video_page.dart   // 全屏视频页面
│     ├── main.dart                     // example主入口
│     └── video_page.dart                   // 视频浏览页 
│                   
├─lib
│  ├── hadss_adaptive_video.dart
│  ├── immersion
│  |      ├── adaptive_immersion.dart      // 自适应沉浸规则
|  |      └── immersion_rules.dart              // 沉浸规则
|  └── rotation
|         ├── api
|         |     └── device_orientation_api.dart // 使用原生接口改变设备方向API
|         ├── adaptive_rotation.dart       // 自适应旋转规则
|         ├── breakpoint                        // 断点
|         |     ├── breakpoint.dart
|         |     └── breakpoint_manager.dart
|         └── rotation_rules.dart               // 旋转规则

安装与使用

运行前准备

flutter pub get
cd example

移动设备运行

flutter run

Web端运行

flutter run -d chrome --web-hostname=127.0.0.1

自适应规则说明

沉浸规则

自适应沉浸式规则适用于视频滑动播放页面,为用户提供沉浸式播放效果。沉浸状态下视频播放组件的尺寸大小、窗口位置及沉浸建议基于当前应用窗口大小计算,因此视频播放组件需要与其他组件进行适当的布局适配。

具体规则如下:

沉浸效果图

沉浸规则适用于视频宽高比是9:16的视频,其他比例的视频均遵循默认沉浸规则。

规则序号 视频尺寸(宽高比) 窗口宽高比X的范围 行为描述
1 9:16 0 <= x < 9:20 窗口高度减去底部tab高度,状态栏高度之后,等比例缩放视频至视频可视区域宽高比为9:17.8,并居中显示在剩余区域,左右超出窗口部分自适应裁剪
2 9:16 9:20 <= x < 9:18 窗口高度减去底部tab高度后,
1、剩余区域宽高比y >= 9:16,视频将窗口宽撑满,上下超出窗口部分自适应裁剪;
2、剩余区域宽高比y < 9:16,视频从窗口顶部将剩余区域高撑满,等比例缩放视频,最大缩放至可视区域宽高比为9:17.8,若剩余区域还有未被覆盖的区域,不做处理,左右超出窗口部分自适应裁剪
3 9:16 9:18 <= x < 9:14.4 1、9:18 < x <= 9:16:视频将窗口高撑满,上下根据窗口大小决定是否裁剪;
2、9:16 < x <= 9:14.4:高撑满,左右根据窗口大小决定是否裁剪
4 9:16 9:14.4 <= x < 9:10.8 视频将窗口高撑满,视频宽自适应等比例缩放
5 9:16 9:10.8 <= x < 9:7.2 视频将窗口高撑满,视频宽自适应等比例缩放
6 9:16 9:7.2 <= x 视频将窗口高撑满,视频宽自适应等比例缩放
7 其他视频尺寸(宽高比)z 任意窗口尺寸(宽高比)y 默认沉浸规则:窗口高度减去底部导航栏和状态栏高度,剩余区域宽高比 y >= z(视频宽高比)时,视频将剩余区域高撑满,视频宽自适应等比例缩放;反之宽度将剩余区域宽撑满,视频高自适应等比例缩放

沉浸规则接口说明

AdaptiveImmersion视频适配沉浸

名称 参数 返回值 说明
getImmersionInfo BuildContext: context, Size videoSize, double bottomTabHeight ImmersionInfo 根据视频尺寸和底部导航高度计算最优沉浸式布局参数。

ImmersionInfo沉浸信息

字段 类型 说明
videoSize Size 视频原生尺寸
videoPosition Offset 视频在屏幕上的显示位置(x, y 坐标)
immersionSettings ImmersionSettings 沉浸式设置(状态栏和底部标签栏是否沉浸)

ImmersionSetting沉浸式设置

字段 类型 说明
isStatusBarImmersion bool 状态栏是否沉浸
isBottomTabImmersion bool 底部标签栏是否沉浸

使用示例:

// 计算沉浸式布局信息
final info = AdaptiveImmersion().getImmersionInfo(context,
  Size(1080, 1920), // 视频原始尺寸
  60.0, // 底部标签栏高度
);

print(info.toString());      // 输出视频沉浸信息

旋转规则

自适应旋转规则适用于视频滑动播放页面、视频全屏播放页面,将为开发者自动设置全屏、非全屏页面下的窗口旋转属性。视频页面的旋转属性基于窗口所在的窗口的屏幕类型( 根据断点区间判定)、视频类型(横向视频、竖向视频,依据视频宽高判定)、屏幕方向( 根据重力判定,依赖开源库motion_sensors ,通过设备旋转角度判断手持的设备方向 ,ohos平台需要授权ohos.permission.ACCELEROMETER)。

具体规则如下:

断点区间图

依据断点区间判定屏幕类型

序号 横向断点 纵向断点 屏幕类型
1 0(XSmall) 0(Small) xSmallLandscape
2 0(XSmall) 1(Medium) xSmallSquare
3 0(XSmall) 2(Large) xSmallPortrait
4 1(Small) 0(Small) smallLandscape
5 1(Small) 1(Medium) smallSquare
6 1(Small) 2(Large) smallPortrait
7 2(Medium) 0(Small) mediumLandscape
8 2(Medium) 1(Medium) mediumSquare
9 2(Medium) 2(Large) mediumPortrait
10 3(Large) 0(Small) largeLandscape
11 3(Large) 1(Medium) largeSquare
12 3(Large) 2(Large) largePortrait
13 4(XLarge) 0(Small) xLargeLandscape
14 4(XLarge) 1(Medium) xLargeSquare
15 4(XLarge) 2(Large) xLargePortrait

依据屏幕类型、视频类型、屏幕方向判定旋转属性

序号 屏幕类型 视频方向(宽>高:横向) 全屏/非全屏浏览场景 旋转属性描述(部分设备不能反向竖屏)
1 smallPortrait,mediumLandscape,smallSquare 竖向 非全屏 临时方向:portraitUp,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp
2 smallPortrait,mediumLandscape 横向 非全屏 临时方向:portraitUp,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp, landscapeRight, landscapeLeft
3 smallSquare 横向 非全屏 临时方向:portraitUp,允许旋转方向,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp
4 mediumPortrait,mediumSquare,largeLandscape,largeSquare,largePortrait,xLargeLandscape 竖向 非全屏 临时方向:跟随系统方向,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp, landscapeRight, landscapeLeft
5 mediumPortrait,mediumSquare,largeLandscape,largeSquare,largePortrait,xLargeLandscape 横向 非全屏 临时方向:跟随系统方向,允许旋转方向,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp, landscapeRight, landscapeLeft
6 smallPortrait,mediumLandscape,smallSquare 竖向 全屏 临时方向:portraitUp,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp
7 mediumPortrait,mediumSquare,largePortrait,largeSquare,largeLandscape,xLargeLandscape 竖向 全屏 临时方向:跟随系统方向,允许旋转方向,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp
8 smallPortrait,mediumLandscape 横向 全屏 临时方向:landscapeLeft,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp, landscapeRight, landscapeLeft
9 smallSquare 横向 全屏 临时方向:portraitUp,允许旋转方向,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp
10 mediumPortrait,mediumSquare,largePortrait,largeSquare,largeLandscape,xLargeLandscape 横向 全屏 临时方向:跟随系统方向,允许旋转方向,允许旋转方向,受到控制中心的自由旋转锁控制:portraitUp, landscapeRight, landscapeLeft

旋转规则接口说明

AdaptiveRotation视频适配旋转

接口名称 参数 返回值 描述
registerEvent void void 注册监听,用于监听设备方向
unregisterEvent void void 注销监听,初始化缓存参数
setGravityUpdateInterval int interval void 设置传感器频率
addRotationListener ScreenRotationCallback listener void 添加屏幕旋转变化回调
removeRotationListener ScreenRotationCallback? listener void 删除屏幕旋转变化回调,传null清空所有回调
pauseEvent void void 进入后台暂停监听
resumeEvent void void 进入前台恢复监听
setNotFullScreen {required Size videoSize, required Size screenSize} void 设置正常浏览视频场景的屏幕旋转属性
setFullScreen {required Size videoSize, required Size screenSize} void 设置全屏播放视频场景的屏幕旋转属性

ScreenRotationCallback屏幕旋转回调监听

接口名称 参数 返回值 描述
ScreenRotationCallback Orientation orientation void 屏幕旋转变化监听

使用示例:

void initState() {
  // 注册监听,用于监听设备方向
  AdaptiveRotation().registerEvent();

  AdaptiveRotation().addRotationListener((Orientation orientation) {
    // 设置屏幕旋转回调
  });

  // 设置正常浏览视频场景的屏幕旋转属性
  AdaptiveRotation().setNotFullScreen(
      videoSize: _videoSize, // 视频尺寸
      screenSize: MediaQuery
          .of(context)
          .size // 窗口尺寸
  );

  // 设置全屏播放视频场景的屏幕旋转属性
  AdaptiveRotation().setFullScreen(
      videoSize: _videoSize, // 视频尺寸
      screenSize: MediaQuery
          .of(context)
          .size // 窗口尺寸
  );
}

void dispose() {
  // 注销监听,初始化缓存参数
  AdaptiveRotation().unregisterEvent();
}

void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (state == AppLifecycleState.resumed) {
    // 应用回到前台,恢复监听
    AdaptiveRotation().resumeEvent();
  } else if (state == AppLifecycleState.paused) {
    // 应用进入后台,暂停监听
    AdaptiveRotation().pauseEvent();
  }
}

约束与限制

  1. 自适应沉浸规则适用于视频宽高比是9:16的视频,其他比例的视频均遵循默认沉浸规则。
  2. 2in1、PC、TV、车机暂定不支持旋转。进入全屏时会根据视频宽高选择**横屏(宽>高)还是竖屏(宽<=高) **。
  3. OpenHarmony SDK: >= API 12。
  4. flutter sdk >= 3.7.12

贡献代码

使用过程中发现任何问题都可以提 Issue
同时,也非常欢迎您提交 PR

开源协议

本项目基于Apache License 2.0 ,请自由地享受和参与开源。