MediaHelperExtend.java 11.8 KB
package com.yanzuoguang.util;

import com.yanzuoguang.util.log.Log;
import it.sauronsoftware.jave.*;

import java.io.File;

/**
 * 视频帮助类
 * <p>
 * 59s视频,抖音上拍摄59s,下载后是27.79mb。先从手机上拍摄59s,原视频是111mb,上传抖音后下载的视频是47.32mb
 *
 * @author 颜佐光
 */
public class MediaHelperExtend extends ImageHelper {

    public static final int FIRST_FRAME = 5;
    public static final int DEFAULT_BIT_RATE = 372 * 1000;

    public static final String FORMAT_EMPTY = "";
    public static final String FORMAT_FLV = "flv";
    public static final String FORMAT_MPEG = "mp4";
    public static final String FORMAT_MPEG_CODEC = "mpeg4";
    //    public static final String FORMAT_MPEG_CODEC = "mpeg";
    public static final String FORMAT_3PG = "3gp";
    public static final String FORMAT_3PG_CODEC = "mpeg4";

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @throws EncoderException
     */
    public static void zipVideo(String fromFile, String toFile) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_EMPTY, FORMAT_EMPTY, DEFAULT_SIZE, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @throws EncoderException
     */
    public static void zipVideo(String fromFile, String toFile, float size) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_EMPTY, FORMAT_EMPTY, size, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @param bitRate  它为新的重新编码的视频流设置比特率值。如果未设置比特率值,编码器将选择默认值。
     *                 该值应以位/秒表示。在这个例子中,如果你想要一个360kb/s的比特率,你应该调用setBitRate(新整数(360000))。
     * @throws EncoderException
     */
    public static void zipVideo(String fromFile, String toFile, float size, int bitRate) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_EMPTY, FORMAT_EMPTY, size, bitRate);
    }


    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @throws EncoderException
     */
    public static void zipVideo3pg(String fromFile, String toFile) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_3PG, FORMAT_3PG_CODEC, DEFAULT_SIZE, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @throws EncoderException
     */
    public static void zipVideo3pg(String fromFile, String toFile, float size) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_3PG, FORMAT_3PG_CODEC, size, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @param bitRate  它为新的重新编码的视频流设置比特率值。如果未设置比特率值,编码器将选择默认值。
     *                 该值应以位/秒表示。在这个例子中,如果你想要一个360kb/s的比特率,你应该调用setBitRate(新整数(360000))
     * @throws EncoderException
     */
    public static void zipVideo3pg(String fromFile, String toFile, float size, int bitRate) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_3PG, FORMAT_3PG_CODEC, size, bitRate);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @throws EncoderException
     */
    public static void zipVideoMpeg(String fromFile, String toFile) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_MPEG, FORMAT_MPEG_CODEC, DEFAULT_SIZE, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @throws EncoderException
     */
    public static void zipVideoMpeg(String fromFile, String toFile, float size) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_MPEG, FORMAT_MPEG_CODEC, size, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @param bitRate  它为新的重新编码的视频流设置比特率值。如果未设置比特率值,编码器将选择默认值。
     *                 该值应以位/秒表示。在这个例子中,如果你想要一个360kb/s的比特率,你应该调用setBitRate(新整数(360000))。
     * @throws EncoderException
     */
    public static void zipVideoMpeg(String fromFile, String toFile, float size, int bitRate) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_MPEG, FORMAT_MPEG_CODEC, size, bitRate);
    }


    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @throws EncoderException
     */
    public static void zipVideoFlv(String fromFile, String toFile) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_FLV, FORMAT_FLV, DEFAULT_SIZE, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @throws EncoderException
     */
    public static void zipVideoFlv(String fromFile, String toFile, float size) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_FLV, FORMAT_FLV, size, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param size     宽度和高度是否压缩
     * @param bitRate  它为新的重新编码的视频流设置比特率值。如果未设置比特率值,编码器将选择默认值。
     *                 该值应以位/秒表示。在这个例子中,如果你想要一个360kb/s的比特率,你应该调用setBitRate(新整数(360000))。
     * @throws EncoderException
     */
    public static void zipVideoFlv(String fromFile, String toFile, float size, int bitRate) throws EncoderException {
        zipVideo(fromFile, toFile, FORMAT_FLV, FORMAT_FLV, size, bitRate);
    }


    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param format   要支持的格式
     * @param codeC    视频的格式
     * @throws EncoderException
     */
    public static void zipVideo(String fromFile, String toFile,
                                String format, String codeC) throws EncoderException {
        zipVideo(fromFile, toFile, format, codeC, DEFAULT_SIZE, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param format   要支持的格式
     * @param codeC    视频的格式
     * @param size     宽度和高度是否压缩
     * @throws EncoderException
     */
    public static void zipVideo(String fromFile, String toFile,
                                String format, String codeC, float size) throws EncoderException {
        zipVideo(fromFile, toFile, format, codeC, size, DEFAULT_BIT_RATE);
    }

    /**
     * 从视频文件中获取第一张图片
     *
     * @param fromFile 视频文件
     * @param toFile   第一帧图片
     * @param format   要支持的格式
     * @param codeC    视频的格式
     * @param size     宽度和高度是否压缩
     * @param bitRate  它为新的重新编码的视频流设置比特率值。如果未设置比特率值,编码器将选择默认值。
     *                 该值应以位/秒表示。在这个例子中,如果你想要一个360kb/s的比特率,你应该调用setBitRate(新整数(360000))。
     * @throws EncoderException
     */
    public static void zipVideo(String fromFile, String toFile,
                                String format, String codeC,
                                float size, int bitRate) throws EncoderException {
        if (size > 1) {
            throw YzgError.getRuntimeException("038");
        }
        File source = new File(fromFile);
        File target = new File(toFile);
        if (!target.getParentFile().exists()) {
            target.getParentFile().mkdirs();
        }
        // 编码方式
        Encoder encoder = new Encoder();

        MultimediaInfo fromInfo = encoder.getInfo(source);
        VideoInfo fromVideo = fromInfo.getVideo();
        AudioInfo fromAudio = fromInfo.getAudio();
        if (fromAudio == null) {
            fromAudio = new AudioInfo();
        }
        if (fromVideo == null) {
            fromVideo = new VideoInfo();
        }
        if (FORMAT_EMPTY.equals(format) || format == null) {
            format = fromInfo.getFormat();
        }
        if (FORMAT_EMPTY.equals(codeC) || codeC == null) {
            codeC = fromVideo.getDecoder();
        }


        // 音频编码设置
        int toBitRate = fromAudio.getBitRate();
        if (toBitRate == -1) {
            toBitRate = 64000;
        }
        int toChannels = fromAudio.getChannels();
        int toSamplingRate = Math.min(22050, fromAudio.getSamplingRate());

        AudioAttributes audio = new AudioAttributes();
        audio.setCodec("libmp3lame");
        audio.setBitRate(toBitRate);
        audio.setChannels(toChannels);
        audio.setSamplingRate(toSamplingRate);

        // 视频编码设置
        VideoAttributes video = new VideoAttributes();
        // video.setCodec(VideoAttributes.DIRECT_STREAM_COPY);
        video.setCodec(codeC);
        // video.setTag("DIVX");
        int toFrameRate = 15;
        video.setFrameRate(toFrameRate);
        // 压缩比特率
        video.setBitRate(bitRate);

        // 压缩宽高
        VideoSize fromSize = fromVideo.getSize();
        int toWidth = (int) (fromSize.getWidth() * size);
        int toHeight = (int) (fromSize.getHeight() * size);
        VideoSize toSize = new VideoSize(toWidth, toHeight);
        video.setSize(toSize);

        Log.info(MediaHelperExtend.class, "%s-%s " +
                        "原音频:bitRate=%d,channels=%d,samplingRate=%d " +
                        "新音频:bitRate=%d,channels=%d,samplingRate=%d \n" +
                        "原视频:width=%d,height=%d,bitRate=%d,frameRate=%d " +
                        "新视频:width=%d,height=%d,bitRate=%d,frameRate=%d ",
                format, codeC,
                fromAudio.getBitRate(), fromAudio.getChannels(), fromAudio.getSamplingRate(),
                toBitRate, toChannels, toSamplingRate,
                fromSize.getWidth(), fromSize.getHeight(), fromVideo.getBitRate(), toFrameRate,
                toSize.getWidth(), toSize.getHeight(), bitRate, toFrameRate
        );

        // 视频转码编码设置
        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setFormat(format);
        attrs.setAudioAttributes(audio);
        attrs.setVideoAttributes(video);

        // 编码器
        encoder.encode(source, target, attrs);

        System.out.println("压缩完成...");
    }
}