相关文章:
《react-native 集成 FFmpeg 能力 - 使用 FFmpegKit(二)》
《react-native 集成 FFmpeg 能力 - 使用 FFmpegKit(三)》
这一篇主要记录对于 react-native 库的使用。
最近在做 react-native 的需求,需要做一些视频剪辑。ios 上使用的是 AVFoundation,询问了 AI 还比较顺利,功能实现了。Android 上使用的是 MediaCodec,就是怎么都调试不出来。AI 也直接建议用 FFmpeg 了。
一、现状调研
FFmpeg 也是个很知名很强大的音视频处理工具了,一般用在命令行。在这个基础上,网上有大佬封装适配了多个平台的库,其中也包括 react-native,仓库地址 ffmpeg-kit。很遗憾的是,今年年初因为人力资源问题,大佬停止了更新。
这里提到了:《Saying Goodbye to FFmpegKit》。感谢大佬们的用爱发电啊。
截止到当前,FFmpeg 版本是 7,FFmpegKit 封装的版本是 6。同时 FFmpegKit 也删除了 IOS 和 Android 仓库里的库,所以 react-native 的也用不了了。但是仓库源码还在。所以目前还想继续使用 FFmpegKit 的话,可以:
- 找之前网上保留过的资源,或者其他大佬私下打包出来分享的。
- 自己根据源码打包,因为不维护了,自己解决打包出现的问题。
二、资源准备
当然找到了资源包,也得自己引入,因为正常的安装流程已经报错了,得本地引入(自己打包放到网上仓库也可以),首先:
Android - aar 下载,然后在本地引入。
IOS - 参考文章,可以将 podFile 指向 FFmpegKit 原仓库的地址改成指向「别的地址」(其实就是这个文章作者大佬自己的仓库),保证能下载到依赖压缩包就行,也可以根据这份 podspec 文件里面指向的 zip 包地址,把依赖包下载下来,放在自己本地引入。
三、react-native 库引入使用
react-native 库:《ffmpeg-kit-react-native》,原《使用文档》,现在安装这个库会报已经废弃的警告。
现在在获得 IOS 和 Android 依赖包的情况下,进行本地引入,使得 react-native 库也能用起来。当然相应的 IOS 和 Android 库也能用。
首先在项目根目录放置两个依赖库(地址随意,用的时候正确使用就行):

ios 文件夹有一个 ffmpeg-kit-ios-video.podspec 文件,这不是资源包下载下来附带的,要自己添加,相当于依赖声明。
Android 端修复使用
Android 端的使用还是比较简单的,直接打 patch 修改 node_modules 里的文件内容就行:找到 node_modules/ffmpeg-kit-react-native/android/build.gradle 文件,修改成一下这样即可:
dependencies {
api 'com.facebook.react:react-native:+'
// 这句注释:implementation 'com.arthenica:ffmpeg-kit-' + safePackageName(safeExtGet('ffmpegKitPackage', 'https')) + ':' + safePackageVersion(safeExtGet('ffmpegKitPackage', 'https'))
// 添加下面两句,引入本地依赖和其他依赖
implementation files('../../../libs/android/ffmpeg-kit.aar')
implementation 'com.arthenica:smart-exception-java:0.2.1'
}
IOS 端修复使用
1、
首先上面提到的 ffmpeg-kit-ios-video.podspec:
Pod::Spec.new do |s|
s.name = 'ffmpeg-kit-ios-video'
s.version = '6.0'
s.summary = 'FFmpeg Kit for React Native'
s.homepage = 'https://github.com/arthenica/ffmpeg-kit'
s.license = 'LGPL-3.0'
s.authors = 'author'
s.platform = :ios
s.requires_arc = true
s.static_framework = true
s.source = { path: '.' }
s.dependency "React-Core"
s.vendored_frameworks = '*.xcframework'
end
2、
然后项目下找到 ios/Podfile 文件,修改:
// 备用:pod 'ffmpeg-kit-ios-full', :podspec => 'https://raw.githubusercontent.com/luthviar/ffmpeg-kit-ios-full/main/ffmpeg-kit-ios-full.podspec'
pod 'ffmpeg-kit-ios-video', :path => '../libs/ios/ffmpeg-kit-ios-video'
pod 'ffmpeg-kit-react-native', :subspecs => ['video'], :podspec => '../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec'
// 找到下面这一句,然后在这一句上面添加上面那两句,顺序严格
config = use_native_modules!(config_command)
注意:这里的依赖库名是 ffmpeg-kit-ios-video
,是因为我自己本地打了个 video 包出来,所以命名为 video 后缀。如果自己打出来了别的包,或者网上找的包是 full 或者别的名字,只要把所有相应的名字改了就行。
比如 ffmpeg-kit-ios-video
全改成 ffmpeg-kit-ios-full
,包括那个 libs/ios 下的 podspec 文件。:subspecs => ['video']
理论上应该也没影响了,不过也最好改一下,改成::subspecs => ['full']
。
3、
如果是 expo 项目,这里有个小问题。ios 文件夹都是每次 build 生成的,当然里面的 Podfile 文件也是,也就是每次重新创建文件,都要自己去打这个补丁。太麻烦了,所以得换另外方式。
注意下面示例我是用了 ffmpeg-kit-ios-full 的包,这个和自己本地引入的实际包名保持一致就好了。
用官方的工具 expo-build-properties,在 app.config.ts 文件加上:
const config = {
// 其他省略
plugins: [
[
'expo-build-properties',
{
ios: {
extraPods: [
{
name: 'ffmpeg-kit-ios-full',
path: '../libs/ios/ffmpeg-kit-ios-full', // 本地路径(相对于 ios/Podfile)
},
{
name: 'ffmpeg-kit-react-native',
podspec:
'../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec', // 本地路径(相对于 ios/Podfile)
},
],
},
},
],
],
}
这样,每次 build 创建 ios/Podfile 文件时候,就会打上上面的补丁。可以看到上面是打了两份补丁,一个 ffmpeg-kit 本身,自己使用本地引入的。一个是对应的 react-native 库,指向了 node_modules 里的文件,但是这个 react-native 库 podspec 文件已经知道是有问题的。
所以还要再对 node_modules 的 ffmpeg-kit-react-native 依赖包再打一份针对 ios 的 patch:
Pod::Spec.new do |s|
s.source = { :git => "https://github.com/arthenica/ffmpeg-kit.git", :tag => "react.native.v#{s.version}" }
s.dependency "React-Core"
s.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
s.dependency 'ffmpeg-kit-ios-full', "6.0"
s.ios.deployment_target = '10'
end
四、测试使用
本地库和配置文件都准备完毕,因为改了原生依赖,所以最好重新编译一遍。我使用的是 expo 项目,可以执行:npx expo prebuild --clean
重新安装一遍。
如果用的纯 react-native 项目,就用 xcode 和 Android Studio 重新安装。
在代码里测试是否引用成功:
import { ReturnCode } from 'ffmpeg-kit-react-native';
FFmpegKitConfig.getFFmpegVersion().then(v => console.log('getFFmpegVersion', v))