一、简介
使用FFmpeg对视频进行压缩,6核12线程的情况下压缩10s的mp4平均用时1s
二、maven依赖
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-core</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-nativebin-win64</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.20</version>
</dependency>
三、工具类源码
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.IdUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.File;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class VideoCompressUtils {
private static final Logger logger = LoggerFactory.getLogger(VideoCompressUtils.class);
private static final AtomicInteger compressingCount = new AtomicInteger(0);
private static final int maxBitRate = 128000;
private static final int maxSamplingRate = 44100;
private static final int bitRate = 800000;
private static final int maxFrameRate = 20;
private static final int maxWidth = 1280;
private static final Integer encodingThreads = Integer.valueOf(Runtime.getRuntime().availableProcessors() / 2);
public static File compression(File sourceFile, String fileType) {
if (sourceFile == null) {
return null;
}
TimeInterval timer = DateUtil.timer();
logger.info("准备压缩视频: " + sourceFile.getName());
String newFilePath = sourceFile.getParent() + File.separator + IdUtil.simpleUUID() + "." + fileType;
File newFile = new File(newFilePath);
try {
MultimediaObject object = new MultimediaObject(sourceFile);
EncodingAttributes attr = new EncodingAttributes();
AudioInfo audioInfo = object.getInfo().getAudio();
if (audioInfo != null) {
AudioAttributes audio = new AudioAttributes();
if (audioInfo.getBitRate() > maxBitRate) {
audio.setBitRate(new Integer(maxBitRate));
}
audio.setChannels(audioInfo.getChannels());
if (audioInfo.getSamplingRate() > maxSamplingRate) {
audio.setSamplingRate(maxSamplingRate);
}
attr.setAudioAttributes(audio);
}
ws.schild.jave.info.VideoInfo videoInfo = object.getInfo().getVideo();
VideoAttributes video = new VideoAttributes();
video.setCodec("h264");
if (videoInfo.getBitRate() > bitRate) {
video.setBitRate(bitRate);
}
if (videoInfo.getFrameRate() > maxFrameRate) {
video.setFrameRate(maxFrameRate);
}
int width = videoInfo.getSize().getWidth().intValue();
int height = videoInfo.getSize().getHeight().intValue();
if (width > maxWidth) {
float rat = (float) width / maxWidth;
video.setSize(new VideoSize(maxWidth, (int) (height / rat)));
}
attr.setVideoAttributes(video);
attr.setEncodingThreads(encodingThreads);
while (compressingCount.get() >= 3) {
TimeUnit.SECONDS.sleep(3);
}
compressingCount.incrementAndGet();
logger.info("压缩视频开始: " + sourceFile.getName() + ", 当前正在压缩视频数: " + compressingCount.get());
try {
new Encoder().encode(new MultimediaObject(sourceFile), newFile, attr);
} finally {
compressingCount.decrementAndGet();
}
logger.info("视频压缩完成: " + sourceFile.getName() + ": " + timer.intervalSecond());
return newFile;
} catch (Exception e) {
logger.error("压缩视频失败: " + sourceFile.getName() + ": " + e.getLocalizedMessage(), e);
}
return null;
}
}
四、系统环境配置
- 进入maven本地仓库,找到 jave-nativebin-win64-3.4.0.jar 并以压缩包方式打开

- 提取出jar包中的 ffmpeg-amd64.exe 文件,重命名为 ffmpeg-amd64-3.4.0.exe

3、将 ffmpeg-amd64-3.4.0.exe 复制到系统临时文件夹和tomcat的临时文件夹\jave下(没有jave就新建一个)
(1) 系统临时文件夹\jave(linux的路径是/tmp/jave/)

(2) tomcat的临时文件夹\jave
