JAVA-ffmpeg音视频工具类

日常工作中,如果涉及到音视频处理,免不了使用ffmpeg工具,对音视频文件进行解析。

结合日常工作,把一套可应用于生产的JAVA工具,整理于此。

maven引用

        <!--ffmpeg-->
        <dependency>
            <groupId>net.bramp.ffmpeg</groupId>
            <artifactId>ffmpeg</artifactId>
            <version>0.8.0</version>
        </dependency>

java工具类

public class MediaInfoUtil {
    protected static final Logger LOGGER = LoggerFactory.getLogger(MediaInfoUtil.class);

    private static final FFprobe ffprobe;
    static {
        try {
            ffprobe = new FFprobe();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 获取视频的相关信息
     * url请替换成完整的内网域名
     * @param path 本地路径 或者 url
     * @return VideoInfoVO
     * @throws IOException
     */
    public static MediaInfoVO getVideoParam(String path) throws IOException {
        MediaInfoVO mediaInfoVO = new MediaInfoVO();
        VideoInfoVO videoVO = new VideoInfoVO();
        AudioInfoVO audioVO = new AudioInfoVO();


        FFmpegProbeResult probeResult = ffprobe.probe(path);
        FFmpegFormat format = probeResult.getFormat();
        List<FFmpegStream> streams = probeResult.getStreams();

        // 音频 视频 都没有
        if (CollectionUtils.isEmpty(streams)){
            LOGGER.error("视频文件解析失败,该文件音频和视频数据不完整,请上传合规视频文件!");
            throw new IOException("视频文件解析失败,该文件音频和视频数据不完整,请上传合规视频文件");
        }

        // 音频 视频 只有其中一个
        if (streams.size()==1) {
            FFmpegStream fFmpegStream = streams.get(0);
            if (fFmpegStream.codec_type == FFmpegStream.CodecType.VIDEO) {
                buildVideo(path, mediaInfoVO, videoVO, format, fFmpegStream);
                LOGGER.info("getVideoParam path is {} mediaInfoVO is {}", path, JSON.toJSONString(mediaInfoVO));
                return mediaInfoVO;
            }

            LOGGER.info("getVideoParam 只有一个音频流,文件错误 path is {}", path);
            return null;
        }

        // 视频信息 0可能为音频信息
        FFmpegStream videoStream = streams.get(0);
        // 音频信息 1可能为视频信息
        FFmpegStream audioStream = streams.get(1);

        // 视频信息
        if (videoStream.codec_type == FFmpegStream.CodecType.VIDEO) {
            buildVideo(path, mediaInfoVO, videoVO, format, videoStream);
        }
        if (audioStream.codec_type == FFmpegStream.CodecType.VIDEO) {
            buildVideo(path, mediaInfoVO, videoVO, format, audioStream);
        }

        //音频信息
        if (audioStream.codec_type == FFmpegStream.CodecType.AUDIO) {
            buildAudio(mediaInfoVO, audioVO, audioStream);
        }
        if (videoStream.codec_type == FFmpegStream.CodecType.AUDIO) {
            buildAudio(mediaInfoVO, audioVO, videoStream);
        }

        LOGGER.info("getVideoParam path is {} mediaInfoVO is {}", path, JSON.toJSONString(mediaInfoVO));
        return mediaInfoVO;
    }

    private static void buildAudio(MediaInfoVO mediaInfoVO, AudioInfoVO audioVO, FFmpegStream audioStream) {
        audioVO.setChannels(audioStream.channels);
        audioVO.setCodecName(audioStream.codec_name);
        audioVO.setSampleRate(audioStream.sample_rate);
        mediaInfoVO.setAudioInfoVO(audioVO);
    }

    private static void buildVideo(String path, MediaInfoVO mediaInfoVO, VideoInfoVO videoVO, FFmpegFormat format,
        FFmpegStream videoStream) {
        getVideoInfo(path, videoVO, format, videoStream);
        mediaInfoVO.setVideoInfoVO(videoVO);
    }

    /**
     * url请替换成完整的内网域名
     * @param path 本地路径 或者 url
     * @return
     * @throws IOException
     */
    public static AudioInfoVO getAudioParam(String path) throws IOException {
        AudioInfoVO audioVO = new AudioInfoVO();

        FFprobe ffprobe = new FFprobe();
        FFmpegProbeResult probeResult = ffprobe.probe(path);
        FFmpegFormat format = probeResult.getFormat();
        //
        FFmpegStream audioStream = probeResult.getStreams().get(0);

        // 音频信息
        if (audioStream.codec_type != FFmpegStream.CodecType.AUDIO) {
            return null;
        }

        audioVO.setDuration(format.duration);
        audioVO.setSize(format.size);
        audioVO.setFormat(format.format_name);
        audioVO.setChannels(audioStream.channels);
        audioVO.setCodecName(audioStream.codec_name);
        audioVO.setSampleRate(audioStream.sample_rate);

        return audioVO;
    }

    /**
     * url请替换成完整的内网域名
     * @param path 本地路径 或者 url
     * @return
     * @throws IOException
     */
    public static PictureInfoVO getPictureParam(String path) throws IOException {
        PictureInfoVO pictureInfoVO = new PictureInfoVO();

        FFprobe ffprobe = new FFprobe();
        FFmpegProbeResult probeResult = ffprobe.probe(path);
        FFmpegFormat format = probeResult.getFormat();
        //
        FFmpegStream pictureStream = probeResult.getStreams().get(0);

        // 图片信息
        if (pictureStream.codec_type != FFmpegStream.CodecType.VIDEO) {
            return null;
        }

        pictureInfoVO.setSize(format.size);
        pictureInfoVO.setFormat(FilenameUtils.getExtension(path).split("\\?")[0]);

        int width = pictureStream.width;
        int height = pictureStream.height;
        //分辨率
        pictureInfoVO.setResolutions(new int[]{width, height});
        pictureInfoVO.setCodecName(pictureStream.codec_name);

        return pictureInfoVO;
    }

    private static void getVideoInfo(String url, VideoInfoVO videoVO, FFmpegFormat format, FFmpegStream videoStream) {
        //文件大小
        videoVO.setSize(format.size);
        //时长
        videoVO.setDuration(format.duration);
        //扩展名
        videoVO.setFormat(FilenameUtils.getExtension(url).split("\\?")[0]);

        int width = videoStream.width;
        int height = videoStream.height;
        //分辨率
        videoVO.setResolutions(new int[]{width, height});
        //pix格式
        videoVO.setPixFmt(videoStream.pix_fmt);
        //编码格式
        videoVO.setCodecName(videoStream.codec_name);
        //码率
        videoVO.setBitRate(videoStream.bit_rate);
        //帧数
        videoVO.setFrames(videoStream.nb_frames);
        //帧率
        Fraction rFrameRate = videoStream.r_frame_rate;
        String frameRateStr = rFrameRate.toString();
        if (StringUtils.isEmpty(frameRateStr)) {
            videoVO.setFrameRate(0);
        }
        String[] split = frameRateStr.split("/");
        float fps = Float.valueOf(split[0]) / Float.valueOf(split[1]);
        videoVO.setFrameRate(Math.round(fps));
    }

}

相关JAVABean

/**
 * 音视频的信息
 */
@Data
public class MediaInfoVO {
    /**
     * 文件名称
     */
    private String fileName;
    /**
     * 文件url
     */
    private String url;
    /**
     * 文件id
     */
    private String id;

    /** 视频信息 */
    private VideoInfoVO videoInfoVO;
    /** 音频信息 */
    private AudioInfoVO audioInfoVO;
}

/**
 * 视频的信息
 */
@Data
public class VideoInfoVO {
    /**
     * 文件名称
     */
    private String fileName;
    /**
     * 文件url
     */
    private String url;
    /**
     * 文件id
     */
    private String id;

    /** 视频格式*/
    private String format;
    /** 视频大小*/
    private Long size;
    /** 视频时长*/
    private Double duration;
    /** 视频分别率 */
    private int[] resolutions;
    /**视频总帧数*/
    private Long frames;
    /**视频帧率*/
    private Integer frameRate;

    private String pixFmt;
    private String codecName;
    private Long bitRate;
}

/**
 * 视频的信息
 */
@Data
public class AudioInfoVO {
    /**
     * 文件名称
     */
    private String fileName;
    /**
     * 文件url
     */
    private String url;
    /**
     * 文件id
     */
    private String id;

    /** 音频格式*/
    private String format;
    /** 音频大小*/
    private Long size;
    /** 音频时长*/
    private Double duration;
    /** 声道数 */
    private Integer channels;
    /** 音频编码格式 */
    private String codecName;
    /** 采样率 */
    private Integer sampleRate;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值