Java使用ffmpeg压缩视频

1、引入maven仓库

<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-core</artifactId>
    <version>3.1.1</version>
</dependency>
<!-- 在windows上开发 开发机可实现压缩效果 window64位 -->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-win64</artifactId>
    <version>3.1.1</version>
</dependency>

<!-- 在linux上部署 linux服务器需要这个才能生效 linux64位 -->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-linux64</artifactId>
    <version>3.1.1</version>
</dependency>

2、代码

我这里使用了一些基本的属性,压缩速度180M压缩后40M,时间两分钟

mport lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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 ws.schild.jave.info.VideoSize;

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

/**
 * @author ganggang
 */
@Component
@Slf4j
public class VideoCompression {
    /**
     * @param source 原文件地址
     * @param target 生成新文件地址
     */
    public static void compressionVideo(File source, File target) {
        if (source == null) {
            return;
        }
        try {
            MultimediaObject multimediaObject=new MultimediaObject(source);
            AudioInfo audioInfo=multimediaObject.getInfo().getAudio();
            /**
             * 根据视频大小来判断是否需要进行压缩,
             */
            int maxSize = 5;
            double mb=Math.ceil(source.length()/1024/1024);
            int second=(int)multimediaObject.getInfo().getDuration();
            BigDecimal bd = new BigDecimal(String.format("%.4f", mb / second));
            log.info("开始压缩视频了--> 视频每秒平均 " + bd + " MB ");
            /**
             * 视频 > 5MB, 或者每秒 > 0.5 MB 才做压缩, 不需要的话可以把判断去掉
             */
            boolean temp = mb > maxSize || bd.compareTo(new BigDecimal(0.5)) > 0;
            if (temp) {
                long begin = System.currentTimeMillis();
                //TODO 视频属性设置
                int maxBitRate = 128000;
                int maxSamplingRate = 44100;
                int bitRate = 180000;
                int maxFrameRate = 15;
                int maxWidth = 1280;
                AudioAttributes audio = new AudioAttributes();
                /**
                 *  它设置将用于音频流转码的编解码器的名称。您必须从当前Encoder实例的getAudioEncoders()方法返回的列表中选择一个值。
                 *  否则,您可以传递AudioAttributes.DIRECT_STREAM_COPY特殊值,这需要源文件中原始音频流的副本。
                 */
                audio.setCodec(AudioAttributes.DIRECT_STREAM_COPY);
                /**
                 *  它为新的重新编码的音频流设置比特率值。如果没有设置比特率值,编码器将选择一个默认值。该值应以每秒位数表示。
                 *  例如,如果您想要 128 kb/s 的比特率,您应该调用setBitRate(new Integer(128000))。
                 */
                if(audioInfo.getBitRate()>maxBitRate){
                    audio.setBitRate(Integer.valueOf(maxBitRate));
                }
                /**
                 * 它为新的重新编码的音频流设置采样率。如果没有设置采样率值,编码器将选择一个默认值。该值应以赫兹表示。
                 * 例如,如果您想要类似 CD 的 44100 Hz 采样率,您应该调用setSamplingRate(new Integer(44100))。
                 */
                if(audioInfo.getSamplingRate()>maxSamplingRate){
                    audio.setSamplingRate(Integer.valueOf(maxSamplingRate));
                }
                /**
                 * 它设置将在重新编码的音频流中使用的音频通道数(1 = 单声道,2 = 立体声,4 = 4声道)。如果未设置通道值,则编码器将选择默认值。
                 */
                audio.setChannels(audioInfo.getChannels());
                /**
                 * 可以调用此方法来更改音频流的音量。值为 256 表示没有音量变化。因此,小于 256 的值是音量减小,而大于 256 的值将增加音频流的音量。
                 */
                audio.setVolume(Integer.valueOf(256));
                VideoInfo videoInfo = multimediaObject.getInfo().getVideo();
                VideoAttributes video = new VideoAttributes();
                /**
                 * 它设置将用于视频流转码的编解码器的名称。您必须从当前Encoder实例的getVideoEncoders()方法返回的列表中选择一个值。
                 * 否则,您可以传递VideoAttributes.DIRECT_STREAM_COPY特殊值,这需要从源文件复制原始视频流。
                 */
                video.setCodec("h264");
                /**
                 * 它设置与重新编码的视频流相关联的标签/fourcc 值。如果未设置任何值,则编码器将选择默认值。多媒体播放器经常使用标签值来选择在流上运行的视频解码器。
                 * 在示例中,带有“DIVX”标签值的 MPEG 4 视频流将使用播放器使用的默认 DivX 解码器进行解码video.setTag();。
                 * 而且,顺便说一下,这正是 DivX 的含义:带有附加“DIVX”标签/fourcc 值的 MPEG 4 视频流!
                 *
                 */
                /**
                 * 它为新的重新编码的视频流设置比特率值。如果没有设置比特率值,编码器将选择一个默认值。该值应以每秒位数表示。
                 * 例如,如果您想要 360 kb/s 的比特率,您应该调用setBitRate(new Integer(360000))。
                 */
                if(videoInfo.getBitRate()>bitRate){
                    video.setBitRate(Integer.valueOf(bitRate));
                }

                /**
                 * 它为新的重新编码的音频流设置帧速率值。如果没有设置比特率帧率,编码器将选择一个默认值。该值应以每秒帧数表示。
                 * 例如,如果您想要 30 f/s 的帧速率,您应该调用setFrameRate(new Integer(30))。
                 */
                if(videoInfo.getFrameRate()>maxFrameRate){
                    video.setFrameRate(Integer.valueOf(maxFrameRate));
                }

                /**
                 * 限制视频宽高
                 * 它设置视频流中图像的大小和比例。如果未设置任何值,编码器将保留原始大小和比例。否则,您可以使用您喜欢的大小传递 it.sauronsoftware.java.VideoSize实例。
                 * 您可以使用像素值设置新编码视频的宽度和高度,缩放原始视频。例如,如果您想将视频缩放到 512 像素的宽度和 384 像素的高度,您应该调用setSize(new VideoSize(512, 384))。
                 */
                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();
                /**
                 * 它为转码操作设置偏移量。源文件将从其开始的偏移秒开始重新编码。例如,如果您想剪切源文件的前五秒,您应该对传递给编码器的EncodingAttributes对象调用setOffset(5)。
                 */
                /**
                 * 它设置转码操作的持续时间。只有源的持续时间秒才会在目标文件中重新编码。例如,如果您想从源中提取和转码 30 秒的一部分,您应该在传递给编码器的EncodingAttributes对象上调用setDuration(30)。
                 */
                /**
                 * 用于解码的线程数(如果编解码器支持)10 100 135s
                 */
                attr.setDecodingThreads(Runtime.getRuntime().availableProcessors()/2);
                /**
                 * 用于编码的线程数(如果编解码器支持)10
                 */
                attr.setEncodingThreads(Runtime.getRuntime().availableProcessors()/2);
                attr.setAudioAttributes(audio);
                attr.setVideoAttributes(video);
                Encoder encoder = new Encoder();
                encoder.encode(new MultimediaObject(source), target, attr);
                long end = System.currentTimeMillis();
                log.info("时间:" + (end - begin)/1000 + "s");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值