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 视频压缩 的相关文章

  • Java简单加密

    我想加密存储在磁盘上的文本 配置 文件 尝试使用DES http en wikipedia org wiki Data Encryption Standard加密 我在客户端计算机上遇到了致命错误 后来我发现该算法无法处理重音字符 我怀疑这
  • Criteria eager fetch-joined 集合以避免 n+1 选择

    假设 Item 和 Bid 是实体 一个 Item 有多个 Bid 它们被映射到休眠在典型的父子关系中
  • 如何向 OkHttp 请求拦截器添加标头?

    我将这个拦截器添加到我的 OkHttp 客户端 public class RequestTokenInterceptor implements Interceptor Override public Response intercept C
  • Spring MVC 中的 CSRF(跨站请求伪造)保护

    我对春季的 CSRF 跨站请求伪造 保护有点困惑 不 我有我的 jsp 我的控制器和一个 Web 服务 我想要做的是在 Web 服务级别验证令牌 如果令牌匹配 则运行 Web 服务 在我的例子中执行数据库插入 JSP file
  • Java - 了解 PrintWriter 和刷新的需要

    好吧 首先我对所有代码表示歉意 但我觉得代码太多总比代码不够好 我正在制作一个简单的聊天客户端和印刷机 尤其是我正在努力解决的问题 使用现在的代码 它将与服务器类交互 并且完美地打印我想要打印的内容 但是 当我删除 writer flush
  • 平衡括号问题的优化解

    给定一个仅包含字符的字符串 and 判断输入字符串是否有效 输入字符串在以下情况下有效 左括号必须由相同类型的括号封闭 左括号必须按正确的顺序关闭 请注意 空字符串也被视为有效 示例1 Input Output true Example 2
  • ORMLite - join where 子句中的括号

    我想使用连接三个表QueryBuilder join and QueryBuilder joinor但我想在 where 子句中添加括号 如下所示 WHERE first table where AND second table where
  • 使用用户名进行 Java LDAP 身份验证

    好吧 这让我发疯 我正在尝试使用 Java 创建 LDAP 身份验证 如果我在 SECURITY PRINCIPAL 中使用我的名字和姓氏 一切都很好 这是我的代码 try Hashtable
  • Eclipse 内容协助无法在枚举常量参数列表中工作

    使用 eclipse 当我输入以下内容时 public enum Foo A Integer private final Integer integer private Foo Integer integer this integer in
  • 读取 Nashorn JO4 和 NativeArray

    Java调用代码 import jdk nashorn api scripting myCustomHashMap dataStore new myCustomHashMap ScriptEngineManager sem new Scri
  • 大型 XML 的 XML 节点到字符串转换

    到目前为止我一直在使用DOM源在我的 Android 应用程序中将 XML 文件转换为字符串 这是我的代码 public String convertElementToString Node element throws Transform
  • 基于Java模式分割字符串

    您好 我有以下模式的日志文件 2014 03 06 03 21 45 432 ERROR mfs pool 3 thread 19 dispatcher StatusNotification Error processing notific
  • 未从线程接收位置数据

    我尝试使用计时器经常发送包含用户位置的短信 最初 我遇到了空指针异常 这是由于我犯了一个简单的错误 一旦解决了这个问题 一切似乎都运行良好 但是 它永远不会获取我的位置 因此 不断发送的文本显示 无法接收位置 我想问的是为什么它无法获取我的
  • 无法从 ViewPager 中的 Fragment 编辑 ActionBar 标题

    我有一个Activity它通过一个托管多个片段ViewPager 在活动的onCreate方法我使用以下代码来更改ActionBar title Toolbar toolbar findViewById R id toolbar setSu
  • JavaFX 8 默认消息图标

    随着 JavaFX 的最近几次更新 我们收到了警报 我想获取消息的默认图标 错误 警告 在Swing中 我可以通过一些方式获取L F消息图标UIManager的属性 如何在 JavaFX 中获取消息的默认图标 它们是包含在属性中 还是由 C
  • System.out.println("嗨"+6+10);打印Hi610?

    为什么要这样做 太令人困惑了 运算符优先级和结合性 两点 操作员 如果一个或两个参数都是字符串 则进行字符串连接 操作员 从左到右工作 所以在你的例子中 Hi 6 is Hi6 and Hi6 10 is Hi610 编辑 正如您在对另一个
  • SecurityContextHolder.getContext().getAuthentication() 返回 null

    我想使用以下代码手动绕过 spring Security 的用户 User localeUser new User UsernamePasswordAuthenticationToken auth new UsernamePasswordA
  • JSF - 实施受限页面过滤器

    我正在关注 BalusC 的回答JSF 2 0 如何获取在浏览器地址栏中输入的 URL https stackoverflow com questions 4105263 jsf 2 0 how to get the url that is
  • 如何设置 commons-logging 来使用 logback?

    我们使用 slf4j logback 并且碰巧有一些使用 commons logging 的第三方库 如何设置它以使用 logback 答案是不要使用 commons logging jar 因为 SLF4J 的设计目的与 commons
  • Hibernate 命名查询使用 Like 和 % % 运算符?

    在我的 Hibernate JPA 示例代码中 public List

随机推荐

  • 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