视频
React Native Skia 提供了一种将视频帧加载为图像的方法,从而在您的应用程序中实现丰富的多媒体体验。视频帧可以用于任何接受 Skia 图像的地方:Image
、ImageShader
和 Atlas
。Web 也支持视频。
要求
- Reanimated 版本 3 或更高版本。
- Android: API 级别 26 或更高版本。
示例
以下是如何在 React Native Skia 中使用视频支持的示例。此示例演示如何在画布中加载和显示视频帧,并应用颜色矩阵以获得视觉效果。点击屏幕将暂停和播放视频。
视频可以是远程 (http://...
) 或本地 URL (file://
),也可以是来自捆绑包的视频。
tsx
importReact from "react";import {Canvas ,ColorMatrix ,Fill ,ImageShader ,useVideo } from "@shopify/react-native-skia";import {Pressable ,useWindowDimensions } from "react-native";import {useSharedValue } from "react-native-reanimated";export constVideoExample = () => {constpaused =useSharedValue (false);const {width ,height } =useWindowDimensions ();const {currentFrame } =useVideo ("https://bit.ly/skia-video",{paused ,});return (<Pressable style ={{flex : 1 }}onPress ={() => (paused .value = !paused .value )}><Canvas style ={{flex : 1 }}><Fill ><ImageShader image ={currentFrame }x ={0}y ={0}width ={width }height ={height }fit ="cover"/><ColorMatrix matrix ={[0.95, 0, 0, 0, 0.05, 0.65, 0, 0, 0, 0.15, 0.15, 0, 0, 0, 0.5, 0,0, 0, 1, 0,]}/></Fill ></Canvas ></Pressable >);};
tsx
importReact from "react";import {Canvas ,ColorMatrix ,Fill ,ImageShader ,useVideo } from "@shopify/react-native-skia";import {Pressable ,useWindowDimensions } from "react-native";import {useSharedValue } from "react-native-reanimated";export constVideoExample = () => {constpaused =useSharedValue (false);const {width ,height } =useWindowDimensions ();const {currentFrame } =useVideo ("https://bit.ly/skia-video",{paused ,});return (<Pressable style ={{flex : 1 }}onPress ={() => (paused .value = !paused .value )}><Canvas style ={{flex : 1 }}><Fill ><ImageShader image ={currentFrame }x ={0}y ={0}width ={width }height ={height }fit ="cover"/><ColorMatrix matrix ={[0.95, 0, 0, 0, 0.05, 0.65, 0, 0, 0, 0.15, 0.15, 0, 0, 0, 0.5, 0,0, 0, 1, 0,]}/></Fill ></Canvas ></Pressable >);};
返回值
useVideo
Hook 返回 currentFrame
,其中包含当前视频帧,以及 currentTime
、rotation
和 size
。
播放选项
下表描述了 useVideo
Hook 可用的播放选项
选项 | 描述 |
---|---|
seek | 允许以毫秒为单位跳转到视频中的特定点。默认值为 null 。 |
paused | 指示视频是否暂停。 |
looping | 指示视频是否应该循环播放。 |
volume | 一个从 0 到 1 的值,表示音量级别 (0 为静音,1 为最大音量)。 |
在下面的示例中,每次我们点击视频时,都会将视频的跳转位置设置为 2 秒。
tsx
importReact from "react";import {Canvas ,Fill ,Image ,useVideo } from "@shopify/react-native-skia";import {Pressable ,useWindowDimensions } from "react-native";import {useSharedValue } from "react-native-reanimated";export constVideoExample = () => {constseek =useSharedValue <null | number>(null);// Set this value to true to pause the videoconstpaused =useSharedValue (false);const {width ,height } =useWindowDimensions ();const {currentFrame ,currentTime } =useVideo ("https://bit.ly/skia-video",{seek ,paused ,looping : true});return (<Pressable style ={{flex : 1 }}onPress ={() => (seek .value = 2000)}><Canvas style ={{flex : 1 }}><Image image ={currentFrame }x ={0}y ={0}width ={width }height ={height }fit ="cover"/></Canvas ></Pressable >);};
tsx
importReact from "react";import {Canvas ,Fill ,Image ,useVideo } from "@shopify/react-native-skia";import {Pressable ,useWindowDimensions } from "react-native";import {useSharedValue } from "react-native-reanimated";export constVideoExample = () => {constseek =useSharedValue <null | number>(null);// Set this value to true to pause the videoconstpaused =useSharedValue (false);const {width ,height } =useWindowDimensions ();const {currentFrame ,currentTime } =useVideo ("https://bit.ly/skia-video",{seek ,paused ,looping : true});return (<Pressable style ={{flex : 1 }}onPress ={() => (seek .value = 2000)}><Canvas style ={{flex : 1 }}><Image image ={currentFrame }x ={0}y ={0}width ={width }height ={height }fit ="cover"/></Canvas ></Pressable >);};
旋转视频
rotation
属性可以是 0
、90
、180
或 270
。我们提供了一个 fitbox
函数,可以帮助旋转和缩放视频。
tsx
importReact from "react";import {Canvas ,Image ,useVideo ,fitbox ,rect } from "@shopify/react-native-skia";import {Pressable ,useWindowDimensions } from "react-native";import {useSharedValue } from "react-native-reanimated";export constVideoExample = () => {constpaused =useSharedValue (false);const {width ,height } =useWindowDimensions ();const {currentFrame ,rotation ,size } =useVideo ("https://bit.ly/skia-video");constsrc =rect (0, 0,size .width ,size .height );constdst =rect (0, 0,width ,height )consttransform =fitbox ("cover",src ,dst ,rotation );return (<Canvas style ={{flex : 1 }}><Image image ={currentFrame }x ={0}y ={0}width ={width }height ={height }fit ="none"transform ={transform }/></Canvas >);};
tsx
importReact from "react";import {Canvas ,Image ,useVideo ,fitbox ,rect } from "@shopify/react-native-skia";import {Pressable ,useWindowDimensions } from "react-native";import {useSharedValue } from "react-native-reanimated";export constVideoExample = () => {constpaused =useSharedValue (false);const {width ,height } =useWindowDimensions ();const {currentFrame ,rotation ,size } =useVideo ("https://bit.ly/skia-video");constsrc =rect (0, 0,size .width ,size .height );constdst =rect (0, 0,width ,height )consttransform =fitbox ("cover",src ,dst ,rotation );return (<Canvas style ={{flex : 1 }}><Image image ={currentFrame }x ={0}y ={0}width ={width }height ={height }fit ="none"transform ={transform }/></Canvas >);};
使用资源
下面是一个示例,我们使用 expo-asset 从捆绑包加载视频文件。
tsx
import {useVideo } from "@shopify/react-native-skia";import {useAssets } from "expo-asset";// Example usage:// const video = useVideoFromAsset(require("./BigBuckBunny.mp4"));export constuseVideoFromAsset = (mod : number,options ?:Parameters <typeofuseVideo >[1]) => {const [assets ,error ] =useAssets ([mod ]);if (error ) {throwerror ;}returnuseVideo (assets ?assets [0].localUri : null,options );};
tsx
import {useVideo } from "@shopify/react-native-skia";import {useAssets } from "expo-asset";// Example usage:// const video = useVideoFromAsset(require("./BigBuckBunny.mp4"));export constuseVideoFromAsset = (mod : number,options ?:Parameters <typeofuseVideo >[1]) => {const [assets ,error ] =useAssets ([mod ]);if (error ) {throwerror ;}returnuseVideo (assets ?assets [0].localUri : null,options );};
视频编码
要从 Skia 图像编码视频,您可以使用 ffmpeg,也可以查看 react-native-skia-video。