@ohmi/react-native-video
TypeScript icon, indicating that this package has built-in type declarations

5.2.1-0.2.41 • Public • Published

模板版本:v0.2.2

react-native-video

Supported platforms License

[!TIP] Gitee 地址

安装与使用

请到三方库的 Releases 发布地址查看配套的版本信息:@ohmi/react-native-video Releases 。对于未发布到npm的旧版本,请参考安装指南安装tgz包。

进入到工程目录并输入以下命令:

npm

npm install @ohmi/react-native-video

yarn

yarn add @ohmi/react-native-video

下面的代码展示了这个库的基本使用场景:

[!WARNING] 使用时 import 的库名不变。

import React, {useState, useRef} from "react";
import {View, ScrollView, StyleSheet, Text, TextInput} from "react-native";
import RNCVideo from "react-native-video";

function RNCVideoDemo() {
    const [muted, setMuted] = useState(true);
    const [paused, setPaused] = useState(false);
    const [repeat, setRepeat] = useState(true);
    const [controls, setControls] = useState(false);
    const [disableFocus, setDisableFocus] = useState(false);
    const [uri, setUri] = useState(
        "https://res.vmallres.com//uomcdn/CN/cms/202210/C75C7E20060F3E909F2998E13C3ABC03.mp4"
    );
    const [txt, setTxt] = useState("empty");
    const [resizeMode, setResizeMode] = useState("none");
    const [posterResizeMode, setPosterResizeMode] = useState("cover");
    const [seekSec, setSeekSec] = useState(5000);

    const [onVideoLoad, setOnVideoLoad] = useState("onVideoLoad");
    const [onVideoLoadStart, setOnVideoLoadStart] = useState("onVideoLoadStart");
    const [onVideoError, setOnVideoError] = useState("onVideoError");
    const [onVideoProgress, setOnVideoProgress] = useState("onVideoProgress");
    const [onVideoEnd, setOnVideoEnd] = useState("onVideoEnd");
    const [onVideoBuffer, setOnVideoBuffer] = useState("onVideoBuffer");
    const [onPlaybackStalled, setOnPlaybackStalled] = useState("onPlaybackStalled");
    const [onPlaybackResume, setOnPlaybackResume] = useState("onPlaybackResume");

    const videoRef = React.useRef < typeof RNCVideo > ();

    const toggleMuted = () => {
        setMuted((prevMuted) => !prevMuted);
    };

    const toggleControls = () => {
        setControls((prevControls) => !prevControls);
    };

    const togglePaused = () => {
        setPaused((prevPaused) => !prevPaused);
    };

    const toggleRepeat = () => {
        setRepeat((prevRepeat) => !prevRepeat);
    };

    const toggleDisableFocus = () => {
        setDisableFocus((prevDisableFocus) => !prevDisableFocus);
    };

    const firstVideo = () => {
        setUri((prevRepeat) => "https://vjs.zencdn.net/v/oceans.mp4");
    };

    const secondVideo = () => {
        // setUri((prevRepeat) => 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4');
        setUri(
            (prevRepeat) =>
                "https://res.vmallres.com//uomcdn/CN/cms/202210/C75C7E20060F3E909F2998E13C3ABC03.mp4"
        );
    };

    const changeResizeMode = (resizeMode) => {
        setResizeMode((prevResizeMode) => resizeMode);
    };

    return (
        <ScrollView style={styles.container}>
            <View style={styles.container}>
                <Text style={styles.title}>网络视频demo</Text>
                <Text style={styles.labelB}>{onVideoLoad}</Text>
                <Text style={styles.label}>{onVideoError}</Text>
                <Text style={styles.label}>{onVideoLoadStart}</Text>
                <Text style={styles.labelB}>{onVideoProgress}</Text>
                <Text style={styles.label}>{onVideoEnd}</Text>
                <Text style={styles.label}>{onVideoBuffer}</Text>
                <Text style={styles.label}>{onPlaybackStalled}</Text>
                <Text style={styles.label}>{onPlaybackResume}</Text>
                <Text style={styles.title}>update source</Text>
                <View
                    style={{
                        flexDirection: "row",
                        height: 40,
                        padding: 0,
                    }}
                >
                    <Text
                        style={{backgroundColor: "blue", flex: 0.25}}
                        onPress={() => {
                            setUri(
                                "https://res.vmallres.com//uomcdn/CN/cms/202210/C75C7E20060F3E909F2998E13C3ABC03.mp4"
                            );
                            setPosterResizeMode("stretch");
                        }}
                    >
                        切换net:vmallres
                    </Text>
                    <Text
                        style={{backgroundColor: "red", flex: 0.25}}
                        onPress={() => {
                            setUri("https://vjs.zencdn.net/v/oceans.mp4");
                            setPosterResizeMode("contain");
                        }}
                    >
                        切换net:oceans
                    </Text>
                </View>
                <Text style={styles.title}>set resizeMode</Text>
                <View
                    style={{
                        flexDirection: "row",
                        height: 40,
                        padding: 0,
                    }}
                >
                    <Text
                        style={{backgroundColor: "blue", flex: 0.25}}
                        onPress={() => {
                            setResizeMode("none");
                        }}
                    >
                        none
                    </Text>
                    <Text
                        style={{backgroundColor: "red", flex: 0.25}}
                        onPress={() => {
                            setResizeMode("contain");
                        }}
                    >
                        contain
                    </Text>
                    <Text
                        style={{backgroundColor: "yellow", flex: 0.25}}
                        onPress={() => {
                            setResizeMode("stretch");
                        }}
                    >
                        stretch
                    </Text>
                    <Text
                        style={{backgroundColor: "green", flex: 0.25}}
                        onPress={() => {
                            setResizeMode("cover");
                        }}
                    >
                        cover
                    </Text>
                </View>
                <View
                    style={{
                        flexDirection: "row",
                        flexWrap: "wrap",
                        padding: 0,
                    }}
                >
                    <Text style={styles.title}>操作</Text>
                    <TextInput
                        style={styles.prop_input}
                        placeholder="input seek sec number:"
                        multiline={false}
                        maxLength={30}
                        keyboardType="numeric"
                        onChangeText={(text) => {
                            const newText = text.replace(/[^\d]+/, "");
                            setSeekSec(Number(newText));
                        }}
                        autoFocus={false}
                    />
                </View>
                <View
                    style={{
                        flexDirection: "row",
                        flexWrap: "wrap",
                        padding: 0,
                    }}
                >
                    <Text
                        style={styles.button_b}
                        onPress={() => {
                            videoRef.current?.seek(seekSec);
                        }}
                    >
                        seek:{seekSec.toString()}
                    </Text>
                    <Text
                        style={styles.button_b}
                        onPress={() => {
                            togglePaused();
                        }}
                    >
                        paused:{paused.toString()}
                    </Text>
                    <Text
                        style={styles.button_b}
                        onPress={() => {
                            toggleMuted();
                        }}
                    >
                        muted:{muted.toString()}
                    </Text>
                    <Text style={styles.button_b} onPress={() => {
                        toggleControls()
                    }}>controls:{controls.toString()}</Text>
                    <Text
                        style={styles.button_b}
                        onPress={() => {
                            toggleRepeat();
                        }}
                    >
                        repeat:{repeat.toString()}
                    </Text>
                    <Text
                        style={styles.button_b}
                        onPress={() => {
                            toggleDisableFocus();
                        }}
                    >
                        disableFocus:{disableFocus.toString()}
                    </Text>
                    <Text style={styles.button_b}>
                        ReSizeMode:{resizeMode.toString()}
                    </Text>
                </View>
                <RNCVideo
                    style={styles.video}
                    ref={videoRef}
                    source={{uri: uri, isNetwork: true}}
                    paused={paused}
                    muted={muted}
                    resizeMode={resizeMode}
                    controls={controls}
                    repeat={repeat}
                    volume={1}
                    disableFocus={disableFocus}
                    poster={
                        "https://res.vmallres.com/pimages/uomcdn/CN/pms/202304/sbom/4002010007801/group/800_800_9B1356F1330EADDCB20D35D2AE1F46E0.jpg"
                    }
                    posterResizeMode={posterResizeMode}
                    onLoad={(e) => {
                        setOnVideoLoad(
                            "onVideoLoad currentTime =" +
                            e.currentPosition +
                            "s duration =" +
                            e.duration +
                            "s width =" +
                            e.naturalSize.width +
                            " orientation =" +
                            e.naturalSize.orientation
                        );
                        setOnVideoError("onVideoError error = ok");
                    }}
                    onLoadStart={(e) => {
                        setOnVideoLoadStart(
                            "onVideoLoadStart isNetwork =" +
                            e.isNetwork +
                            " type=" +
                            e.type +
                            " uri=" +
                            e.uri
                        );
                    }}
                    onProgress={(e) => {
                        setOnVideoProgress(
                            "onVideoProgress currentTime =" +
                            e.currentTime +
                            " playableDuration=" +
                            e.playableDuration +
                            " seekableDuration=" +
                            e.seekableDuration
                        );
                    }}
                    onError={(e) => {
                        setOnVideoError("onVideoError error =" + e.error);
                    }}
                    onEnd={() => {
                        setOnVideoEnd("onVideoEnd completed");
                    }}
                    onBuffer={(e) => {
                        setOnVideoBuffer("onVideoBuffer :" + e.isBuffering);
                    }}
                    onPlaybackStalled={() => {
                        setOnPlaybackStalled("onPlaybackStalled : true");
                        setOnPlaybackResume("onPlaybackResume :false");
                    }}
                    onPlaybackResume={() => {
                        setOnPlaybackStalled("onPlaybackStalled :false");
                        setOnPlaybackResume("onPlaybackResume :true");
                    }}
                    onReadyForDisplay={() => {
                        console.log(`onReadyForDisplay :setShowPoster(false)`);
                    }}
                />
            </View>
        </ScrollView>
    );
}

const styles = StyleSheet.create({
    video: {
        width: "100%",
        height: 260,
    },
    container: {
        width: "100%",
        height: "100%",
        backgroundColor: "#f8f8f8",
    },
    title: {
        color: "white",
        width: "30%", // hack
        height: 30, // hack
    },
    label: {
        color: "gray",
        width: "100%", // hack
        minHeight: 20,
    },
    labelB: {
        color: "gray",
        width: "100%", // hack
        minHeight: 40,
    },
    button: {
        width: 160,
        height: 36,
        backgroundColor: "hsl(190, 50%, 70%)",
        paddingHorizontal: 16,
        paddingVertical: 8,
        borderRadius: 8,
    },
    buttonText: {
        width: "100%",
        height: "100%",
        fontWeight: "bold",
    },
    button_b: {
        paddingHorizontal: 8,
        paddingVertical: 6,
        borderRadius: 4,
        backgroundColor: "oldlace",
        alignSelf: "flex-start",
        marginHorizontal: "1%",
        marginBottom: 6,
        minWidth: "25%",
        minHeight: 20,
        textAlign: "center",
    },
    prop_input: {
        width: 160,
        height: 40,
        borderWidth: 1,
        backgroundColor: "white",
        color: "black",
        borderRadius: 8,
    },
});

export default RNCVideoDemo;

Link

目前 HarmonyOS 暂不支持 AutoLink,所以 Link 步骤需要手动配置。

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony

1.在工程根目录的 oh-package.json5 添加 overrides 字段

{
  ...
  "overrides": {
    "@rnoh/react-native-openharmony": "./react_native_openharmony"
  }
}

2.引入原生端代码

目前有两种方法:

  1. 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
  2. 直接链接源码。

方法一:通过 har 包引入(推荐)

[!TIP] har 包位于三方库安装路径的 harmony 文件夹下。

打开 entry/oh-package.json5,添加以下依赖

"dependencies": {
...
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
"@react-native-oh-tpl/react-native-video": "file:../../node_modules/@ohmi/react-native-video/harmony/rn_video.har"
}

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

方法二:直接链接源码

[!TIP] 如需使用直接链接源码,请参考直接链接源码说明

3.配置 CMakeLists 和引入 RNCVideoPackage

打开 entry/src/main/cpp/CMakeLists.txt,添加:

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@ohmi/react-native-video/src/main/cpp" ./video)
# RNOH_BEGIN: manual_package_linking_1

file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")

add_library(rnoh_app SHARED
    ${GENERATED_CPP_FILES}
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_video)
# RNOH_END: manual_package_linking_2

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SamplePackage.h"
+ #include "RNCVideoPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
      std::make_shared<RNOHGeneratedPackage>(ctx),
      std::make_shared<SamplePackage>(ctx),
+     std::make_shared<RNCVideoPackage>(ctx)
    };
}

4.在 ArkTs 侧引入 RNCVideo 组件

找到 function buildCustomComponent(),一般位于 entry/src/main/ets/pages/index.etsentry/src/main/ets/rn/LoadBundle.ets,添加:

  ...
+ import { RNCVideo, RNC_VIDEO_TYPE } from "@ohmi/react-native-video"

@Builder
function buildCustomRNComponent(ctx: ComponentBuilderContext) {
  ...
+ if (ctx.componentName === RNC_VIDEO_TYPE) {
+   RNCVideo({
+     ctx: ctx.rnComponentContext,
+     tag: ctx.tag
+   })
+ }
 ...
}
...

[!TIP] 本库使用了混合方案,需要添加组件名。

entry/src/main/ets/pages/index.etsentry/src/main/ets/rn/LoadBundle.ets 找到常量 arkTsComponentNames 在其数组里添加组件名

const arkTsComponentNames: Array<string> = [
  ...
+ RNC_VIDEO_TYPE
  ];

5.在 ArkTs 侧引入 RNCVideoPackage

打开 entry/src/main/ets/RNPackagesFactory.ts,添加:

  ...
+ import { RNCVideoPackage } from '@ohmi/react-native-video/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
    new SamplePackage(ctx),
+   new RNCVideoPackage(ctx)
  ];
}

6.运行

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

然后编译、运行即可。

兼容性

要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。

请到三方库相应的 Releases 发布地址查看 Release 配套的版本信息:@ohmi/react-native-video Releases

权限与要求

  • 由于此库涉及后台播放,需要配置后台运行权限,权限需配置在entry/src/main目录下module.json5文件中。具体权限配置见文档:程序访问控制

  • 此库后台播放功能需要添加权限:ohos.permission.KEEP_BACKGROUND_RUNNING,还需配置后台播放模式:

    "abilities": [
       {
        "backgroundModes": ["audioPlayback"]
       }
    ]
    

属性

详情请查看react-native-video 官方文档

[!TIP] "Platform"列表示该属性在原三方库上支持的平台。

[!TIP] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

Name 描述 Type Required Platform HarmonyOS Support
disableFocus 确定视频音频是否应覆盖 Android 和 HarmonyOS 设备中的背景音乐/音频。
false (默认) - 不覆盖背景音乐/音频
boolean No Android Exoplayer yes
muted 控制音频是否静音。
false (默认) - 不静音
boolean No All yes
paused 控制媒体是否暂停。
false (默认) - 不暂停媒体
boolean No All yes
repeat 确定是否在视频结束时重复播放。
false (默认) - 不重复播放
boolean No All yes
resizeMode 确定当帧与原始视频尺寸不匹配时如何调整视频大小。
"none" (默认) - 不应用调整大小
string No Android ExoPlayer, Android MediaPlayer, iOS, Windows UWP yes
volume 调整音量。
1.0 (默认) - 以全音量播放
number No All yes
poster 在视频加载时显示的图像
值:包含海报 URL 的字符串,例如 "https://baconmockup.com/300/200/"
string No All yes
posterResizeMode 确定当帧与原始视频尺寸不匹配时如何调整海报图像大小。
"contain" (默认) - 按比例缩放图像(保持图像的宽高比),使得图像的宽度和高度都小于或等于视图的相应维度(减去内边距)。
string No All yes
allowsExternalPlayback 指示播放器是否允许切换到外部播放模式,例如 AirPlay 或 HDMI。 boolean No iOS No
audioOnly 指示播放器是否仅播放音频轨道,并且显示海报而不是视频轨道。 boolean No All No
onPlaybackStalled 缓冲开始时的回调,控制加载视图的显示 boolean No Android No
onPlaybackResume 缓存结束时的回调,控制加载视图的隐藏 boolean No Android No
automaticallyWaitsToMinimizeStalling 布尔值,指示播放器是否应自动延迟播放以最小化卡顿。适用于链接到 iOS 10.0 及更高版本的客户端 boolean No iOS No
bufferConfig 调整缓冲设置。此属性接受包含以下一个或多个属性的对象。 object No Android No
controls 确定是否显示播放器控件。 boolean No All yes
currentPlaybackTime 当播放带有 EXT-X-PROGRAM-DATE-TIME 标签配置的 HLS 实时流时,此属性将包含以毫秒为单位的纪元值。 string No All No
filter 添加视频滤镜 string No iOS No
filterEnabled 启用视频滤镜。 string No iOS No
fullscreen 控制播放时是否进入全屏模式。 boolean No iOS No
fullscreenAutorotate 如果设置了首选全屏方向,则会导致视频旋转到该方向,但允许用户持有的屏幕方向旋转。默认为 TRUE。 boolean No iOS No
fullscreenOrientation 设置全屏方向。 string No iOS No
headers 将标头传递给 HTTP 客户端。可用于授权。标头必须是源对象的一部分。 object No Android No
hideShutterView 控制是否启用 ExoPlayer 快门视图(加载时的黑屏)。 boolean No Android No
id 设置 DOM id 元素,以便可以在 Web 平台上使用 document.getElementById。接受字符串值。 string No All No
ignoreSilentSwitch 控制 iOS 静音开关的行为 string No iOS No
maxBitRate 设置网络带宽消耗的期望限制(以每秒比特数为单位),当播放列表中有多个视频流可用时。 number No All No
minLoadRetryCount 设置在失败并报告错误给应用程序之前最少重试加载数据的次数。有助于恢复短暂的互联网故障。 number No Android No
mixWithOthers 控制音频与其他应用程序的混合方式。 string No iOS No
pictureInPicture 确定媒体是否作为画中画播放。 boolean No iOS No
playInBackground 确定媒体是否在应用程序处于后台时继续播放。这允许客户继续收听音频。 boolean No All yes
playWhenInactive 确定媒体是否在通知或控制中心位于视频前面时继续播放。 boolean No iOS No
preferredForwardBufferDuration 播放器在网络中缓冲媒体的时间长度,以防止播放中断。设置 AVPlayerItem 的 preferredForwardBufferDuration 实例属性。 number No iOS No
preventsDisplaySleepDuringVideoPlayback 控制在播放视频时是否允许显示器休眠。默认不允许显示器休眠。 boolean No All No
progressUpdateInterval onProgress 事件之间的延迟,以毫秒为单位。 number No iOS No
rate 媒体播放的速度。 number No All yes
reportBandwidth 确定是否生成 onBandwidthUpdate 事件。这是由于 ExoPlayer 上这些事件的频率较高而需要的。 boolean No Android No
selectedAudioTrack 配置要播放的音频轨道(如果有)。 object No All No
selectedTextTrack 配置要显示的文本轨道(字幕或隐藏字幕)(如果有)。 object No All No
selectedVideoTrack 配置要播放的视频轨道。默认情况下,播放器使用自适应比特率流技术,根据可用带宽自动选择其认为性能最佳的流。 object No Android No
stereoPan 调整左右音频通道的平衡。接受 –1.0 到 1.0 之间的任何值。 number No Android No
textTracks 加载一个或多个“旁白”文本轨道。此属性接受代表每个轨道的对象数组。 object No All No
trackId 配置视频流的标识符,以将播放上下文链接到发出的事件。 string No Android No
useTextureView 控制是否输出到 TextureView 或 SurfaceView。 boolean No Android No

事件回调

[!TIP] "Platform"列表示该属性在原三方库上支持的平台。

[!TIP] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

Name 描述 Type Required Platform HarmonyOS Support
onLoad 媒体加载并准备好播放时调用的回调函数。 function No All yes
onLoadStart 媒体开始加载时调用的回调函数。 function No All yes
onReadyForDisplay 第一帧视频准备好显示时调用的回调函数。这就是移除海报的时候。 function No Android ExoPlayer, Android MediaPlayer, iOS, Web yes
onProgress 每隔 progressUpdateInterval 秒调用一次的回调函数,提供当前播放位置的信息。 function No All yes
onEnd 播放器到达媒体结尾时调用的回调函数。 function No All yes
onError 播放器遇到播放错误时调用的回调函数。 function No All yes
onBuffer 播放器缓冲时调用的回调函数。 function No Android, iOS yes
onPlaybackStalled MediaPlayer MEDIA_INFO_BUFFERING_START 的回调函数 function No Android MediaPlayer yes
onPlaybackResume MediaPlayer MEDIA_INFO_BUFFERING_END 的回调函数 function No Android MediaPlayer yes
onAudioBecomingNoisy 当音频因音频输出变化即将变得“嘈杂”时调用的回调函数。通常是在音频输出从外部来源(如耳机)切换回内部扬声器时调用。在这种情况下,最好暂停媒体以免扬声器突然开始大声播放声音。 function No All No
onBandwidthUpdate 当可用带宽发生变化时调用的回调函数。 function No Android No
onExternalPlaybackChange 当前播放视频的外部播放模式发生更改时调用的回调函数。主要用于连接/断开 Apple TV 时——在连接/断开时调用。 function No iOS No
onFullscreenPlayerWillPresent 播放器即将进入全屏模式时调用的回调函数。 function No All No
onFullscreenPlayerDidPresent 播放器已进入全屏模式时调用的回调函数。 function No All No
onFullscreenPlayerWillDismiss 播放器即将退出全屏模式时调用的回调函数。 function No All No
onFullscreenPlayerDidDismiss 播放器已退出全屏模式时调用的回调函数。 function No All No
onPictureInPictureStatusChanged 当画中画变为活动或非活动状态时调用的回调函数。 function No IOS No
onPlaybackRateChange 播放速率更改时调用的回调函数——无论是暂停还是开始/恢复。 function No All yes
onSeek 寻找完成时调用的回调函数。 function No All yes
onRestoreUserInterfaceForPictureInPictureStop 对应于 Apple 的 restoreUserInterfaceForPictureInPictureStopWithCompletionHandler。在此函数中调用 restoreUserInterfaceForPictureInPictureStopCompleted 以完成用户界面恢复。 function No iOS No
onTimedMetadata 当定时元数据可用时调用的回调函数 function No All No

静态方法

[!TIP] "Platform"列表示该属性在原三方库上支持的平台。

[!TIP] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

Name 描述 Type Required Platform HarmonyOS Support
seek() 跳转到由秒表示的指定位置。seconds 是一个浮点值。 function No All yes
dismissFullscreenPlayer() 退出全屏模式。 function No All No
presentFullscreenPlayer() 进入全屏模式。 function No All No
save() 使用当前滤镜属性将视频保存到照片中。返回 promise。 function No iOS No
restoreUserInterfaceForPictureInPictureStop() 对应于 Apple 的恢复用户界面 ForPictureInPictureStop 完成处理程序。重要提示:必须在调用 onRestoreUserInterfaceForPictureInPictureStop 后调用此函数。 function No iOS No

遗留问题

  • [x] source 暂时只支持在线 URL 资源问题: issue#34
  • [x] react-native-video 部分属性和方法未实现 HarmonyOS 化: issue#60

其他

开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。

/@ohmi/react-native-video/

    Package Sidebar

    Install

    npm i @ohmi/react-native-video

    Weekly Downloads

    69

    Version

    5.2.1-0.2.41

    License

    MIT

    Unpacked Size

    483 kB

    Total Files

    129

    Last publish

    Collaborators

    • mangocc
    • kaworu-nagisa
    • carry5250
    • liufenling
    • inkmu