java.lang.NoClassDefFoundError: Could not initialize class org.bytedeco.ffmpeg.global.avutil
使用javacv,ffmpeg视频流按帧转图片中出现的问题, 在idea的开发环境中运行没问题,linux中使用jar包部署也没问题. 就在docker中报错
网上查找了很多信息, 说是依赖问题, 换了很多依然有报错, 也有说是openjdk和普通jdk的问题, 都切换用过也还是报错
下面为我的代码和依赖
@Async("video-to-image-")
@Override
public void starVideoToImage(String url, String videoName) throws Exception {
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(url);
//javacv只打印错误日志(不加这行会导致由于视频流格式或像素不推荐或过时导致一直打印警告日志(不影响功能))
// 默认情况下,JavaCV 使用 RTSP 传输协议中的 UDP 方式进行数据传输,
// 如果视频服务器不支持 UDP 协议,则需要手动设置使用 TCP 协议进行数据传输。设置方法如下:
grabber.setOption("rtsp_transport", "tcp");
grabber.start();
Frame frame;
//视频帧数 (此视频流一秒多少帧)
double frameRate = grabber.getFrameRate();
int i = 0;
while ((frame = grabber.grab()) != null) {
String continueOrNot = (String) redisTemplate.opsForValue().get(videoName);
if (StringUtils.equals("true", continueOrNot)) {
// 过滤前 jumpTime 帧,避免出现全黑的图片,依自己情况而定
//每 splitTime 帧 生成一张图片保留,若显示帧不为关键帧,则寻找相邻的下一帧,
if ((i % frameRate) == 0 && i > jumpTime) {
// 对视频帧进行处理 按帧进行, 可在while加入条件
String rotate = grabber.getVideoMetadata("rotate");// 视频的旋转角度
frame = processFrame(frame, rotate, videoName);
}
// 强制线程休息,使其他线程竞争, 避免此线程霸占cpu导致占用率过高问题
Thread.sleep(1);
//只截一张图
// if (i == frameRate) {
// break;
// }
i++;
} else {
break;
}
}
grabber.stop();
grabber.release();
}
下面是处理图片的代码
private void doExecuteFrame(Frame f, String targetFileName) throws Exception {
if (null == f || null == f.image) {
return;
}
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.getBufferedImage(f);
//转流
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bi, "JPG", os);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
//上传到minio(测试)
//文件夹
String dataFolder = DateUtil.format(new Date(), "yyyy-MM-dd");
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(dataFolder + "/" + targetFileName)
.stream(byteArrayInputStream, byteArrayInputStream.available(), -1)
.contentType("JPG")
.build()
);
}
下面是我的依赖(windos和linux使用不同的)
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.7</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<version>5.0-1.5.7</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<version>5.0-1.5.7</version>
<!-- <classifier>windows-x86_64</classifier>-->
<classifier>linux-x86_64</classifier>
</dependency>
下面是我的报错
java.lang.NoClassDefFoundError: Could not initialize class org.bytedeco.javacv.FFmpegFrameGrabber
at com.zh.ipdata.selfTest.videoTask.service.impl.VideoServiceImpl.starVideoToImage(VideoServiceImpl.java:41) ~[classes!/:na]
at com.zh.ipdata.selfTest.videoTask.service.impl.VideoServiceImpl$$FastClassBySpringCGLIB$$a02b32bb.invoke(<generated>) ~[classes!/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at com.zh.cloud.core.aop.MultipleDataSourceAspect.doAround(MultipleDataSourceAspect.java:63) ~[zh-cloud-core-3.2.7-zh.jar!/:na]
at sun.reflect.GeneratedMethodAccessor325.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_181]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_181]