全面指南:使用Java进行视频压缩的实现
最编程
2024-08-03 18:56:56
...
说明
Java压缩视频大小,10M视频压缩完成后大约是1M,用时大约2S
技术:基于 fffmpeg 技术实现视频压缩
条件:需要maven引入jar包
步骤一
- 引入pom基础依赖(前提是maven工程,在 pom.xml 文件中添加如下行)
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-core</artifactId>
<version>3.0.0</version>
</dependency>
- 依据服务器操作系统来设定如下包(此处我是用win10-64位),部署到服务器一般是linux,所以建议下面行都加入 pom.xml文件中
<!-- 在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>
步骤二
具体的代码(压缩视频)
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.VideoSize;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.channels.FileChannel;
/**
* 传视频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);
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 ");
// 视频 > 5MB, 或者每秒 > 0.5 MB 才做压缩, 不需要的话可以把判断去掉
boolean temp = mb > maxSize || bd.compareTo(new BigDecimal(0.5)) > 0;
// if(temp){
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(new Integer(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 target;
// }
} catch (Exception e) {
e.printStackTrace();
}finally {
if(target.length() > 0){
source.delete();
}
}
return source;
}
注意事项
正常只在windows操作系统上开发代码没问题。
但是部署到linux上跑项目,还需要2个步骤:
1.在刚刚依赖的jar包中,找到箭头文件夹
上面箭头点进去,找到下面箭头文件
把它复制到桌面并解压它,得到如下 数字1 文件:
你需要重命名为跟pom.xml版本一致的名字,也就是 数字2 那个文件。
2.把数字2文件,复制丢到linux服务器的 /tmp/java 路径下(99%的linux服务器是这样的路径,如果没有就创建文件夹并丢进去)
提醒:如果“ffmpeg-amd64-3.0.0” 文件丢到 “ /tmp/java ”不起作用,建议到报错的代码,也就是下面这儿检查(我就是看源码解决的)
MultimediaObject object = new MultimediaObject(source);
或者到类 DefaultFFMPEGLocator.class 中看具体使用哪个路径,但是大部分都是 /tmp/java路径,相信我!!!!!!!!
下一篇: 用Java在网上下载视频的实操教程
推荐阅读
-
Java 8新特性探究(十三)JavaFX 8新特性以及开发2048游戏-JavaFX历史## 跟java在服务器端和web端成绩相比,桌面一直是java的软肋,于是Sun公司在2008年推出JavaFX,弥补桌面软件的缺陷,请看下图JavaFX一路走过来的改进 从上图看出,一开始推出时候,开发者需使用一种名为JavaFX Script的静态的、声明式的编程语言来开发JavaFX应用程序。因为JavaFX Script将会被编译为Java bytecode,程序员可以使用Java代码代替。 JavaFX 2.0之后的版本摒弃了JavaFX Script语言,而作为一个Java API来使用。因此使用JavaFX平台实现的应用程序将直接通过标准Java代码来实现。 JavaFX 2.0 包含非常丰富的 UI 控件、图形和多媒体特性用于简化可视化应用的开发,WebView可直接在应用中嵌入网页;另外 2.0 版本允许使用 FXML 进行 UI 定义,这是一个脚本化基于 XML 的标识语言。 从JDK 7u6开始,JavaFx就与JDK捆绑在一起了,JavaFX团队称,下一个版本将是8.0,目前所有的工作都已经围绕8.0库进行。这是因为JavaFX将捆绑在Java 8中,因此该团队决定跳过几个版本号,迎头赶上Java 8。 ##JavaFx8的新特性 ## ###全新现代主题:Modena 新的Modena主题来替换原来的Caspian主题。不过在Application的start方法中,可以通过setUserAgentStylesheet(STYLESHEET_CASPIAN)来继续使用Caspian主题。 参考http://fxexperience.com/2013/03/modena-theme-update/ ###JavaFX 3D 在JavaFX8中提供了3D图像处理API,包括Shape3D (Box, Cylinder, MeshView, Sphere子类),SubScene, Material, PickResult, LightBase (AmbientLight 和PointLight子类),SceneAntialiasing等。Camera类也得到了更新。从JavaDoc中可以找到更多信息。 ###富文本 强化了富文本的支持 ###TreeTableView ###日期控件DatePicker 增加日期控件 ###用于 CSS 结构的公共 API
-
使用Java进行3D建模的实现
-
全面指南:使用JavaScript进行网页跳转的方法
-
全面指南:使用TestNG、Mockito和Powermock进行Java单元测试
-
全面指南:使用Ansys(Ansoft)Maxwell RMxprt进行电机仿真实验的入门教程
-
全面指南:使用Ansys(Ansoft)Maxwell RMxprt进行电机仿真实验的入门教程
-
全面指南:使用Java进行视频压缩的实现
-
使用Java的MultipartFile进行视频压缩
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
如何在Eclipse中使用Java JPDA进行远程应用程序调试 - 配置Java应用的步骤指南