java ffmpeg压缩视频报错踩坑整理+解决措施:

这篇具有很好参考价值的文章主要介绍了java ffmpeg压缩视频报错踩坑整理+解决措施:。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者:丘杨(如需转载请注明出处)

背景:

为加快网页加载速度,压缩相关视频文件。其中发现在进行视频压缩的时候会报ws.schild.jave.EncoderException: Exit code of ffmpeg encoding run is 1错误,本文章旨在记录踩坑历史。

原代码:

参考文章:视频压缩(记录)_videoattributes-CSDN博客

本代码基于参考文章的基础上,将入参改为inputstream,出参改为byte以适配minio上传、下载文件的需求。

maven:

        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-core</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!-- 在windows上开发 开发机可实现压缩效果 window64位 -->
        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-nativebin-win64</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!-- 在linux上部署 linux服务器需要这个才能生效 linux64位 -->
        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-nativebin-linux64</artifactId>
            <version>3.0.0</version>
        </dependency>

原代码:

    /**
     * 传视频File对象(这是一个具体的文件),返回压缩后File对象信息
     *
     * @param inputStream
     */
    public byte[] compressionVideo(InputStream inputStream, String suffix) throws EncoderException, IOException {
        if (inputStream == null) {
            return null;
        }
        File source = null;
        File target = null;
        try {
            source = File.createTempFile("source", suffix);
            target = File.createTempFile("target", suffix);
            OutputStream outputStream = new FileOutputStream(source);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
            inputStream.close();
            outputStream.close();

            MultimediaObject object = new MultimediaObject(source);
            AudioInfo audioInfo = object.getInfo().getAudio();
            // 根据视频大小来判断是否需要进行压缩,
            int maxSize = 5;
            double mb = Math.ceil(source.length() / 1048576);
            int second = (int) object.getInfo().getDuration() / 1000;
            BigDecimal bd = new BigDecimal(String.format("%.4f", mb / second));
            System.out.println("开始压缩视频了--> 视频每秒平均 " + bd + " MB ");
            long time = System.currentTimeMillis();
            //TODO 视频属性设置
            int maxBitRate = 128000;
            int maxSamplingRate = 44100;
            int bitRate = 800000;
            int maxFrameRate = 20;
            int maxWidth = 1280;

            AudioAttributes audio = new AudioAttributes();
            // 设置通用编码格式10                   audio.setCodec("aac");
            // 设置最大值:比特率越高,清晰度/音质越好
            // 设置音频比特率,单位:b (比特率越高,清晰度/音质越好,当然文件也就越大 128000 = 182kb)
            if (audioInfo.getBitRate() > maxBitRate) {
                audio.setBitRate(maxBitRate);
            }
            // 设置重新编码的音频流中使用的声道数(1 =单声道,2 = 双声道(立体声))。如果未设置任何声道值,则编码器将选择默认值 0。
            audio.setChannels(audioInfo.getChannels());
            // 采样率越高声音的还原度越好,文件越大
            // 设置音频采样率,单位:赫兹 hz
            // 设置编码时候的音量值,未设置为0,如果256,则音量值不会改变
            // audio.setVolume(256);
            if (audioInfo.getSamplingRate() > maxSamplingRate) {
                audio.setSamplingRate(maxSamplingRate);
            }


            //TODO 视频编码属性配置
            ws.schild.jave.info.VideoInfo videoInfo = object.getInfo().getVideo();
            VideoAttributes video = new VideoAttributes();
//            video.setCodec("h264");
            //设置音频比特率,单位:b (比特率越高,清晰度/音质越好,当然文件也就越大 800000 = 800kb)
            if (videoInfo.getBitRate() > bitRate) {
                video.setBitRate(bitRate);
            }

            // 视频帧率:15 f / s  帧率越低,效果越差
            // 设置视频帧率(帧率越低,视频会出现断层,越高让人感觉越连续),视频帧率(Frame rate)是用于测量显示帧数的量度。所谓的测量单位为每秒显示帧数(Frames per Second,简:FPS)或“赫兹”(Hz)。
            if (videoInfo.getFrameRate() > maxFrameRate) {
                video.setFrameRate(maxFrameRate);
            }

            // 限制视频宽高
            int width = videoInfo.getSize().getWidth();
            int height = videoInfo.getSize().getHeight();
            if (width > maxWidth) {
                float rat = (float) width / maxWidth;
                video.setSize(new VideoSize(maxWidth, (int) (height / rat)));
            }

            EncodingAttributes attr = new EncodingAttributes();
//                attr.setFormat("mp4");
            attr.setAudioAttributes(audio);
            attr.setVideoAttributes(video);

            // 速度最快的压缩方式, 压缩速度 从快到慢: ultrafast, superfast, veryfast, faster, fast, medium,  slow, slower, veryslow and placebo.
//                attr.setPreset(PresetUtil.VERYFAST);
//                attr.setCrf(27);
//                // 设置线程数
//                attr.setEncodingThreads(Runtime.getRuntime().availableProcessors()/2);

            Encoder encoder = new Encoder();
            encoder.encode(new MultimediaObject(source), target, attr);
            System.out.println("压缩总耗时:" + (System.currentTimeMillis() - time) / 1000);
            return fileToBytes(target);
        } catch (
                Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            assert source != null;
            source.delete();
            assert target != null;
            target.delete();
        }

    }

    public static byte[] fileToBytes(File file) {
        FileInputStream fis = null;
        byte[] bytes = null;

        try {
            fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;

            while ((bytesRead = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }

            bytes = bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        return bytes;
    }

踩坑记录:

坑1:AudioInfo报空指针

修改compressionVideo方法:

exit code of ffmpeg encoding run is 1,ffmpeg,java,音视频

加audioInfo的空指针判断:

        if (ObjectUtils.isNotEmpty(audioInfo)) {
            if (audioInfo.getBitRate() > maxBitRate) {
                audio.setBitRate(maxBitRate);
            }
            // 设置重新编码的音频流中使用的声道数(1 =单声道,2 = 双声道(立体声))。如果未设置任何声道值,则编码器将选择默认值 0。
            audio.setChannels(audioInfo.getChannels());
            // 采样率越高声音的还原度越好,文件越大
            // 设置音频采样率,单位:赫兹 hz
            // 设置编码时候的音量值,未设置为0,如果256,则音量值不会改变
            // audio.setVolume(256);
            if (audioInfo.getSamplingRate() > maxSamplingRate) {
                audio.setSamplingRate(maxSamplingRate);
            }
        }

坑2:多个视频文件报 ws.schild.jave.EncoderException: Exit code of ffmpeg encoding run is 1

压缩视频时发现经常报ws.schild.jave.EncoderException: Exit code of ffmpeg encoding run is 1问题,debug源码后发现有如下问题:

问题1:height不能整除2导致报错

exit code of ffmpeg encoding run is 1,ffmpeg,java,音视频

解决后的代码:

// 限制视频宽高
            int width = videoInfo.getSize().getWidth();
            int height = videoInfo.getSize().getHeight();
            if (width > maxWidth) {
                float rat = (float) width / maxWidth;
                int newHeight = (int) (height / rat) % 2 == 1 ? (int) (height / rat) + 1 : (int) (height / rat);
                video.setSize(new VideoSize(maxWidth, newHeight));
            }
问题2:Specified sample rate 44100 is not supported 

bitrate不支持44100

exit code of ffmpeg encoding run is 1,ffmpeg,java,音视频

在原代码里,代码的maxSamplelingRate设置为44100

exit code of ffmpeg encoding run is 1,ffmpeg,java,音视频

暴力解决,直接删除下面代码

exit code of ffmpeg encoding run is 1,ffmpeg,java,音视频exit code of ffmpeg encoding run is 1,ffmpeg,java,音视频取了默认的96000bps,代码无报错文章来源地址https://www.toymoban.com/news/detail-808510.html

到了这里,关于java ffmpeg压缩视频报错踩坑整理+解决措施:的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FFmpeg截屏、剪切一段视频、或者压缩视频

    网上大多是通过命令的显示操作ffmpeg,不太灵活 这里我给出剪切视频的一段代码,缺点是无法精确,比如我想剪切20秒,但是可能剪切好的是23秒。 其中FFmpegFrameRecorder(outputstream)操作流会报错。原因未知。 import cn.hutool.core.io.FileUtil; import lombok.SneakyThrows; import lombok.extern.slf4j

    2024年02月12日
    浏览(40)
  • 纯前端使用ffmpeg实现视频压缩

    实现需求 用户上传视频并压缩,并且可以选择压缩程度,搜索遍各大网站,最终选择了ffmpeg进行操作。本文包含具体如何实现加上过程中遇到的各种坑 ffmpeg视频压缩代码使用很简单,上代码 html部分  js部分 这个ffmpeg大神处理好的cdn我也是找了好久才找到,之前找的各种版本

    2024年02月04日
    浏览(46)
  • 工具 | Axiom FFmpeg压缩视频教程

    目录 一、前言 闲聊 FFmpeg Axiom FFmpeg 二、具体步骤 1.下载Axiom FFmpeg 2.使用Axiom FFmpeg压缩视频 降低视频的分辨率 增大CRF         今天,老师让我把项目的演示视频发给他,要求时长5分钟。录了半个小时,终于把视频录好了,但是打开微信一发送——         行吧,我立

    2023年04月09日
    浏览(30)
  • vue 使用ffmpeg上传视频前压缩视频,压缩后在上传到服务器

    1,使用ffmpeg: npm install @ffmpeg/ffmpeg @ffmpeg/core -S ; 2,vue 引入ffmpeg 3,需要配置vue.config.js,否则会报错 完整代码:

    2024年02月11日
    浏览(44)
  • ffmpeg 视频分辨率修改 质量压缩

    随着手机像素的提高,拍摄视频也越来越大,10秒的视频动辄 二三十兆,这给视频传输和播放都带来了 诸多不变。一般都需要 前端或或者后端  对视频进行压缩。由于我这边前端是 H5,所以只能后端进行压缩, 采用主流压缩库采用 ffmpeg 进行,我这边是 nodejs 环境 先说下我

    2024年02月02日
    浏览(71)
  • element-plus的el-select实现触底加载更多(新版本报错踩坑)

    element-plus新版增加了一个属性,且默认为true,使得下拉菜单被插入到了body元素下。即.el-select下默认不包含.el-select-dropdown了。 当依旧按照之前的方式,封装自定义指令,实现滚动到el-select下拉菜单的底部,加载更多数据的功能时就会报错。 原逻辑:  报错 原因也就是前言中

    2024年02月08日
    浏览(57)
  • 使用ffmpeg修改视频分辨率同时压缩视频的质量

    调整视频的质量和码率可以使用FFmpeg中的编码选项。以下是一些常用的选项: 1 质量选项 :使用 -q:v 参数设置视频的质量等级。质量等级的范围是 0-51,其中 0 表示无损压缩,51 表示最低质量。质量等级越低,视频的文件大小就越小,但是视频的质量也会降低。 2 码率选项

    2024年02月10日
    浏览(42)
  • Vue 2.0 前端使用 ffmpeg 压缩视频

    1. (我之前因为直接装了导致报错)  要安装这个版本 npm install @ffmpeg/ffmpeg@0.10.1 -S npm install @ffmpeg/core@0.10.0 -S 2.找到vue.config.js devServer: {      headers: {       \\\"Cross-Origin-Opener-Policy\\\": \\\"same-origin\\\",       \\\"Cross-Origin-Embedder-Policy\\\": \\\"require-corp\\\",     }, } 加上红色这段代码 3

    2024年02月09日
    浏览(42)
  • FFMPEG视频压缩与Python使用方法

    FFMPEG  是一个完整的,跨平台的解决方案,记录,转换和流音频和视频。 官网:https://ffmpeg.org/ 1、Linux: 2、Mac: 3、Windows:  下载文件:  解压缩:  配置环境变量:   出现上图所示response即可说明成功安装。 1、指定视频压缩大小: -fs 10 : 表示文件大小最大值为 100MB 2、设置

    2024年02月07日
    浏览(46)
  • FFMPEG 视频类过滤器学习整理

    针对FFMPEG提供视频过滤器进行了介绍,并提供使用实例 addroi 作用 在视频帧上标记一块感兴趣的区域。 帧数据被原封不动地传递,但元数据被附加到帧,指示可能影响后续编码行为的感兴趣区域。可以通过多次应用过滤器来标记多个区域。 参数 qoffset: 应用在此区域的量化偏

    2024年02月07日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包