package com.multictrl.common.utils; import lombok.extern.slf4j.Slf4j; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; /** * 图像、音频处理 * * @author Sdy * @since 1.0.0 2026/4/29 */ @Slf4j public class FfmpegUtils { //视频预览图片帧抽取 private static final String FFMPEG_VIDEO_COVER_IMAGE_COMMAND = "ffmpeg -i %s -vf \"select=eq(pict_type\\,I)\" -frames:v 1 -pix_fmt yuvj422p -vsync vfr -qscale:v 2 -f image2 %s -y"; /** * 生成视频封面图片 */ public static void generateVideoCover(String videoPath, String videoCoverPath) { File file = new File(videoPath); if (file.exists()) { File imageFile = new File(videoCoverPath); if (!imageFile.exists()) { String command = String.format(FFMPEG_VIDEO_COVER_IMAGE_COMMAND, videoPath, videoCoverPath); String[] cmd = {"/bin/sh", "-c", command}; try { ProcessBuilder processBuilder = new ProcessBuilder(); processBuilder.command(cmd).inheritIO(); processBuilder.environment().clear(); processBuilder.environment().put("LANG", "en_US.UTF-8"); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); InputStream inputStream = process.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream, "GBK"); char[] chars = new char[1024]; int len; while ((len = reader.read(chars)) != -1) { String string = new String(chars, 0, len); log.debug("ffmpeg->video->cover : {}", string); } reader.close(); inputStream.close(); } catch (Exception e) { log.error("ffmpeg->video->cover: error", e); } log.debug("mp4 file = {} ,image file={} ,执行ffmpeg命令={} , imageFile_exists_flag={}", file.getAbsolutePath(), imageFile.getAbsolutePath(), command, imageFile.exists()); } } } /** * 指令运行 */ public static void runCommand(String command) { String[] cmd = {"/bin/sh", "-c", command}; try { ProcessBuilder processBuilder = new ProcessBuilder(); processBuilder.command(cmd).inheritIO(); processBuilder.environment().clear(); processBuilder.environment().put("LANG", "en_US.UTF-8"); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); InputStream inputStream = process.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream, "GBK"); char[] chars = new char[1024]; int len; while ((len = reader.read(chars)) != -1) { String string = new String(chars, 0, len); log.info("ffmpeg->shout->file->cover : {}", string); } reader.close(); inputStream.close(); } catch (Exception e) { log.error("ffmpeg->shout->file->cover: error", e); } } }