docker安装FFmpeg

发布于:2025-08-07 ⋅ 阅读:(16) ⋅ 点赞:(0)

官网地址: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
  1. 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 完成
  1. 视频通话方案(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(适合视频通话)


网站公告

今日签到

点亮在社区的每一天
去签到