【Java】mp4视频压缩

一、简介

使用FFmpeg对视频进行压缩,6核12线程的情况下压缩10s的mp4平均用时1s

二、maven依赖

<!-- 3.0.0到3.4.0都可以 -->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-core</artifactId>
    <version>3.4.0</version>
</dependency>
<!-- windows用这个, linux、mac、arm也有对应依赖, 需要的去maven仓库搜一下-->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-win64</artifactId>
    <version>3.4.0</version>
</dependency>
<!-- 不爱用hutool的朋友可以自己实现, 代码里使用的地方很少 -->
<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);
    // 音频比特率(b)
    private static final int maxBitRate = 128000;
    // 音频采样率(hz)
    private static final int maxSamplingRate = 44100;
    // 视频比特率(b)
    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);

    /**
     * 视频压缩
     *
     * @param sourceFile 源文件
     * @param fileType   源文件类型, 例: mp4
     * @return 压缩后文件
     */
    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));
                }
                // 设置重新编码的音频流中使用的声道数(1 =单声道,2 = 双声道(立体声))。如果未设置任何声道值,则编码器将选择默认值 0。
                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);

            // 同时只压缩3个, 防止内存溢出
            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;
    }
}

四、系统环境配置

  1. 进入maven本地仓库,找到 jave-nativebin-win64-3.4.0.jar 并以压缩包方式打开
    在这里插入图片描述
  2. 提取出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
    在这里插入图片描述
  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
您可以使用Java编程语言来在安卓应用中进行视频压缩。以下是一些可能有用的库和示例代码: 1. Android MediaCodec API - 这是一组Android API,可用于编码和解码视频。您可以使用此API对视频进行压缩。以下是一些有用的示例代码: ``` MediaCodec codec = MediaCodec.createEncoderByType("video/avc"); MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height); format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iFrameInterval); codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); codec.start(); ``` 2. FFmpeg - 这是一种流行的开源视频处理库,可用于视频压缩和转码。您可以在安卓应用程序中使用FFmpeg进行视频压缩。以下是一些有用的示例代码: ``` ffmpeg -i input.mp4 -vcodec libx264 -crf 20 output.mp4 ``` 3. AndroidVideoEncoder - 这是一个简单的Java库,可用于在安卓应用程序中进行视频压缩。以下是一些有用的示例代码: ``` AndroidSequenceEncoder encoder = new AndroidSequenceEncoder(outputFile); for (BufferedImage bi : images) { // convert BufferedImage to Bitmap Bitmap bitmap = Bitmap.createBitmap(bi.getWidth(), bi.getHeight(), Bitmap.Config.ARGB_8888); ByteBuffer buffer = ByteBuffer.wrap(bitmap.getNinePatchChunk()); buffer.rewind(); bi.copy().getRaster().getDataElements(0, 0, bi.getWidth(), bi.getHeight(), buffer); // encode Bitmap to video encoder.encodeImage(bitmap); } encoder.finish(); ``` 这些都是可能有用的示例,但是视频压缩是一项复杂的任务,需要深入了解视频编码和解码。如果您不熟悉此主题,建议使用现有的视频压缩库和工具来完成任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

站在亭桥上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值