5.2.1-0.2.41 • Published 6 months ago

@ohmi/react-native-video v5.2.1-0.2.41

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

模板版本:v0.2.2

!TIP(https://gitee.com/kunyuan-hongke/react-native-video)

安装与使用

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

事件回调

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

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

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

静态方法

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

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

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

遗留问题

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

其他

开源协议

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