qq_39297720 2023-09-25 15:26 采纳率: 0%
浏览 41

使用javacv,ffmpeg视频流按帧转图片中出现的问题, 在idea的开发环境中运行没问题,linux中使用jar包部署也没问题. 就在docker中报错

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]
  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-09-25 15:45
    关注

    引自免费小程序-皆我百晓生,希望对题主有所帮助,如有帮助,还请采纳。


    这个问题可能是由于加载ffmpeg库文件时出现了错误。在Linux-Docker环境中,可能需要额外的配置和依赖项来正确加载这些库文件。

    以下是一些可能的解决方案:

    1. 确保在Docker镜像中有FFmpeg库文件的正确版本。您可以尝试手动将库文件复制到Docker容器中,或者使用第三方Docker镜像,该镜像已包含FFmpeg库文件。

    2. 确保在Docker容器中正确设置了环境变量。您可以通过在Dockerfile中添加ENV语句或在运行Docker容器时使用-e参数来设置环境变量。

    3. 检查FFmpeg库文件的路径是否正确。可能需要在代码中显式设置FFmpeg库文件的路径,例如通过调用Loader.load(org.bytedeco.ffmpeg.global.avutil.class)。

    4. 确保将所有依赖项正确添加到Docker镜像或Dockerfile中。您可能还需要添加其他依赖项,以确保FFmpeg库文件能够正确加载。

    5. 如果以上解决方案都没有解决问题,您可以尝试使用其他方法来将视频流转换为图片,例如使用Java自带的库或其他第三方库。

    希望这些解决方案能帮助您解决问题。如果问题仍然存在,请提供更多关于您的Docker环境和配置的信息,以便我们可以更进一步地帮助您解决问题。

    评论

报告相同问题?

问题事件

  • 修改了问题 9月26日
  • 修改了问题 9月26日
  • 修改了问题 9月26日
  • 修改了问题 9月25日
  • 展开全部

悬赏问题

  • ¥300 寻抓云闪付tn组成网页付款链接
  • ¥15 请问Ubuntu要怎么安装chrome呀?
  • ¥15 视频编码 十六进制问题
  • ¥15 Xsheii7我安装这个文件的时候跳出来另一个文件已锁定文件的无一部分进程无法访问。这个该怎么解决
  • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)
  • ¥15 服务端控制goose报文控制块的发布问题