> 技术文档 > FFmpeg音视频处理解决方案_ffmpeg 处理视频

FFmpeg音视频处理解决方案_ffmpeg 处理视频

核心组件:

ffmpeg:主要的命令行工具,用于转码、转换格式等

ffprobe:用于分析多媒体文件信息的工具

ffplay:简单的媒体播放器

主要功能:

✅ 格式转换(转码)

视频裁剪、合并

✅ 调整分辨率、比特率

✅ 提取音频/视频

✅ 截图/生成缩略图

✅ 添加水印、字幕

✅ 流媒体处理

一、安装FFmpeg

Windows:

  1. 访问 https://ffmpeg.org/download.html
  2. 下载Windows版本,解压到指定目录
  3. 将bin目录添加到系统PATH环境变量

Linux (Ubuntu/Debian):

sudo apt updatesudo apt install ffmpeg

macOS:

brew install ffmpeg

二、项目配置

在application.properties或application.yml中配置FFmpeg路径:

# application.propertiesffmpeg.path=/usr/bin/ffmpeg # Linux/Mac# 或ffmpeg.path=C:\\\\ffmpeg\\\\bin\\\\ffmpeg.exe # Windows

三、依赖注入与异步处理

@Service@Slf4jpublic class VideoTranscodingService { @Value(\"${ffmpeg.path}\") private String ffmpegPath; // 注入FFmpeg路径 @Async // 异步执行,避免阻塞请求 public void transcodeVideo(Long materialId, String inputPath) { // 转码逻辑 }}

核心转码方法

  • ProcessBuilder
  • Process
private void transcodeToResolution(String inputPath, String outputPath, String resolution) throws Exception { List<String> command = new ArrayList<>(); command.add(ffmpegPath); command.add(\"-i\"); command.add(inputPath); // 输入文件 command.add(\"-s\"); command.add(resolution); // 目标分辨率 command.add(\"-c:v\"); command.add(\"libx264\"); // 视频编码器 command.add(\"-crf\"); command.add(\"23\"); // 视频质量 command.add(\"-c:a\"); command.add(\"aac\"); // 音频编码器 command.add(\"-b:a\"); command.add(\"128k\"); // 音频比特率 command.add(outputPath); // 输出文件 ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); int exitCode = process.waitFor(); // 等待转码完成 if (exitCode != 0) { throw new RuntimeException(\"FFmpeg转码失败,退出码: \" + exitCode); }}

四、控制器中上传文件视频

@RestController@RequestMapping(\"/api/video\")public class VideoController { @Autowired private VideoTranscodingService transcodingService; @PostMapping(\"/upload\") public ResponseEntity<String> uploadVideo(@RequestParam(\"file\") MultipartFile file, @RequestParam Long materialId) { try { // 1. 保存上传的文件 String uploadDir = \"uploads/\"; String originalFilename = file.getOriginalFilename(); String filePath = uploadDir + UUID.randomUUID() + \"_\" + originalFilename; File dest = new File(filePath); file.transferTo(dest); // 2. 异步启动转码 transcodingService.transcodeVideo(materialId, filePath); return ResponseEntity.ok(\"视频上传成功,转码中...\");  } catch (Exception e) { return ResponseEntity.status(500).body(\"上传失败: \" + e.getMessage()); } }}
@GetMapping(\"/status/{materialId}\")public ResponseEntity<Map<String, Object>> getTranscodingStatus(@PathVariable Long materialId) { CourseMaterial material = materialRepository.findById(materialId).orElse(null); if (material == null) { return ResponseEntity.notFound().build(); } Map<String, Object> response = new HashMap<>(); response.put(\"status\", material.getTranscodingStatus()); response.put(\"filePath\", material.getFilePath()); response.put(\"duration\", material.getDuration()); return ResponseEntity.ok(response);}