npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hadss/react_native_adaptive_video

v1.0.0-rc.0

Published

RN framework-oriented multi-device adaptive video package

Downloads

9

Readme

@hadss/react_native_adaptive_video

介绍

这是一个旨在解决短视频多设备自适应问题的三方库,专为不同设备类型(包括折叠屏、平板、手机等)提供了便捷的支持。该库包含的接口和开箱即用的组件,使开发者能够轻松应对各种设备的布局适配需求。

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

工程目录

src
├── immersion //  自适应沉浸
│   ├── api
│   │   └── AdaptiveImmersion.ts // 沉浸接口类
│   ├── common
│   │   └── ImmersionConstants.ts // 常量类
│   └── rule
│       └── ImmersionRuleSet.ts // 沉浸规则
├── index.ts // 入口
└── rotation // 自适配旋转
    ├── api
    │   └── AdaptiveRotation.ts // 旋转接口类
    ├── rule
    │   ├── Breakpoint.ts // 断点规则
    │   ├── HarmonyOrientation.ts // HarmonoyOS Orientation 旋转规则
    │   └── RotationDatabase.ts // 旋转规则
    └── utils
        └── SensorUtil.ts // 传感器工具类

使用说明

自适应沉浸库AdaptiveImmersion使用示例

import React from 'react';
import {StyleSheet, View, Text, StatusBar} from 'react-native';
import Video from 'react-native-video';
import {videoImmersionList} from '../../components/videos';
import {AdaptiveImmersion} from '@hadss/react_native_adaptive_video';
import {useFocusEffect} from '@react-navigation/native';
import {
  SafeAreaView,
  useSafeAreaInsets,
  useSafeAreaFrame,
} from '@react-native-oh-tpl/react-native-safe-area-context';

const BOTTOM_TAB_HEIGHT = 50; // dp

const VideoDetail = ({route, navigation}) => {
  const insets = useSafeAreaInsets();
  const frame = useSafeAreaFrame();
  console.log(
    `窗口宽vp:${frame.width} 高vp:${frame.height} 宽高比:${(
      frame.width / frame.height
    ).toFixed(2)} 状态栏高度vp:${
      insets.top
    } 底部栏高度vp:${BOTTOM_TAB_HEIGHT}`,
  );
  const {id} = route.params;
  const video = videoImmersionList[id];

  // 调用单例方法获取沉浸规则:传入视频宽高、当前窗口大小、状态栏高度和底部tab组件高度
  const immersionInfo = AdaptiveImmersion.getInstance().getImmersionInfo(
    {width: video.width, height: video.height},
    {width: frame.width, height: frame.height},
    insets.top,
    BOTTOM_TAB_HEIGHT,
  );
  if (!immersionInfo) {
    throw new Error('get immersionInfo failed');
  }

  // 获取视频播放组件的宽高
  const {width: videoWidth, height: videoHeight} = immersionInfo.videoSize;
  // 获取视频播放组件的位置 x,y (相对屏幕左上角)
  const videoPosition = immersionInfo.videoPosition;

  // 获取底部tab栏是否沉浸
  const opacity = immersionInfo.immersionSetting.isBottomTabImmersive
    ? 0.5
    : 1.0;

  // 获取状态栏是否沉浸
  const isStatusBarImmersive =
    immersionInfo.immersionSetting.isStatusBarImmersive;

  useFocusEffect(
    React.useCallback(() => {
      if (isStatusBarImmersive) {
        // 进入页面时设置状态栏是否沉浸
        StatusBar.setBarStyle('light-content');
        StatusBar.setTranslucent(true);
        StatusBar.setBackgroundColor('transparent');
      }

      return () => {
        if (isStatusBarImmersive) {
          // 退出页面时重置状态栏
          StatusBar.setBarStyle('dark-content');
          StatusBar.setTranslucent(false);
          StatusBar.setBackgroundColor('#ffffff');
        }
      };
    }, [isStatusBarImmersive]),
  );

  return (
    <SafeAreaView style={{flex: 1, position: 'relative'}}>
      <Video
        style={{
          position: 'absolute',
          width: videoWidth, // 设置视频播放组件宽度
          height: videoHeight, // 设置视频播放组件高度
          left: videoPosition.x, // 设置视频播放组件 x 坐标
          top: videoPosition.y, // 设置视频播放组件 y 坐标
          zIndex: 1,
        }}
        source={{uri: `assets://${video.source}`}}
        resizeMode="contain"
        controls={false}
        onError={error => console.log('Video error:', error)}
        repeat={true}
      />
      <View
        style={{
          height: BOTTOM_TAB_HEIGHT,
          width: '100%',
          opacity: opacity,
          backgroundColor: '#999',
          justifyContent: 'center',
          alignItems: 'center',
          position: 'absolute',
          bottom: 0,
          zIndex: 2,
        }}>
        <Text style={styles.myTabText}>底部Tab栏</Text>
      </View>
    </SafeAreaView>
  );
};

自适应旋转库AdaptiveRotation使用示例

import React, {useEffect, useMemo} from 'react';
import {View, StyleSheet, Dimensions, Button} from 'react-native';
import Video from 'react-native-video';
import {videoRotationList as videos} from '../../components/videos';
import {AdaptiveRotation} from '@hadss/react_native_adaptive_video';
import Fold from '@hadss/react_native_adaptive_layout/src';

const VideoSwiper = ({navigation}) => {
  useEffect(() => {
    AdaptiveRotation.getInstance().start(); // 进入播放界面时开启重力监听
    return () => {
      AdaptiveRotation.getInstance().stop(); // 退出页面停止重力监听
    };
  }, []);

  return (
    <View style={{flex: 1}}>
      <Swiper loop={false} horizontal={false} showsPagination={false}>
        {videoRotationList.map(video => (
          <View key={video.id} style={styles.slide}>
            <Video 
              source={{uri: `assets://${videos[id].source}`}}
              style={styles.video}
              resizeMode="contain"
              muted={true}
              repeat={true}
            />
            <Button
              title="进入全屏"
              onPress={() => {
                navigation.navigate('Details', {id: video.id});
                // 调用单例方法进入全屏旋转:传入视频的宽高
                AdaptiveRotation.getInstance().setOrientationFullScreen({
                  width: video.width,
                  height: video.height,
                });
              }}
            />
          </View>
        ))}
      </Swiper>
    </View>
  );
};

// 退出全屏时调用:传入视频的宽高
AdaptiveRotation.getInstance().setOrientationNotFullScreen({
    width: video.width,
    height: video.height,
});

link

本库依赖以下三方库,请查看对应文档:

@react-native-oh-tpl/react-native-orientation-locker @react-native-ohos/react-native-sensors

接口说明

  1. 自适应沉浸

AdaptiveImmersion类: 自适应视频沉浸单例类

| 方法名称 | 参数 | 返回值类型 | 说明 | |-------------------------------|-----------------------------------------------------------------------------------|-------------------|------------------------------------| | AdaptiveImmersion.getInstance | / | AdaptiveImmersion | 静态方法,获取AdaptiveImmersion单例对象 | | getImmersionInfo | videoSize: Size,windowSize:Size, statusBarHeight: number, bottomTabHeight: number | ImmersionInfo | 根据视频宽高、显示窗口大小、状态栏高度和下Tab组件高度获取沉浸信息 |

ImmersionInfo接口: 沉浸状态下的视频页面信息

| 参数名称 | 类型 | 说明 | |------------------|------------------|-----------------------| | videoSize | Size | 视频播放组件的尺寸大小 | | windowSize | Size | 显示窗口大小 | | videoPosition | Position | 视频播放组件的位置(以窗口左上角作为锚点) | | immersionSetting | ImmersionSetting | 状态栏和下Tab栏的沉浸建议 |

ImmersionSetting接口: 状态栏和下tab栏的沉浸建议

| 参数名称 | 类型 | 说明 | |----------------------|---------|-----------| | isStatusBarImmersive | boolean | 状态栏是否沉浸 | | isBottomTabImmersive | boolean | 下tab栏是否沉浸 |

videoSize: Size 作为入参,表示视频的宽高

| 参数名称 | 类型 | 说明 | |----------------------|---------|---------| | width | number | 输入视频的宽度 | | height | number | 输入视频的高度 |

videoSize: Size 作为返回值,表示视频播放组件的宽高

| 参数名称 | 类型 | 说明 | |----------------------|---------|-----------| | width | number | 视频播放组件的宽度 | | height | number | 视频播放组件的高度 |

windowSize: Size 显示窗口大小

| 参数名称 | 类型 | 说明 | |----------------------|---------|-------| | width | number | 窗口的宽度 | | height | number | 窗口的高度 |

videoPosition: Position 表示视频播放组件的布局坐标

| 参数名称 | 类型 | 说明 | |----|---------|--------------| | x | number | 视频播放组件的x坐标(相对屏幕左上角) | y | number | 视频播放组件的y坐标(相对屏幕左上角)

  1. 自适应旋转

AdaptiveRotation类: 自适应视频旋转单例类

| 方法名称 | 参数 | 返回值类型 | 说明 | |------------------------------|-----------------|------------------|-----------------------------| | AdaptiveRotation.getInstance | / | AdaptiveRotation | 静态方法,获取AdaptiveRotation单例对象 | | start | | | 开启自适应旋转重力监听 |
| stop | | | 结束自适应旋转重力监听 |
| setOrientationNotFullScreen | videoSize: Size | / | 非全屏、退出全屏时调用,根据视频宽高自动设置旋转属性 | | setOrientationFullScreen | videoSize: Size | / | 进入全屏时调用,根据视频宽高自动设置旋转属性 | | reset | | / | 重置到初始默认旋转方向 |

videoSize: Size 表示输入视频的宽高

| 参数名称 | 类型 | 说明 | |----------------------|---------|---------| | width | number | 输入视频的宽度 | | height | number | 输入视频的高度 |

自适应规则说明

  1. 沉浸规则
  • 自适应沉浸式规则适用于视频滑动播放页面,为用户提供沉浸式视频播放效果。

具体规则如下:

沉浸效果图

沉浸式规则

| 序号 | 视频宽高比 z | 窗口宽高比 x | 沉浸规则描述 | |----|---------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 | 9:16 | 0 <= x < 9:20 | 窗口高度减去底部导航栏高度,状态栏高度后,等比例缩放视频至视频可视区域宽高比为9:17.8,并居中显示在剩余区域,左右超出窗口部分自适应裁剪 | | 2 | 9:16 | 9:20 <= x < 9:18 | 窗口高度减去底部导航栏高度后,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.9 | 视频将窗口高撑满,视频宽自适应等比例缩放 | | 5 | 9:16 | 9.9 <= x | 视频将窗口高撑满,视频宽自适应等比例缩放 | | 6 | 非9:16 | | 默认沉浸规则: 窗口高度减去底部导航栏高度和状态栏高度后, 1、剩余显示区域宽高比 y >= z,视频将剩余区域高撑满,视频宽自适应等比例缩放;2、剩余显示区域宽高比 y < z,视频将剩余区域宽撑满,视频高自适应等比例缩放 |

  1. 旋转规则
  • 自适应旋转规则适用于视频滑动播放页面、视频全屏播放页面,可自动设置全屏、非全屏页面下的窗口旋转属性。
  • 本框架接口在被调用时将会根据传入的视频宽高自动判定视频类型:横屏视频(宽>高)竖屏视频(宽<=高)
  • 视频页面的旋转属性基于视频所在窗口的屏幕类型(根据断点区间判定)、视频类型(横向视频、竖向视频)、屏幕方向(重力判定)综合判定
  • 使用时可选择是否自动监听可折叠设备的形态变化,如选择监听,可自动适配可折叠设备在播放视频时设备形态改变后的旋转属性。
  • 2in1、PC、TV、车机暂定不支持旋转。

具体规则如下:

断点区间图

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

| 序号 | 横向断点 | 纵向断点 | 屏幕类型 | |----|-----------|-----------|------------------| | 1 | 0(XSmall) | 0(Small) | XSmall_Landscape | | 2 | 0(XSmall) | 1(Medium) | XSmall_Square | | 3 | 0(XSmall) | 2(Large) | XSmall_Portrait | | 4 | 1(Small) | 0(Small) | Small_Landscape | | 5 | 1(Small) | 1(Medium) | Small_Square | | 6 | 1(Small) | 2(Large) | Small_Portrait | | 7 | 2(Medium) | 0(Small) | Medium_Landscape | | 8 | 2(Medium) | 1(Medium) | Medium_Square | | 9 | 2(Medium) | 2(Large) | Medium_Portrait | | 10 | 3(Large) | 0(Small) | Large_Landscape | | 11 | 3(Large) | 1(Medium) | Large_Square | | 12 | 3(Large) | 2(Large) | Large_Portrait | | 13 | 4(XLarge) | 0(Small) | XLarge_Landscape | | 14 | 4(XLarge) | 1(Medium) | XLarge_Square | | 15 | 4(XLarge) | 2(Large) | XLarge_Portrait |

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

屏幕方向(0 - 竖屏, 1 - 反向横屏, 2 - 反向竖屏, 3 - 横屏)

| 序号 | 屏幕类型 | 视频类型 | 进入全屏/退出全屏 | 旋转属性(视频方向:属性) | 旋转属性描述 | |----|------------------------------------------------------------------------------------------------------|------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 | Small_Portrait, Medium_Landscape | 横向视频 | 进入全屏(横屏) | 0:window.Orientation.USER_ROTATION_LANDSCAPE,1:window.Orientation.USER_ROTATION_LANDSCAPE_INVERTED,2:window.Orientation.USER_ROTATION_LANDSCAPE,3:window.Orientation.USER_ROTATION_LANDSCAPE | USER_ROTATION_LANDSCAPE: 调用时临时旋转到横屏,之后跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定(如在某种设备,可以旋转到竖屏、横屏、反向横屏三个方向,无法旋转到反向竖屏)。USER_ROTATION_LANDSCAPE_INVERTED: 调用时临时旋转到反向横屏,之后跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定(如在某种设备,可以旋转到竖屏、横屏、反向横屏三个方向,无法旋转到反向竖屏)。 | | 2 | Small_Portrait, Medium_Landscape, Small_Square | 竖向视频 | 进入全屏(竖屏) | 0:window.Orientation.PORTRAIT,1:window.Orientation.PORTRAIT,2:window.Orientation.PORTRAIT,3:window.Orientation.PORTRAIT | PORTRAIT: 表示竖屏显示模式。 | | 3 | Small_Portrait, Medium_Landscape | 横向视频 | 非全屏 | 0:window.Orientation.USER_ROTATION_PORTRAIT,1:window.Orientation.USER_ROTATION_PORTRAIT,2:window.Orientation.USER_ROTATION_PORTRAIT,3:window.Orientation.USER_ROTATION_PORTRAIT | USER_ROTATION_PORTRAIT:调用时临时旋转到竖屏,之后跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定(如在某种设备,可以旋转到竖屏、横屏、反向横屏三个方向,无法旋转到反向竖屏)。 |
| 4 | Small_Portrait, Medium_Landscape, Small_Square | 竖向视频 | 非全屏 | 0:window.Orientation.PORTRAIT,1:window.Orientation.PORTRAIT,2:window.Orientation.PORTRAIT,3:window.Orientation.PORTRAIT | PORTRAIT: 表示竖屏显示模式。 | | 5 | Small_Square | 横向视频 | 非全屏 | 0:window.Orientation.PORTRAIT,1:window.Orientation.PORTRAIT,2:window.Orientation.PORTRAIT,3:window.Orientation.PORTRAIT | PORTRAIT: 表示竖屏显示模式。 | | 6 | Small_Square | 横向视频 | 全屏 | 0:window.Orientation.PORTRAIT,1:window.Orientation.PORTRAIT,2:window.Orientation.PORTRAIT,3:window.Orientation.PORTRAIT | PORTRAIT: 表示竖屏显示模式。 | | 7 | Medium_Portrait, Medium_Square, Large_Portrait, Large_Landscape, Large_Square, XLarge_Landscape | 横向视频 | 进入全屏(横屏) | 0:window.Orientation.AUTO_ROTATION_UNSPECIFIED,1:window.Orientation.AUTO_ROTATION_UNSPECIFIED,2:window.Orientation.AUTO_ROTATION_UNSPECIFIED,3:window.Orientation.AUTO_ROTATION_UNSPECIFIED | AUTO_ROTATION_UNSPECIFIED :跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定(如在某种设备,可以旋转到竖屏、横屏、反向横屏三个方向,无法旋转到反向竖屏)。 | | 8 | Medium_Portrait, Medium_Square, Large_Portrait, Large_Landscape, Large_Square, XLarge_Landscape | 竖向视频 | 进入全屏(竖屏) | 0:window.Orientation.AUTO_ROTATION_UNSPECIFIED,1:window.Orientation.AUTO_ROTATION_UNSPECIFIED,2:window.Orientation.AUTO_ROTATION_UNSPECIFIED,3:window.Orientation.AUTO_ROTATION_UNSPECIFIED | AUTO_ROTATION_UNSPECIFIED :跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定(如在某种设备,可以旋转到竖屏、横屏、反向横屏三个方向,无法旋转到反向竖屏)。 | | 9 | Medium_Portrait, Medium_Square, Large_Portrait, Large_Landscape, Large_Square, XLarge_Landscape | 横向视频 | 非全屏 | 0:window.Orientation.AUTO_ROTATION_UNSPECIFIED,1:window.Orientation.AUTO_ROTATION_UNSPECIFIED,2:window.Orientation.AUTO_ROTATION_UNSPECIFIED,3:window.Orientation.AUTO_ROTATION_UNSPECIFIED | AUTO_ROTATION_UNSPECIFIED :跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定(如在某种设备,可以旋转到竖屏、横屏、反向横屏三个方向,无法旋转到反向竖屏)。 |
| 10 | Medium_Portrait, Medium_Square, Large_Portrait, Large_Landscape, Large_Square, XLarge_Landscape | 竖向视频 | 非全屏 | 0:window.Orientation.AUTO_ROTATION_UNSPECIFIED,1:window.Orientation.AUTO_ROTATION_UNSPECIFIED,2:window.Orientation.AUTO_ROTATION_UNSPECIFIED,3:window.Orientation.AUTO_ROTATION_UNSPECIFIED | AUTO_ROTATION_UNSPECIFIED :跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定(如在某种设备,可以旋转到竖屏、横屏、反向横屏三个方向,无法旋转到反向竖屏)。 |

约束与限制

本示例仅支持标准系统上运行,支持设备:华为手机。 DevEco Studio版本:DevEco Studio NEXT Developer Beta5及以上。 SDK版本:API13及以上。