docker安装FFmpeg
官网地址:https://ffmpeg.org
x86镜像
docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg:latest
arrch64镜像
docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/linux_arm64_ffmpeg:latest
运行命令
docker run -d \--name ffmpeg-worker \--restart=unless-stopped \ # 容器崩溃时自动重启(除非手动停止)--cpus 2 \ # 限制 CPU 使用(避免耗尽资源)--memory 2g \ # 限制内存使用(根据需求调整)--network host \ # 高性能网络模式(适合流媒体处理)-v /data/ffmpeg/input:/input \ # 输入文件目录-v /data/ffmpeg/output:/output \ # 输出文件目录-v /data/ffmpeg/logs:/var/log/ffmpeg \ # 日志持久化-e TZ=Asia/Shanghai \ # 设置时区(可选)registry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg \ #镜像-i /input/video.mp4 \ # 输入文件-c:v libx264 -preset fast -crf 23 \ # 视频编码参数(平衡质量与速度)-c:a aac -b:a 128k \ # 音频编码参数-y \ # 自动覆盖输出文件/output/video_processed.mp4
(1) 资源隔离
为每个 FFmpeg 任务分配独立的容器,避免相互影响。
使用 --cpus 和 --memory 限制资源。
(2) 日志管理
将日志输出到文件并持久化:
ffmpeg -i input.mp4 ... > /var/log/ffmpeg/process.log 2>&1
或者使用 Docker 日志驱动:
--log-driver=json-file --log-opt max-size=10m --log-opt max-file=3
(3) 错误处理
检查 FFmpeg 退出状态码:
if docker inspect ffmpeg-worker --format='{{.State.ExitCode}}' | grep -q 0; thenecho "Processing succeeded"
elseecho "Processing failed"
fi
批量处理脚本
#!/bin/bash
INPUT_DIR="/data/ffmpeg/input"
OUTPUT_DIR="/data/ffmpeg/output"
LOGS_DIR="/data/ffmpeg/logs"for file in $INPUT_DIR/*.mp4; dofilename=$(basename "$file")docker run --rm \-v $INPUT_DIR:/input \-v $OUTPUT_DIR:/output \-v $LOGS_DIR:/logs \registry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg \-i "/input/$filename" \-c:v libx264 -preset fast -crf 23 \-c:a aac -b:a 128k \-y "/output/${filename%.*}_processed.mp4" \> "/logs/${filename%.*}.log" 2>&1
done
高级场景
直播推流
docker run -d \--name ffmpeg-streamer \--network host \registry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg \-re -i input.mp4 \-c:v libx264 -preset ultrafast -tune zerolatency \-c:a aac -f flv "rtmp://live.twitch.tv/app/STREAM_KEY"
GPU 加速(如果宿主机有 NVIDIA GPU)
docker run -d \--gpus all \jregistry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg \-hwaccel cuda -i input.mp4 -c:v h264_nvenc output.mp4
监控与维护
查看容器资源使用情况:
docker stats ffmpeg-worker
查看日志:
docker logs -f ffmpeg-worker
清理完成的容器:
docker ps -a | grep "Exited" | awk '{print $1}' | xargs docker rm
Java 接口调用 FFmpeg 进行 推流 或 视频处理,并让 Docker 化的 FFmpeg 作为一个服务运行
1、FFmpeg 作为后台服务(Docker 容器运行)
2、Java 通过 REST API 或 gRPC 调用 FFmpeg
3、支持推流(RTMP)、视频处理(转码、剪辑等)
4、支持视频通话(WebRTC + FFmpeg 转码)
部署 FFmpeg 服务(Docker)
1.1 直接运行 FFmpeg 容器(临时任务)
docker run -d \--name ffmpeg-service \-p 8066:8066 \ # 自定义端口,用于 Java 调用-v /data/ffmpeg:/data \ # 持久化存储jregistry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg \bash -c "while true; do sleep 1000; done" # 保持容器运行
用途:Java 可以 docker exec 调用 FFmpeg 执行命令。
1.2 使用 FFmpeg + 轻量级 HTTP 服务(推荐🔥)
由于 FFmpeg 本身没有 HTTP 接口,我们可以用 Python + Flask 包装 FFmpeg,提供 REST API:
Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg
# 安装 Python 和 Flask
RUN apt-get update && apt-get install -y python3 python3-pip && \pip3 install flask requests
# 添加 API 代码
COPY app.py /app/
WORKDIR /app
EXPOSE 8066
CMD ["python3", "app.py"]
app.py(Python FFmpeg API)
from flask import Flask, request, jsonify
import subprocess
import osapp = Flask(__name__)@app.route("/ffmpeg/convert", methods=["POST"])
def convert_video():data = request.jsoninput_file = data["input"]output_file = data["output"]cmd = f"ffmpeg -i {input_file} -c:v libx264 -c:a aac {output_file}"subprocess.run(cmd, shell=True, check=True)return jsonify({"status": "success", "output": output_file})@app.route("/ffmpeg/stream", methods=["POST"])
def start_stream():data = request.jsoninput_file = data["input"]rtmp_url = data["rtmp_url"]cmd = f"ffmpeg -re -i {input_file} -c:v libx264 -preset fast -f flv {rtmp_url}"subprocess.Popen(cmd, shell=True) # 后台运行return jsonify({"status": "streaming", "rtmp": rtmp_url})if __name__ == "__main__":app.run(host="0.0.0.0", port=8066)
构建并运行
docker build -t ffmpeg-api .
docker run -d -p 8066:8066 -v /data/ffmpeg:/data --name ffmpeg-api ffmpeg-api
- Java 调用 FFmpeg 服务
2.1 通过 HTTP API 调用
Java 代码示例(使用 HttpClient):
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;public class FFmpegClient {public static void main(String[] args) throws Exception {// 调用 FFmpeg 转换接口String jsonInput = "{\"input\":\"/data/input.mp4\", \"output\":\"/data/output.mp4\"}";HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8066/ffmpeg/convert")).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(jsonInput)).build();HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());}
}
2.2 直接调用 Docker 命令(不推荐)
ProcessBuilder pb = new ProcessBuilder("docker", "exec", "ffmpeg-service","ffmpeg", "-i", "/data/input.mp4", "/data/output.mp4"
);
Process p = pb.start();
p.waitFor(); // 等待 FFmpeg 完成
- 视频通话方案(WebRTC + FFmpeg)
如果要做 视频通话,推荐架构:
前端:使用 WebRTC(如 PeerJS 或 mediasoup)
后端:Java 处理信令(Socket/WebSocket)
FFmpeg:用于转码、录制、推流
3.1 Docker 运行 FFmpeg + WebRTC 转码
docker run -d \--name webrtc-ffmpeg \--network host \ # 低延迟-v /data/webrtc:/data \registry.cn-hangzhou.aliyuncs.com/qiluo-images/ffmpeg \ffmpeg \-f webm -i udp://0.0.0.0:5000 \ # 接收 WebRTC 数据-c:v libx264 -preset ultrafast \ # 转码-f rtp rtp://1.2.3.4:6000 # 发送到 RTP 服务器
3.2 Java 信令服务器(Spring Boot + WebSocket)
@RestController
public class WebRTCController {@PostMapping("/start-stream")public String startStream(@RequestBody StreamRequest request) {// 调用 FFmpeg Docker 容器String cmd = String.format("ffmpeg -i %s -c:v libx264 -f flv %s",request.getInput(), request.getRtmpUrl());// 执行 Docker 命令Runtime.getRuntime().exec(new String[]{"docker", "exec", "ffmpeg-service", "bash", "-c", cmd});return "Stream started!";}
}
场景 方案
Java 调用 FFmpeg HTTP API(Python Flask + Docker)
视频推流(RTMP) ffmpeg -i input -f flv rtmp://…
视频通话(WebRTC) WebRTC + FFmpeg 转码 + Java 信令
Docker 管理 --restart=unless-stopped + 资源限制
推荐方案:
FFmpeg + Python API(适合简单调用)
Java + Docker Exec(适合复杂控制)
WebRTC + FFmpeg(适合视频通话)