官网地址: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; then
echo "Processing succeeded"
else
echo "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; do
filename=$(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 os
app = Flask(__name__)
@app.route("/ffmpeg/convert", methods=["POST"])
def convert_video():
data = request.json
input_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.json
input_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(适合视频通话)