搞JavaCV做音视频处理的老哥,多半都被这么个报错砸到过:项目里头明明把FFmpeg相关的依赖都加进去了,结果一启动jvm,直接甩出UnsatisfiedLinkError: org.bytedeco.ffmpeg.global.avutil.AV_PIX_FMT_GBRAP14()I。别急着怀疑JDK坏了,这几乎都是JavaCV/FFmpeg这套原生库加载的时候出了问题。我当年第一次踩这个坑,对着屏幕愣了几分钟,因为报错信息实在太不像人话了,方法名长得跟乱码似的,后面跟着个()I,网上搜也没几条靠谱解释。今天把这问题彻底摊开说清楚,顺便把排查套路和解决方案一次性整理出来,免得你踩完坑还得吃土。
这块内容主要适合正在用JavaCV做视频解码、推流、图像处理,或者是用ffmpeg-platform这类坐标从Maven拉依赖的开发者。不管你是Maven项目还是Gradle项目,只要海绵体还没变硬就碰到这个报错,接下来这段内容基本都能找到对应解法。
1. 报错现象与问题定性
1.1 这个报错到底在说什么鬼
先拆一下报错字符串:org.bytedeco.ffmpeg.global.avutil.AV_PIX_FMT_GBRAP14()。AV_PIX_FMT_GBRAP14是FFmpeg里avutil库的一个枚举常量,代表一种像素格式(14bit GBR + Alpha planar)。()I是JNI的方法签名,意思是返回Int类型。所以这行报错的字面意思是:JVM在调用avutil的AV_PIX_FMT_GBRAP14()这个native方法时,找不到对应的native实现。
但你要是细想就会觉得离谱:AV_PIX_FMT_GBRAP14根本就不是个函数,它就是个常量啊。怎么会被JVM当成native方法去调用呢?这就是JavaCV的底层机制了。JavaCV在platform包里面用Java类映射FFmpeg结构体、常量和函数,比如avutil.java里会有类似public static native int AV_PIX_FMT_GBRAP14();这样的声明。Java类库librar文件在初始化的时候需要往native层传递参数,或者通过native调用返回常量值。当整个FFmpeg native库没有正确加载到JVM里,这个native方法就成了无源之水,调用它必然报UnsatisfiedLinkError。
换成人话:你把某个.dll/.so文件没放对地方,或者放了个残缺版本,JVM加载不到或者加载错位了,于是它说“你要的那个函数我找不到,罢工了”。
1.2 完整报错栈通常长什么样子
实际生产环境中,这个报错不太可能孤零零出现。它经常伴随着一堆“pillup”的加载异常,或者干脆是启动时先打出几行Failed to load:开头的日志,然后才抛错。典型的完整报错栈是这样的:
java.lang.UnsatisfiedLinkError: org.bytedeco.ffmpeg.global.avutil.AV_PIX_FMT_GBRAP14()I at org.bytedeco.ffmpeg.global.avutil.AV_PIX_FMT_GBRAP14(Native Method) at org.bytedeco.ffmpeg.global.avutil.<clinit>(avutil.java:2390) at java.base/java.lang.Class.forName0(Native Method) ... Caused by: java.lang.RuntimeException: Error loading library from: /xxx/ffmpeg-platform-6.1.1-1.5.9.jar!/org/bytedeco/ffmpeg/linux-x86_64/libavutil.so at org.bytedeco.javacpp.Loader.load(Loader.java:1398) ... Caused by: java.lang.UnsatisfiedLinkError: /tmp/javacpp162738/org.bytedeco.ffmpeg.linux-x86_64/libavutil.so: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.13' not found注意看最后一行,这个报错一半以上的情况下是底层so依赖系统库版本太低导致的。比如Linux上缺少新版本的libstdc++,或者Windows上缺Visual C++运行库。单纯的依赖版本不匹配只是其中一个触发器。
1.3 什么人最容易碰到这个坑
- 用
javacv-platform全家桶依赖,但没注意JavaCV版本、FFmpeg版本、平台classifier的一致性。 - 在Docker容器里跑JavaCV,但容器基础镜像缺少系统原生依赖。
- 使用Spring Boot打包可执行jar,没有配置
jna.platform.package或者Loader的临时目录权限。 - 在Windows下用IDEA启动,但IDEA的热部署或者ClassLoader隔离导致重复加载native库。
- 项目里同时存在旧版的
ffmpeg依赖(比如通过其他音视频库传递引入的),和新版JavaCV冲突。
你仔细想想,周围人讨论这个报错时,是不是很少直接给有效的解决方案?因为这个问题确实不是一句“加个依赖”能搞定的,它更像一个环境治理问题。
2. 根因分析:为什么加载FFmpeg原生库会失败
2.1 第一个怀疑对象:JavaCV与FFmpeg版本不匹配
JavaCV自身做了个非常骚的机制:它通过javacpp-presets项目给FFmpeg提供了预编译好的native库,并把它们打包成一个个平台相关jar包,比如ffmpeg-6.1.1-1.5.9-linux-x86_64.jar。这些jar包的命名规则是ffmpeg-<版本>-<javacpp版本>-<platform>.jar。JavaCV的版本则是对应的javacpp版本(比如1.5.9)。
如果你在maven里手动引入了不同的坐标,比如:
<dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.5.8</version> </dependency>这个1.5.8的JavaCV内部可能绑定的是ffmpeg-6.0-1.5.8-linux-x86_64.jar。但是你又因为其他原因手动加了一个ffmpeg-platform的1.5.9版本,这时候两个jar包同时存在于classpath中,Loader加载时会按照classpath顺序寻找,一旦找到的libavutil.so版本和avutil.java里声明的native方法签名对不上,就必然出现UnsatisfiedLinkError。我遇到过有人把ffmpeg-platform和javacv分开引,且版本号差个哪怕一个小版本,都能炸穿。
2.2 平台classifier识别失败
JavaCV通过org.bytedeco.javacpp.Loader来加载对应平台的动态库。它如何确定当前系统平台?靠的是os.name、os.arch这些系统属性。如果你的JVM跑在非常规环境(比如OpenJ9,或魔改过的Android环境),或者你在Windows上用了32位的JVM,但下载的jar包是windows-x86_64,那Loader可能跑偏,加载失败后自然报UnsatisfiedLinkError。
还有坑:Linux下os.arch可能会返回amd64,而JavaCV的classifier规范却是x86_64。这个时候虽然loader一般会自动做映射,但某些老版本会出问题。macOS M系列芯片有时会识别成aarch64,但你的maven没有添加ffmpeg-6.1.1-1.5.9-macosx-arm64.jar依赖,也会炸。
2.3 共享库依赖的“系统库缺失”
FFmpeg的.so文件不是孤立的,它在Linux上依赖libz、libx264、libstdc++等系统库。JavaCV预编译包为了轻量,很多编码器是内置的,但底层仍然依赖libc和libstdc++。如果一个CentOS 7老环境,它的libstdc++.so.6最高只支持到CXXABI_1.3.7,而新版JavaCV的native库需要CXXABI_1.3.13,那你无论如何都会看到开头那种错。这不是JavaCV的问题,是系统环境太老。
同理,Windows环境下缺少新版Visual C++ Redistributable(比如2015-2022版)时,也会出现类似The specified procedure could not be found或UnsatisfiedLinkError。macOS下经常是dyld: Library not loaded: @rpath/libavutil.dylib,这个就不是UnsatisfiedLinkError了,但根因也是库依赖缺失。
2.4 依赖冲突与隐藏依赖
这种最常见的是项目里既有org.bytedeco:ffmpeg-platform,又有org.bytedeco.javacpp-presets:ffmpeg旧坐标。或者你是用javacv-platform这个汇总坐标,这个坐标会把OpenCV、FFmpeg、flycapture、spinnaker等一堆native库全部带进来。如果系统里之前残留了低版本的动态库,或Maven解析时选择了较旧版本,就会产生内部方法签名不一致的问题。特别是当同一个类在多个jar包出现时,classpath打乱后的结果是毁灭性的。
我用一个简单表格总结一下不同根因的对应特征:
| 根因方向 | 典型消息特征 | 出现时间 |
|---|---|---|
| 版本不匹配 | 找不到AV_PIX_FMT_GBRAP14,且Loader加载的jar包路径和当前版本不一致 | 类初始化时 |
| 平台classifier缺失 | 提示Noorg.bytedeco.ffmpeg.global.avutilclasses,或找不到某个带windows-x86_64后缀的文件 | 启动即炸 |
| 系统库缺失 | libstdc++.so.6: version CXXABI_1.3.13 not found | 加载so文件时报错 |
| 动态库冲突 | 加载libavutil时无法找到符号,或ClassNotFoundException | 触发具体操作时 |
3. 案件排查:一条路走到黑的实操指南
3.1 第一拳:搞清你的依赖树
不管报错多花哨,第一步永远是把依赖树打出来,眼见为实。
Maven项目执行:
mvn dependency:tree -Dincludes=org.bytedeco*Gradle项目执行:
./gradlew dependencies --configuration runtimeClasspath看什么?看有没有多个版本的javacv、ffmpeg、javacpp。如果有,用dependencyManagement或直接exclude清理到只剩一套版本。确认完版本后,再查一下当前项目的JavaCV版本对应的FFmpeg版本是多少。这里有个对应关系,比如JavaCV 1.5.7对应FFmpeg 5.1.4,JavaCV 1.5.8对应FFmpeg 6.0.0,JavaCV 1.5.9对应FFmpeg 6.1.1。你要是混着引,早晚出事。
3.2 第二拳:开启加载日志,让Loader说实话
JavaCV的Loader加载过程可以通过系统属性把日志打开。启动时添加JVM参数:
java -Dorg.bytedeco.javacpp.maxPhysicalBytes=0 \ -Dorg.bytedeco.javacpp.logger=org.slf4j.simpleLogger.SimpleLogger \ -Dorg.bytedeco.javacpp.logger.impl=org.slf4j.simpleLogger.SimpleLogger \ -Dorg.bytedeco.javacpp.loggerLevel=TRACE \ -jar your-app.jar如果你用的不是slf4j,至少加一个:
-Dorg.bytedeco.javacpp.loadDebug=1运行后能看到类似这样的输出:
javacpp: available processors: 8 javacpp: os.name: linux javacpp: os.arch: amd64 javacpp: os.version: 5.4.0 javacpp: java.specification.version: 17 javacpp: java.class.version: 61.0 javacpp: sun.java.command: ... javacpp: configuration in working directory: ...重点看os.name和os.arch是否正常。然后会看到Loading jar:后面跟着具体jar包路径。比如:
Loading jar: /root/.m2/repository/org/bytedeco/ffmpeg/ffmpeg-platform/6.1.1-1.5.9/ffmpeg-platform-6.1.1-1.5.9.jar!/org/bytedeco/ffmpeg/linux-x86_64/如果这里写的linux-x86_64不是你期望的平台,说明classifier选择出问题了。继续往下看,加载时会执行:
javacpp: extracting file to /tmp/javacpp182736/org.bytedeco.ffmpeg.linux-x86_64/libavutil.so如果这个.so文件解压失败,或者解压后的路径目录没有权限访问,会提示无法执行。用ls -l检查一下/tmp/javacpp*目录权限,普通用户如果/tmp被mount成noexec会炸。
3.3 第三拳:检查系统库依赖
如果上面加载日志看起来一切正常,最后却失败了,那大概率是系统库问题。Linux下用ldd检查这个so的依赖:
ldd /tmp/javacpp*/org.bytedeco.ffmpeg.linux-x86_64/libavutil.so输出会列出所有依赖的系统库及路径,如果某些库显示not found,那就是缺了。很多Deploy场景是用Docker镜像,镜像里要是用的是精简版(如Alpine)且没有安装libstdc++,那libstdc++肯定找不到。Alpine下需要:
apk add libstdc++ libgcc如果你是Debian/Ubuntu系的镜像,用:
apt-get update && apt-get install -y libstdc++6还有更隐蔽的:某些库路径下存在一个很老版本的libstdc++.so.6,而你的Java是在不同路径下编译的,导致运行时动态加载器选定旧版库。可以用:
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep CXXABI看看支持到哪个版本。如果没有CXXABI_1.3.13,那就要升级系统库,或者换一个更旧的JavaCV版本(但这不推荐,还是环境升级靠得住)。
3.4 第四拳:敲打ClassLoader和临时目录
Spring Boot的打包插件默认会把项目依赖的jar包全部解压到BOOT-INF/lib/下,但JavaCV的Loader不会直接从classpath解压,而是先把native库提取到临时目录。注意,Spring Boot的可执行jar在java -jar模式下启动时,ClassLoader是LaunchedURLClassLoader,它解压的路径会带着一个和普通file:/...路径不同的标识。JavaCV的老版本(1.5.7之前)对这种情况支持不好,表现为类初始化失败。新版JavaCV的Loader通常能正常处理,但仍偶发报错。可以通过配置:
org.bytedeco.javacpp.tmpdir=/var/tmp或者修改Loader的源码逻辑,强制使用当前项目的相对路径。实际生产中最省心的办法是:用mvn dependency:copy-dependencies把native jar包解压到本地目录,然后通过-Djava.library.path来指定。
4. 对症下药:五套靠谱治疗方案
4.1 方案A:统一依赖版本(99%的情况到此为止)
最标准、最无脑、最可复用的操作:直接用javacv-platform一个坐标,不要零星引入其他FFmpeg坐标。如果因为音视频库需要,必须单独引ffmpeg-platform,那就保持后面的后缀版本和javacv一致。
比如你用的是JavaCV 1.5.9,那么pom里就写成:
<dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.5.9</version> </dependency>同时可以显式添加ffmpeg-platform(可选的,javacv-platform已经传递依赖了):
<dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg-platform</artifactId> <version>6.1.1-1.5.9</version> </dependency>保证版本对得上。但这个方案解决不了系统库缺失问题。
4.2 方案B:针对特定平台引入止痒剂
如果你只需要Linux x86_64平台,完全没必要引入所有平台的全家桶,这样还能减小包体。用经典的“三件套”:
<dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.5.9</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg</artifactId> <version>6.1.1-1.5.9</version> <classifier>linux-x86_64</classifier> </dependency>注意这里我用的ffmpeg坐标,不是ffmpeg-platform。ffmpeg坐标的classifier指定具体平台,而ffmpeg-platform是一个“平台套件”的概念,它内部包含所有平台。如果你用ffmpeg-platform,就不需要指定classifier;但如果用了ffmpeg,必须带上classifier,否则会找不到native库。
但这套方案坑在于:一旦你的开发环境是Windows,生产环境是Linux,你就要把两个classifier都引入,IDE运行时因为classpath顺序问题找错平台。所以这个方案适合你确定最终运行环境,或者用Maven profile切换。
4.3 方案C:处理系统库环境的硬伤
如果确认是libstdc++.so.6版本问题,在Dockerfile里更新即可:
FROM openjdk:17-jdk-slim RUN apt-get update && apt-get install -y libstdc++6 COPY your-app.jar /app.jar CMD ["java", "-jar", "/app.jar"]如果是CentOS 7这种老系统,直接升级libstdc++麻烦,可以考虑通过conda环境或者下载新版libstdc++.so.6放在项目目录,然后用LD_LIBRARY_PATH指定。但这属于旁门左道,会带来安全性问题。我个人建议直接和运维沟通升级基础镜像,别在java层硬撑。
Windows系统的话,安装新版VC运行库,按系统架构选x64版本,重启IDE即可。macOS的话,如果用了M1,记得确认你装的JDK也是ARM版本的,不要用x86_64的JDK去跑ARM一个不存在的native库。
4.4 方案D:采用原生jar解压直引动态库
有些极端环境(比如云函数、微服务实例,临时目录被限制),Loader从这个jar包内解压到临时目录的机制不好使。这时候可以手动把所有JNI库解压到一个固定目录,然后通过-Djava.library.path指过去。
步骤:
- 找到所需的native jar包,比如
ffmpeg-6.1.1-1.5.9-linux-x86_64.jar。 - 把它解压到
/opt/javacpp-native。 - 启动时加
-Djava.library.path=/opt/javacpp-native。 - 最好同时设置
-Dorg.bytedeco.javacpp.loadlibraries=true,让它主动加载指定路径。
还不放心的话,可以在代码里首次调用前强行加载:
import org.bytedeco.javacpp.Loader; public class FfmpegLibraryLoader { static { Loader.load(org.bytedeco.ffmpeg.global.avutil.class); } }如果是Spring Boot项目,把这个静态块放到一个@Configuration里,保证容器启动时率先加载。
4.5 方案E:彻底绕开鸡肋的AV_PIX_FMT_GBRAP14
有人说,我只是用FFmpeg做简单的转码,用不到这个常量,能不能不初始化avutil全部内容?答案是不行。JavaCV的avutil类有很多字段,其中静态字段会在类初始化时触发native调用。不过你要是真的卡在这里很久,可以考虑降低JavaCV版本,比如从1.5.9降到1.5.7,它对应的FFmpeg版本是5.1.4,老版本的AV_PIX_FMT_GBRAP14定义方式可能不同,某些环境能绕过这个报错。但这只是掩耳盗铃,因为下一个方法可能又炸。
我更推荐的做法是:确保native库加载完整,别去逃避这个错误。这个常量之所以被做成native方法,是为了能便捷地将C层的宏定义直接暴露给Java,本质上这是JavaCV的正常操作。
5. 高频实战场景与详细解决记录
5.1 场景:Maven项目本地运行报错,使用IDEA
IDEA环境下,如果你开启了“Use --release option for cross-compilation”,可能把目标架构搞乱。先把那个关闭,确认JDK版本与你引入的JavaCV所要求的体系结构一致(64位JVM对应x86_64)。
然后看IDEA的运行配置里有没有设置-Djava.library.path,如果有,这个参数会干扰JavaCV从自己的jar包加载库,因为JVM会优先去java.library.path指定的目录中找。如果那个目录里有旧的FFmpeg相关dll/so,那就直接加载了旧版本。没有任何特殊需求的话,把java.library.path清空,重启。
5.2 场景:Spring Boot可执行jar部署到Linux服务器
这个场景我再熟悉不过。用spring-boot-maven-plugin打成fat jar后,直接java -jar启动,第一次在服务器上跑时基本都有这个错。怎么查?先看日志,有没有类似Unable to load library字样。如果有,原因是JavaCV内部的Loader在从jar:file:/path/to/app.jar!/BOOT-INF/lib/ffmpeg...jar!/org/bytedeco/ffmpeg/linux-x86_64/libavutil.so这东西里取资源,由于Spring Boot的jar嵌套结构,默认ClassLoader提供的getResourceAsStream()对嵌套jar支持不够,虽然新版有所改善,但依然建议使用以下方法:
在启动命令中增加:
java -Dorg.bytedeco.javacpp.tmpdir=/var/tmp/javacpp -jar app.jar如果还不行,考虑用loader.path或者使用Spring Boot的PropertiesLauncher。其实最粗暴有效的办法是:不用fat jar,把依赖全部解压到外部lib目录,然后java -cp app.jar:lib/* com.xxx.Application。这种部署方式能避开99%的ClassLoader诡异问题。
5.3 场景:Docker容器Alpine镜像
Alpine很好用,但它用的是musl libc,而JavaCV预编译的FFmpeg native库是glibc版本,这导致java.lang.UnsatisfiedLinkError: /tmp/javacpp.../libavutil.so: Error loading shared library: libavformat.so.60: cannot open shared object file: No such file or directory。换用Debian slim镜像能解决卡在这一步的问题。这也是为什么我个人强烈不建议用Alpine跑JavaCV,如果你已经用了Alpine,请立刻打镜像换掉:
FROM openjdk:17-jdk-slim RUN apt-get update && apt-get install -y libstdc++6 libgcc-s15.4 场景:Maven打包依赖排除
如果你的项目同时用了第三方SDK(比如某视频直播SDK),它内部传递引用了老版本的ffmpeg,那你需要找到这个依赖并加排除:
<dependency> <groupId>com.example</groupId> <artifactId>some-video-sdk</artifactId> <version>1.2.3</version> <exclusions> <exclusion> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg-platform</artifactId> </exclusion> <exclusion> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> </exclusion> </exclusions> </dependency>或者全局排除:
<dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg-platform</artifactId> <version>6.1.1-1.5.9</version> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>严格来说不要全排除,而是排除你不需要的那些绑定库。这里给个更聪明的操作:如果你只用FFmpeg,不想要OpenCV等其他JavaCV预编译库,那就不要用javacv-platform,换成javacv+ffmpeg单独引。
5.5 场景:多人协作时环境不一致
团队里有人Windows,有人Mac,有人在Docker里跑。不要在pom里手动写死classifier,用Maven Profile按os激活最优解:
<profiles> <profile> <id>linux-x86_64</id> <activation> <os> <family>unix</family> <name>linux</name> <arch>amd64</arch> </os> </activation> <dependencies> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg</artifactId> <version>${ffmpeg.version}</version> <classifier>linux-x86_64</classifier> </dependency> </dependencies> </profile> <profile> <id>windows-x86_64</id> <activation> <os> <family>windows</family> <arch>amd64</arch> </os> </activation> <dependencies> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg</artifactId> <version>${ffmpeg.version}</version> <classifier>windows-x86_64</classifier> </dependency> </dependencies> </profile> </profiles>用ffmpeg-platform其实不需要这一步,它会根据当前系统只加载对应平台库,但体积偏大。
6. 从报错到预防:一套可复用的管理模板
6.1 依赖版本锁定最佳实践
维护一个独立的BOM或者属性常量:
<properties> <javacv.version>1.5.9</javacv.version> <ffmpeg.version>6.1.1-1.5.9</ffmpeg.version> </properties>然后在pom中引用属性,确保只改动一处。如果一个子项目需要不同版本,那内部依赖就存在隐患,趁早统一。
6.2 自动化检查脚本分享
我写了个小小的bash脚本,在部署前自动检查临时目录的so文件完整性:
#!/bin/bash JAVACPP_DIR="/tmp/javacpp*" for so_file in `find $JAVACPP_DIR -name "*.so" -type f`; do echo "Checking $so_file" ldd "$so_file" | grep "not found" && echo "ERROR: $so_file missing deps" || echo "OK" done把这个脚本放到CI流水线里跑一遍,能提前抓到很多环境问题。
6.3 终极方案:用JavaCV自带工具验证
JavaCV的Loader类本身提供了命令行校验功能。你可以在依赖jar包中带上org.bytedeco.javacpp.Loader类,运行:
java -jar javacpp-platform-1.5.9.jar -help不过更常用的还是通过一个小测试类:
import org.bytedeco.ffmpeg.global.avutil; import org.bytedeco.javacpp.Loader; public class FfmpegCheck { public static void main(String[] args) { System.out.println(Loader.load(avutil.class)); System.out.println(avutil.AV_PIX_FMT_GBRAP14()); } }如果打印出true和数字,一切正常。如果这里还报错,那说明你的运行环境确实有硬伤,再去排查系统库和动态库冲突。
7. 一些碎碎念的实操心得
说实话,JavaCV这套库用起来确实没有一个干净的“一键启动”体验,毕竟它本质上是把C库用Java包装了一层,中间隔着JNI这种难伺候的东西。踩过几次坑之后,我现在遇到UnsatisfiedLinkError,第一反应不是去看报错行底部,而是先看报错上部有没有Caused by:后面的内容,那里才是真正的病根。你如果在搜索框里只复制AV_PIX_FMT_GBRAP14()I这几个字符去查,大概率只能查到一堆问同一个问题的人,而查不到答案。正确做法是复制libavutil.so: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version CXXABI_1.3.13 not found这类信息,准确度立刻提升一个量级。
再说一个容易被忽略的坑:就是JVM宕机留下的半截tmp目录。JavaCV每次启动会随机生成一个/tmp/javacpp<随机数>目录,但如果上次运行被kill,目录没清干净,可能会残留一堆旧版本的库。遇到灵异般“有时启动成功有时失败”的情况,先清掉/tmp/javacpp*再试。这种问题最气人,因为它无法复现,但解决方式极其简单。
最后送各位一句真心话:如果你的需求只是拿FFmpeg做命令行处理,真的没必要在Java里引这个库绕一大圈,直接调系统命令ffmpeg进程完全足够。只有需要做自定义解析、滤镜或实时流处理的时候,再考虑JavaCV也不迟。架构上多引入一层重依赖,就得多承担一层环境风险,这个账要算清楚。