ffmepg工具的使用

FFMPEG是特别强大的专门用于处理音视频的开源库。你既可以使用它的API对音视频进行处理,也可以使用它提供的工具,如ffmpeg, ffplay, ffprobe,来编辑你的音视频文件。

本文主要使用ffmepg进行图像的压缩,以及视频的抽帧。

抽帧:

cmd = "ffmpeg -i %s -y -vframes 1 -vf scale=%d:%d/a %s";
  • ffmpeg: 这是调用 FFmpeg 程序的命令。

  • -i %s: 输入文件的路径,%s 是一个占位符,通常表示视频文件路径。

  • -y: 自动覆盖输出文件(如果已存在),避免手动确认。

  • -vframes 1: 指定提取1帧图片,1 表示只提取一帧。

  • -vf scale=%d:%d/a:

    • -vf 是 FFmpeg 的视频过滤器选项,这里用于缩放图像。

    • scale=%d:%d/a 是缩放过滤器,%d 表示目标宽度和高度,/a 用来保持输入视频的宽高比。意思是,宽度指定为 %d,而高度按比例缩放,使得图像不变形。

  • %s: 输出文件路径的占位符,用来指定生成的图片文件路径。

服务层:

ScaleFilter.createCover4Video(new File(targetFilePath), Constants.LENGTH_150, new File(coverPath));

调用createCover4Video方法

public static void createCover4Video(File sourceFile, Integer width, File targetFile) {
    try {
        //抽取视频中的第一帧
        String cmd = "ffmpeg -i %s -y -vframes 1 -vf scale=%d:%d/a %s";
        ProcessUtils.executeCommand(String.format(cmd, sourceFile.getAbsoluteFile(), width, width, targetFile.getAbsoluteFile()), false);
    } catch (Exception e) {
        logger.error("生成视频封面失败", e);
    }
}

创建线程

public static String executeCommand(String cmd, Boolean outprintLog) throws BusinessException {
    if (StringTools.isEmpty(cmd)) {
        logger.error("--- 指令执行失败,因为要执行的FFmpeg指令为空! ---");
        return null;
    }

    Runtime runtime = Runtime.getRuntime();
    Process process = null;
    try {
        process = Runtime.getRuntime().exec(cmd);
        // 执行ffmpeg指令
        // 取出输出流和错误流的信息
        // 注意:必须要取出ffmpeg在执行命令过程中产生的输出信息,如果不取的话当输出流信息填满jvm存储输出留信息的缓冲区时,线程就回阻塞住
        PrintStream errorStream = new PrintStream(process.getErrorStream());
        PrintStream inputStream = new PrintStream(process.getInputStream());
        //启动读取输出流和错误流的线程
        errorStream.start();
        inputStream.start();
        // 等待ffmpeg命令执行完
        process.waitFor();
        // 获取执行结果字符串
        String result = errorStream.stringBuffer.append(inputStream.stringBuffer + "\n").toString();
        // 输出执行的命令信息

        if (outprintLog) {
            logger.info("执行命令:{},已执行完毕,执行结果:{}", cmd, result);
        } else {
            logger.info("执行命令:{},已执行完毕", cmd);
        }
        return result;
    } catch (Exception e) {
        // logger.error("执行命令失败:{} ", e.getMessage());
        e.printStackTrace();
        throw new BusinessException("视频转换失败");
    } finally {
        if (null != process) {
            ProcessKiller ffmpegKiller = new ProcessKiller(process);
            runtime.addShutdownHook(ffmpegKiller);
        }
    }
}

图像压缩:

cmd = "ffmpeg -i %s -vf scale=%d:-1 %s -y";
  • ffmpeg: 调用 FFmpeg 程序进行视频处理。

  • -i %s: 输入文件路径,%s 是一个占位符,表示视频文件的路径。

  • -vf scale=%d:-1:

    • -vf 表示应用视频过滤器(video filter)。

    • scale=%d:-1 表示对视频进行缩放:

      • %d 是目标宽度的占位符,用实际数值替换。

      • -1 表示高度按比例自动计算,以保持原视频的宽高比不变。

  • %s: 输出文件路径的占位符,用实际的文件路径替换。

  • -y: 自动覆盖已有的输出文件(如果存在),避免提示确认。

public static void compressImage(File sourceFile, Integer width, File targetFile, Boolean delSource) {
    try {
        String cmd = "ffmpeg -i %s -vf scale=%d:-1 %s -y";
        ProcessUtils.executeCommand(String.format(cmd, sourceFile.getAbsoluteFile(), width, targetFile.getAbsoluteFile()), false);
        if (delSource) {
            FileUtils.forceDelete(sourceFile);
        }
    } catch (Exception e) {
        logger.error("压缩图片失败");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值