Bootstrap

使用ffmpeg实现音视频文件格式转换

当前支持,后续继续补充

  •   1、支持音频文件转mp3;
  •    2、支持视频文件转mp4;
  •    3、支持视频提取音频;

1、转换类


import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/***
 *
 * @author xuancg
 * 要求系统内置ffmpeg工具环境
 * @date 2024/9/23
 */
@Slf4j
public class FfmpegUtil {

    private static final String CONVERT_MP3 = "ffmpeg -i %s %s";

    private static final String CONVERT_MP4 = "ffmpeg -i %s -c:v libx264 -c:a copy %s";

    private static final String EXTRACT_MP3 = "ffmpeg -i %s -q:a 0 -map a %s";

    private static final Set<String> MP3_TYPE = new HashSet<>(Arrays.asList("mp3", "wav", "aac", "flac"));

    private static final Set<String> MP4_TYPE = new HashSet<>(Arrays.asList("mp4", "avi", "flv", "mpeg", "wmv"));


    /***
     * 音视频文件格式化
     * 1、支持音频文件转mp3;
     * 2、支持视频文件转mp4;
     * 3、支持视频提取音频;
     */
    public static boolean convertMedia(MediaConvertBo convertBo) {
        File src = convertBo.getSrc();
        File dest = convertBo.getDest();
        if (null == src || !src.isFile()) {
            log.error("原始文件不存在");
            return false;
        }
        if (null != dest && dest.isFile()) {
            log.info("目标文件已存在");
        }
        long start = System.currentTimeMillis();
        Process process = null;
        BufferedReader reader = null;
        try {
            String cmd = createCmd(convertBo);
            if(null == cmd){
                return false;
            }
            log.info("ffmpeg执行命令=" + cmd);
            // 执行命令
            process = Runtime.getRuntime().exec(cmd);
            // 获取命令输出结果
            reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                log.debug(line);
            }
            // 明确自己的命令需要执行多长时间,否则可以一直等待
            int timeout = convertBo.getTimeout();
            if (timeout <= 0) {
                process.waitFor();
            } else {
                process.waitFor(timeout, TimeUnit.SECONDS);
            }
            return dest.isFile() && dest.length() > 10;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            log.error("剪裁视频超时source=" + src.getAbsolutePath());
        } finally {
            if (null != process) {
                process.destroy();
            }
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error("关闭流失败" + e.getMessage());
                }
            }
            log.info("耗时ms=" + (System.currentTimeMillis() - start));
        }
        return false;

    }

    public static boolean isMp4File(File file){
        String name = file.getName();
        String suffix = name.substring(name.lastIndexOf(".") + 1);
        return MP4_TYPE.contains(suffix);
    }

    public static boolean isMp3File(File file){
        String name = file.getName();
        String suffix = name.substring(name.lastIndexOf(".") + 1);
        return MP3_TYPE.contains(suffix);
    }


    private static final String createCmd(MediaConvertBo bo) {
        File src = bo.getSrc();
        if (bo.isConvertMp3()) {
            if(!isMp3File(src)){
                log.error("错误的mp3格式");
                return null;
            }
            return String.format(CONVERT_MP3, src.getAbsolutePath().replace("\\", "/"), bo.getDest().getAbsolutePath().replace("\\", "/"));
        } else if (bo.isConvertMp4()) {
            if(!isMp4File(src)){
                log.error("错误的mp4格式");
                return null;
            }
            return String.format(CONVERT_MP4, src.getAbsolutePath().replace("\\", "/"), bo.getDest().getAbsolutePath().replace("\\", "/"));
        } else if(bo.getType() == MediaConvertBo.Type.EXTRACT_MP3){
            if(!isMp4File(src)){
                log.error("错误的mp4格式");
                return null;
            }
            return String.format(EXTRACT_MP3, src.getAbsolutePath().replace("\\", "/"), bo.getDest().getAbsolutePath().replace("\\", "/"));
        }

        log.error("错误的type");
        return null;
    }

}

2、请求对象



import lombok.Data;

import java.io.File;

/***
 *
 * @author xuancg
 * @date 2024/9/23
 */
@Data
public class MediaConvertBo {


    private File src;
    private File dest;

    /**0表示持续等待,单位秒*/
    private int timeout = 0;

    private Type type;


    public boolean isConvertMp3(){
        return null != type && type == Type.CONVERT_MP3;
    }

    public boolean isConvertMp4(){
        return null != type && type == Type.CONVERT_MP4;
    }

    public enum Type {
        /***/
        CONVERT_MP4,
        CONVERT_MP3,
        EXTRACT_MP3
        ;
    }


}

3、ffmpeg配置环境变量

在Windows上安装并配置FFmpeg的环境变量,请按照以下步骤操作:

1)下载FFmpeg:

访问FFmpeg官网(https://ffmpeg.org/download.html)下载对应于你的操作系统的FFmpeg静态构建。

2)解压缩:

将下载的压缩包解压到你选择的目录,例如:C:\ffmpeg\。

3)配置环境变量:

  • 右键点击“我的电脑”或者“此电脑”,选择“属性”。
  • 点击“高级系统设置”。
  • 在“系统属性”窗口中选择“环境变量”。
  • 在“系统变量”区域找到并选择“Path”变量,点击“编辑”。
  • 点击“新建”,添加FFmpeg的bin目录到路径中,例如:C:\ffmpeg\bin。
  • 点击“确定”保存所有设置。

5)验证安装:

打开命令提示符(CMD)或者PowerShell,输入以下命令来检查FFmpeg是否正确安装和配置:

ffmpeg -version

;