首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 調用 FFmpeg/Mencoder 實現視頻轉碼與縮略圖生成

     編輯:Java 相關知識

視頻上傳場景常需「轉統一格式(FLV/MP4)+ 生成封面縮略圖」。本文提供基於 ProcessBuilder 調用 FFmpeg 與 Mencoder 的完整實現,涵蓋參數調優、同步執行控制與常見坑點規避。

架構設計

  • 轉碼引擎:Mencoder(輸出 FLV 容器 + H.263/MP3 編碼)
  • 截圖引擎:FFmpeg(第 8 秒關鍵幀,縮放 100×100)
  • 同步控制:單線程串行執行,轉碼完成後再截圖,避免併發資源爭搶

核心實現代碼

public class VideoProcessor {
    public boolean transcodeAndCapture(String srcPath, String flvPath, String thumbPath) {
        List mencoderCmd = Arrays.asList(
            "D:/tools/mencoder/mencoder.exe", srcPath,
            "-o", flvPath,
            "-of", "lavf",
            "-oac", "mp3lame", "-lameopts", "abr:br=32:vol=1",
            "-srate", "22050",
            "-ovc", "lavc", "-lavcopts", "vcodec=flv:vbitrate=480:mbd=2:v4mv:turbo",
            "-vf", "scale=400:226"
        );

        List ffmpegCmd = Arrays.asList(
            "D:/tools/ffmpeg/ffmpeg.exe", "-i", srcPath,
            "-y", "-f", "image2", "-ss", "8", "-t", "0.001",
            "-s", "100x100", thumbPath
        );

        try {
            execSync(mencoderCmd);
            execSync(ffmpegCmd);
            return true;
        } catch (IOException | InterruptedException e) {
            log.error("Video processing failed", e);
            return false;
        }
    }

    private void execSync(List cmd) throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.redirectErrorStream(true);
        Process p = pb.start();
        // 消費輸出流防止阻塞
        try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
            String line;
            while ((line = br.readLine()) != null) log.debug(line);
        }
        int exit = p.waitFor();
        if (exit != 0) throw new IOException("Command exited with " + exit);
    }
}

關鍵參數解析與調優建議

參數說明調優方向
-vbitrate=480視頻碼率 kbps根據清晰度需求調整,720p 建議 1500-2500
-ss 8截圖時間點(秒)避開片頭黑屏/字幕,可改為總時長 10% 處
-s 100x100縮略圖尺寸保持原視頻長寬比,防止變形;建議加 -aspect 強制比例
-t 0.001截取時長極短時間僅抓單幀,確保輸出單張圖片

常見問題與解決方案

  1. 輸出文件大於原文件:碼率設定過高或容器開銷大,降低 vbitrate 或改用 H.264 (libx264) 提高壓縮效率
  2. 縮略圖不生成:
    • 尺寸參數不被編碼器支援(如 100×75 失敗,100×100 成功),嘗試標準分辨率(320×240、160×120)
    • 關鍵幀間隔過大,-ss 定位非關鍵幀導致黑屏,加 -keyint_min 或改用 -vf select='eq(pict_type,I)'
  3. 中文路徑亂碼:ProcessBuilder 自動處理參數列表無需轉義,但確保系統默認編碼為 UTF-8,或額外設置 pb.environment().put("LANG", "zh_CN.UTF-8")

生產環境強化清單

  • 引入 ffprobe 先探測視頻時長/編碼,動態計算截圖時間點
  • 使用臨時目錄隔離中間文件,完成後原子性移動
  • 超時機制:p.waitFor(30, TimeUnit.MINUTES) 防止掛起
  • 資源限制:Docker cgroups 限制 CPU/記憶體,避免轉碼佔滿宿主機

完整可運行 Demo 見文末附件,已在 Windows/Linux 雙平台驗證通過。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved