JAVA 视频压缩

2023-05-16

项目依赖

开发引入Windows依赖,生产引入linux依赖;建议一次都引入

		<!-- 视频压缩 -->
		<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>

代码

picName不要和文件重名;不然报错

import ws.schild.jave.Encoder;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;
import ws.schild.jave.info.AudioInfo;
import ws.schild.jave.info.VideoInfo;

import java.io.File;
import java.math.BigDecimal;

/**
 * 视频压缩工具类
 */
public class VideoUtil {

    /**
     * 传视频File对象(这是一个具体的文件),返回压缩后File对象信息
     * @param source
     */
    public static File compressionVideo(File source,String picName) {
        if(source == null){
            return null;
        }
        String newPath = source.getAbsolutePath().substring(0, source.getAbsolutePath().lastIndexOf(File.separator)).concat(File.separator).concat(picName);
        File target = new File(newPath);
        try {
            MultimediaObject object = new MultimediaObject(source);
            // 根据视频大小来判断是否需要进行压缩,
            int maxSize = 200;
            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 ");
            // 视频 > 200MB, 或者每秒 > 0.5 MB 才做压缩
            boolean temp = mb > maxSize || bd.compareTo(new BigDecimal(0.5)) > 0;
            if(temp){
                long time = System.currentTimeMillis();
                // 视频压缩参数
                int maxAudioBitRate = 128000;
                int maxSamplingRate = 44100;
                int maxVideoBitRate = 800000;
                int maxFrameRate = 20;

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

                // 视频编码属性配置
                VideoInfo videoInfo = object.getInfo().getVideo();
                VideoAttributes video = new VideoAttributes();
                //设置音频比特率,单位:b (比特率越高,清晰度/音质越好,当然文件也就越大 800000 = 800kb)
                if(videoInfo.getBitRate() > maxVideoBitRate){
                    video.setBitRate(maxVideoBitRate);
                }
                // 视频帧率:15 f / s  帧率越低,效果越差
                // 设置视频帧率(帧率越低,视频会出现断层,越高让人感觉越连续),视频帧率(Frame rate)是用于测量显示帧数的量度。
                // 所谓的测量单位为每秒显示帧数(Frames per Second,简:FPS)或“赫兹”(Hz)。
                if(videoInfo.getFrameRate() > maxFrameRate){
                    video.setFrameRate(maxFrameRate);
                }

                EncodingAttributes attr = new EncodingAttributes();
                attr.setOutputFormat("mp4");
                attr.setAudioAttributes(audio);
                attr.setVideoAttributes(video);
                // 设置线程数
                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 target;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(target.length() > 0){
                source.delete();
            }
        }
        return source;
    }

}

文件转换工具

前端接收的文件格式为:MultipartFile
后端需要转换为:File

import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class MultipartFileAndFileUtils {

    /**
     * MultipartFile 转 File
     * @param file
     * @throws Exception
     */
    public static File toFile(MultipartFile file) throws Exception {
        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    /**
     *  File 转 MultipartFile
     * @param file
     * @throws Exception
     */
    public static MultipartFile toMultipartFile(File file) throws Exception {
        InputStream inputStream = new FileInputStream(file);
        MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),"application/octet-stream", inputStream);
        return multipartFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除本地临时文件
     * @param file
     */
    public static void delteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }

}

关于报错

ws.schild.jave.EncoderException: Exit code of ffmpeg encoding run is 1
是因为代码来设置了 setCodec;默认不传也可以压缩。
注:一个800M的文件可以压缩到400M左右;我本地测试压缩时间为30分钟左右。
linuxu环境没有测试;可参考以下文章进行配置。

参考文章

Java 压缩视频(无需安装插件)
java视频压缩大小,亲测有效
JAVA,实现视频压缩(最全)
视频压缩(记录)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA 视频压缩 的相关文章

  • 如何将本机库链接到 IntelliJ 中的 jar?

    我正在尝试在 IntelliJ 中设置 OpenCV 但是我一直在弄清楚如何告诉 IntelliJ 在哪里可以找到本机库位置 在 Eclipse 中 添加 jar 后 您可以在 Build Config 屏幕中设置 Native 库的位置
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 如何获取之前的URL?

    我需要调用我的网络应用程序的 URL 例如 如果有一个从 stackoverflow com 到我的网站 foo com 的链接 我需要 Web 应用程序 托管 bean 中的 stackoverflow 链接 感谢所有帮助 谢谢 并不总是
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • 内部类的构造函数引用在运行时失败并出现VerifyError

    我正在使用 lambda 为内部类构造函数创建供应商ctx gt new SpectatorSwitcher ctx IntelliJ建议我将其更改为SpectatorSwitcher new反而 SpectatorSwitcher 是我正
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db
  • Spring Rest 和 Jsonp

    我正在尝试让我的 Spring Rest 控制器返回jsonp但我没有快乐 如果我想返回 json 但我有返回的要求 完全相同的代码可以正常工作jsonp我添加了一个转换器 我在网上找到了用于执行 jsonp 转换的源代码 我正在使用 Sp

随机推荐

  • VINS-Fusion 外参标定效果分析(二)

    测试边缘化对外参标定的影响 参考VIN Fusion中原本的vector2double double2vector和optimization函数 xff0c 在代码中添加vector2double ex double2vector ex和o
  • keil遇到的警告汇总

    文章目录 警告 191 D 警告 191 D user Dataex c 500 warning 191 D type qualifier is meaningless on cast type 警告 xff1a 191 D xff1a 类
  • MOT:A Higher Order Metric for Evaluating Multi-object Tracking

    简介 HOTA A Higher Order Metric for Evaluating Multi object Tracking是IJCV 2020的paper xff0c 在此之前以MOTChallenge为主的多目标跟踪benchm
  • 如何更新Ubuntu系统、调整多系统启动顺序

    如何更新Ubuntu系统 调整多系统启动顺序 安装包 升级前系统前 xff0c 第一个命令或者说动作是 xff1a 以下命令需要在Ubuntu终端窗口内执行 xff0c 打开终端的快捷键是 xff1a CTRL 43 alt 43 T sp
  • git新建仓库,本地分支由master变为main

    由于一些众所周知的原因 xff0c github上传代码的默认分支由master变为了main 还是我昨天新建仓库的时候发现的 xff08 以前的仓库并不受影响 xff09 但本地分支仍旧为master xff0c 这就导致上传之后仓库有两
  • 调试笔记2:SPI+DMA

    一 内容简介 说明 xff1a 关于DMA xff0c SPI的基本知识这里不做介绍 本文只讲述SPI 43 DMA的实现 这里仅实现从外设到内存 从内存到外设也可以参考修改 目的 xff1a 使用STM32作为SPI从机接收数据 xff0
  • ANO匿名上位机V7协议&STM32

    ANO匿名上位机V7协议 amp STM32 说明 xff1a 以下程序为自己编写 xff0c 若有误欢迎各位指出 基于ANO匿名V7上位机的通信协议编写的代码 文章目录 ANO匿名上位机V7协议 amp STM32前言一 Ano V7上位
  • Makefile教程

    1 Makefile 简介 Makefile 是和 make 命令一起配合使用的 很多大型项目的编译都是通过 Makefile 来组织的 如果没有 Makefile 那很多项目中各种库和代码之间的依赖关系不知会多复杂 Makefile的组织
  • centos8安装docker错误解决

    安装出现 Problem problem with installed package buildah Last metadata expiration check 0 08 17 ago on Sat 20 Feb 2021 12 43
  • 深度学习环境配置记录——RTX3050

    一 下载 首先需要先了解一下深度学习环境需要的各个软件之间的关系 xff1a 从源代码构建 TensorFlow google cn 然后了解自己的电脑 NVIDIA控制面板中查看显卡驱动 xff0c 注意这个只是显卡驱动的版本 xff0c
  • RT-Thread— 知识点总结(RTT认证+面试题汇总)

    RT Thread 知识点总结 内核 RO xff1a 只读数据段 xff0c 存放程序中定义的常量 RO Size xff1a code 43 RO Data gt 占用flash大小 RW xff1a 读写数据段 xff0c 存放非0全
  • 建立本地分支与远程分支关联

    文章目录 全过程使用的指令1 1 更新 remote 版本1 2 建立一个新的分支与远程分支对应1 3 关联远程仓库分支 全过程使用的指令 span class token function git span fetch span clas
  • 遥感卫星飞行控制系统设计

    文章目录 1 卫星姿态控制模块组成2 转动惯量和地球自转角速度3 初始姿态和目标姿态4 欧拉角转四元数及四元数转欧拉角5 仿真6 绘图分析 1 卫星姿态控制模块组成 其中执行机构为零动量反作用飞轮 xff0c 此处略去 xff1b 传感器测
  • Objects Track Benchmarks

    MOT 2D MOT MOT challengeTAOCaltech Roadside PedestriansBDD100KWaymoAOTPANDAArgoVerseHiEve Multi person Motion TrackingUA
  • 树莓派4B全40管脚对应功能示意图

    以下两图中 xff0c 图1是树莓派引脚功能图 xff0c 其对应图2红框标注的部分 xff0c 黄色数字标注了对应的管脚 谢谢评论区指正 xff0c 实在抱歉 xff0c 实物图部分误用了树莓派1代的实物图 xff0c 但树莓派4b整体布
  • 【数据结构与算法】车辆路径问题(Vehicle Routing Problem,VRP)

    车辆路径问题 xff08 Vehicle Routing Problem VRP xff09 什么是车辆路径问题 车辆路线问题 xff08 VRP xff09 是指一定数量的客户 xff0c 各自有不同数量的货物需求 xff0c 配送中心向
  • 护士实习自我鉴定

    医院实习护士的评价 篇一 短短一个月的泌尿外科实习生活已接近尾声 xff0c 回顾这段时间的实习生活 xff0c 我感受很深 泌尿外科是我实习的第二站 xff0c 相对肝胆外科就不是那么的忙碌 在泌尿外科经历的业务学习是让我印象最深刻的 x
  • uni-app 实现照片水印并上传照片

    话不多说 xff0c 直接代码 lt template gt lt view class 61 34 wrap 34 gt lt u form model 61 34 model 34 ref 61 34 uForm 34 gt lt u
  • 文档服务器minio 可通过文件路径进行访问

    方法一 登陆服务器 xff0c 直接修改桶的权限 xff1a 1 2 3 4 方法二 创建桶的时候设置桶的策略 xff08 注 xff1a minio版本过高 xff0c 可能没有此方法 xff09 创建一个名为managertest的文件
  • JAVA 视频压缩

    项目依赖 开发引入Windows依赖 xff0c 生产引入linux依赖 xff1b 建议一次都引入 lt 视频压缩 gt lt dependency gt lt groupId gt ws schild lt groupId gt lt