react-native-视频处理
开始使用
npm install react-native-video-processing --save
yarn add react-native-video-processing
你可以通过运行以下命令进行测试
$ npm test
或 $ yarn test
安装
注意:对于 RN 0.4x 版本使用 1.0 版本,对于 RN 0.3x 版本使用 0.16 版本
[Android]
-
打开
android/app/src/main/java/[...]/MainApplication.java
-
在文件顶部的导入部分添加
import com.shahenlibrary.RNVideoProcessingPackage;
-
在 getPackages() 方法返回的列表中添加新的
new RNVideoProcessingPackage()
-
在
android/settings.gradle
文件末尾添加以下行:
include ':react-native-video-processing'
project(':react-native-video-processing').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video-processing/android')
- 在
android/app/build.gradle
文件的 dependencies 块内插入以下行:
compile project(':react-native-video-processing')
- 在
AndroidManifest.xml
文件中添加以下行:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
[iOS]
-
在 Xcode 中,右键点击你的 Xcode 项目并创建一个名为
RNVideoProcessing
的New Group
。 -
进入
node_modules/react-native-video-processing/ios/RNVideoProcessing
并将.swift
文件拖到你刚刚创建的组下。选择Create folder references
选项(如果未选中)。 -
对子目录
RNVideoTrimmer
、RNTrimmerView
和ICGVideoTrimmer
及其下的所有文件重复步骤 1 和 2。确保保持文件夹层次结构相同。 -
进入
node_modules/react-native-video-processing/ios/GPUImage/framework
并将GPUImage.xcodeproj
拖到 Xcode 中你项目的根目录。 -
在你项目的
Build Phases
下,确保你添加的.swift
文件出现在Compile Sources
中。 -
在你项目的
General
标签下,将以下框架添加到Linked Frameworks and Libraries
中:
- CoreMedia
- CoreVideo
- OpenGLES
- AVFoundation
- QuartzCore
- MobileCoreServices
- GPUImage
-
将
GPUImage.frameworkiOS
添加到Embedded Binaries
中。 -
导航到你项目的桥接头文件 <ProjectName-Bridging-Header.h> 并添加
#import "RNVideoProcessing.h"
。 -
清理并运行你的项目。
查看以下视频以获取更多设置参考。
更新 ffmpeg 二进制文件
- 克隆 mobile-ffmpeg
- 设置项目,参见 README 中的 Prerequisites。
- 修改
build/android-ffmpeg.sh
以生成二进制文件(更多信息)- 删除 --disable-programs 行
- 将 --disable-static 行改为 --enable-static
- 删除 --enable-shared 行
- 编译二进制文件:
./android.sh --lts --disable-arm-v7a-neon --enable-x264 --enable-gpl --speed
。命令可能以failed
结束。这没关系,因为我们修改了构建脚本。确保每个构建输出:ffmpeg: ok
。 - 在
prebuilt/[android-arm|android-arm64|android-x86|android-x86_64]/ffmpeg/bin/ffmpeg
中找到ffmpeg
二进制文件 - 复制并重命名二进制文件到
android/src/main/jniLibs/[armeabi-v7a|arm64-v8a|x86|x86_64]/libffmpeg.so
。确保你将二进制文件从ffmpeg
重命名为libffmpeg.so
!
使用示例
import React, { Component } from 'react';
import { View } from 'react-native';
import { VideoPlayer, Trimmer } from 'react-native-video-processing';
class App extends Component {
trimVideo() {
const options = {
startTime: 0,
endTime: 15,
quality: VideoPlayer.Constants.quality.QUALITY_1280x720, // 仅适用于 iOS
saveToCameraRoll: true, // 默认为 false // 仅适用于 iOS
saveWithCurrentDate: true, // 默认为 false // 仅适用于 iOS
};
this.videoPlayerRef.trim(options)
.then((newSource) => console.log(newSource))
.catch(console.warn);
}
compressVideo() {
const options = {
width: 720,
height: 1280,
bitrateMultiplier: 3,
saveToCameraRoll: true, // 默认为 false,仅适用于 iOS
saveWithCurrentDate: true, // 默认为 false,仅适用于 iOS
minimumBitrate: 300000,
removeAudio: true, // 默认为 false
};
this.videoPlayerRef.compress(options)
.then((newSource) => console.log(newSource))
.catch(console.warn);
}
getPreviewImageForSecond(second) {
const maximumSize = { width: 640, height: 1024 }; // 默认值为 { width: 1080, height: 1080 },仅适用于iOS
this.videoPlayerRef.getPreviewForSecond(second, maximumSize) // maximumSize 仅适用于iOS
.then((base64String) => console.log('这是图片的BASE64编码', base64String))
.catch(console.warn);
}
getVideoInfo() {
this.videoPlayerRef.getVideoInfo()
.then((info) => console.log(info))
.catch(console.warn);
}
render() {
return (
<View style={{ flex: 1 }}>
<VideoPlayer
ref={ref => this.videoPlayerRef = ref}
startTime={30} // 秒
endTime={120} // 秒
play={true} // 默认为false
replay={true} // 视频结束后是否重新播放
rotate={true} // 如果视频是横向拍摄的,使用此属性来旋转视频,仅适用于iOS
source={'file:///sdcard/DCIM/....'}
playerWidth={300} // 仅适用于iOS
playerHeight={500} // 仅适用于iOS
style={{ backgroundColor: 'black' }}
resizeMode={VideoPlayer.Constants.resizeMode.CONTAIN}
onChange={({ nativeEvent }) => console.log({ nativeEvent })} // 每秒获取当前时间
/>
<Trimmer
source={'file:///sdcard/DCIM/....'}
height={100}
width={300}
onTrackerMove={(e) => console.log(e.currentTime)} // 仅适用于iOS
currentTime={this.video.currentTime} // 使用此属性设置跟踪器位置,仅适用于iOS
themeColor={'white'} // 仅适用于iOS
thumbWidth={30} // 仅适用于iOS
trackerColor={'green'} // 仅适用于iOS
onChange={(e) => console.log(e.startTime, e.endTime)}
/>
</View>
);
}
}
或者你可以使用ProcessingManager
而不挂载VideoPlayer
组件:
import React, { Component } from 'react';
import { View } from 'react-native';
import { ProcessingManager } from 'react-native-video-processing';
export class App extends Component {
componentWillMount() {
const { source } = this.props;
ProcessingManager.getVideoInfo(source)
.then(({ duration, size, frameRate, bitrate }) => console.log(duration, size, frameRate, bitrate));
// 在iOS上可以通过使用远程文件作为源来裁剪远程文件
ProcessingManager.trim(source, options) // 类似VideoPlayer的trim选项
.then((data) => console.log(data));
ProcessingManager.compress(source, options) // 类似VideoPlayer的compress选项
.then((data) => console.log(data));
ProcessingManager.reverse(source) // 反转源视频
.then((data) => console.log(data)); // 返回新的文件源
ProcessingManager.boomerang(source) // 创建源视频的"回旋镖"效果(正向播放然后反向播放)
.then((data) => console.log(data)); // 返回新的文件源
const maximumSize = { width: 100, height: 200 };
ProcessingManager.getPreviewForSecond(source, forSecond, maximumSize)
.then((data) => console.log(data))
}
render() {
return <View />;
}
}
贡献
- 请遵循eslint样式指南。
- 请使用
$ npm run commit
提交。
路线图
- 使用FFMpeg替代MP4Parser
- 添加应用GLSL滤镜的能力
- Android应能够压缩视频
- 更多处理选项
- 为Android创建原生裁剪器组件
- 提供独立API
- 在README中描述API方法及其参数