JavaCV视频截图
参考文献
https://blog.csdn.net/syz_mumu/article/details/77203247 用Java代码提取视频的缩略图的两种办法
https://blog.csdn.net/zs770635620/article/details/80387932 视频截图-javacv
https://askubuntu.com/questions/453368/skype-error-while-loading-shared-libraries-libxv-so-1-cannot-open-shared-obje 安装libXV.so1文件
最近项目涉及视频上传的问题,有一个需求
就是上传视频后要截取以帧画面作为该视频文件的预览图。经过一番查找后,最终决定使用javaCV这个工具。
导入包
javaCV的使用方法非常简单。如果是使用maven管理jar包的话,可以直接在pom.xml中添加依赖:
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>0.8</version>
</dependency>
这里有两点需要注意的:
不要手动导入相关的包,如果包版本不一致,会一直抛classNotFound异常;
导入0.8版本的包,maven就会自动将相关的包到进来。
使用方法
请看参考文献1《用Java代码提取视频的缩略图的两种办法》,里面包括具体代码
注意事项
许多人提问:使用JavaCV在windows本地成功运行,导出war包后上传到linux服务器上就出现异常了(如果没有出现异常,大概率是因为异常被try catch捕获了)。
具体的异常如下:
java.lang.NoClassDefFoundError: Could not initialize class org.bytedeco.javacpp.avutil
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at org.bytedeco.javacpp.Loader.load(Loader.java:390)
at org.bytedeco.javacpp.Loader.load(Loader.java:358)
at org.bytedeco.javacpp.avformat$AVFormatContext.<clinit>(avformat.java:2539)
at org.bytedeco.javacv.FFmpegFrameGrabber.startUnsafe(FFmpegFrameGrabber.java:383)
at org.bytedeco.javacv.FFmpegFrameGrabber.start(FFmpegFrameGrabber.java:377)
at com.example.Application.convert(Application.java:53)
at com.example.Application.run(Application.java:103)
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:674)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:969)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:958)
at com.example.Application.main(Application.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
重复观察发现,重启项目后第一次错误信息是:
java.lang.UnsatisfiedLinkError: /tmp/javacpp777320859500247/[图片]libjniavdevice.so: [图片]libXv.so.1: cannot open shared object file: No such file or directory
具体的异常如下:
java.lang.UnsatisfiedLinkError: no jniavdevice in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) ~[?:1.8.0_144]
at java.lang.Runtime.loadLibrary0(Runtime.java:870) ~[?:1.8.0_144]
...
Caused by: java.lang.UnsatisfiedLinkError: /tmp/javacpp777320859500247/[图片]libjniavdevice.so: [图片]libXv.so.1: cannot open shared object file: No such file or directory
而第二次之后的错误信息才是:
java.lang.NoClassDefFoundError
这是因为第一次启动更需要加载相关库,而环境缺少相关库(或jar包版本不一致)
解决办法
- 如果是缺少相关的库,那么大概率就是linux环境缺少libXV.so1文件,安装即可
#定位,检查是否安装
#64位
locate /usr/lib/x86_64-linux-gnu/libXv.so.1
#32位
locate /usr/lib/i386-linux-gnu/libXv.so.1
#如果定位成功表示已安装
#检查是否安装
dpkg --get-selections | grep libxv1
#如果返回libxv1:xxx install表示已安装
#安装,注意32位的是i386,64位的是amd64
sudo apt-get install libxv1:i386
#检查是否安装
dpkg --get-selections | grep libxv1
- 如果环境已安装libXV.so1文件,则是jar包版本不一致
如果在windows64位环境编译的程序,maven会自动导入的包都带windows-x86_64
后缀的,如下:
如果在linux32位环境编译的程序,maven会自动导入的包都带linux-x86
后缀的,如下:
而部署环境如果不是windows64位环境(编译与部署不相同),就会报以上错误,甚至与win64环境编译的war包在win32下部署运行也会报错。
所以编译环境和部署环境一定要相同
.
以下提供部分后缀:
win64:windows-x86_64
win32:windows-x86
linux64:linux-x86_64
linux32:linux-x86