You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器中FFmpeg推流YouTube时域名解析失败问题求助

问题描述

我正搭建一个Docker环境,使用NGINX RTMP服务器和PHP容器,通过HLS文件向YouTube Live推流。容器间通过共享卷传输文件,在PHP容器内使用FFmpeg启动推流时,遇到无法解析YouTube RTMP服务器域名的问题。

环境配置详情

Docker Compose配置(docker-compose.yml)

version: '2'
services:
  rtmp:
    image: tiangolo/nginx-rtmp
    ports:
      - "1935:1935"
    volumes:
      - shared_data:/usr/share/nginx/hls
      - ./conf/nginx.conf:/etc/nginx/nginx.conf
  php:
    build: .
    ports:
      - "8080:80"
    volumes:
      - shared_data:/var/www/html/hls
      - ./src:/var/www/html
    security_opt:
      - seccomp:unconfined

volumes:
  shared_data:

Dockerfile

FROM php:apache
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN curl -O https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz && \
    tar -xJf ffmpeg-release-amd64-static.tar.xz && \
    mv ffmpeg-*/ffmpeg /usr/local/bin/ && \
    mv ffmpeg-*/ffprobe /usr/local/bin/ && \
    rm -rf ffmpeg-*

./conf/nginx.conf

worker_processes auto;
rtmp_auto_push on;
events {}
rtmp {
    server {
        listen 1935;
        listen [::]:1935 ipv6only=on;
        access_log /var/log/rtmp_access.log;
        chunk_size 4096;
        timeout 10s;

        application live {
            live on;
            record off;

            hls on;
            hls_path /usr/share/nginx/hls;
            hls_fragment 10s;
        }
    }
}

NGINX容器接收来自GoPro相机的RTMP流,PHP容器提供推流管理UI并通过FFmpeg分发流,接收的HLS文件通过Docker共享卷共享。

失败的FFmpeg命令

ffmpeg -re -i "/var/www/html/hls/.m3u8" -c:a aac -ar 44100 -ab 128k -ac 2 -strict -2 -flags +global_header -bsf:a aac_adtstoasc -bufsize 3000k -f flv "rtmp://a.rtmp.youtube.com/live2/live_key"

错误信息

[tcp @ 0x696d2c0] Failed to resolve hostname a.rtmp.youtube.com: System error
[rtmp @ 0x696d480] Cannot open connection tcp://a.rtmp.youtube.com:1935?tcp_nodelay=0
[out#0/flv @ 0x6890880] Error opening output rtmp://a.rtmp.youtube.com/live2/live_key: Input/output error
Error opening output file rtmp://a.rtmp.youtube.com/live2/live_key.
Error opening output files: Input/output error

成功的FFmpeg命令(使用IP而非域名)

ffmpeg -re -i "/var/www/html/hls/.m3u8" -c:a aac -ar 44100 -ab 128k -ac 2 -strict -2 -flags +global_header -bsf:a aac_adtstoasc -bufsize 3000k -f flv "rtmp://74.125.203.134/live2/live_key"

已尝试的操作

  • 在主机运行FFmpeg:在macOS主机上安装FFmpeg并运行如下命令,可正常推流,说明问题仅存在于Docker容器环境:
    ffmpeg -re -i "http://localhost:8080/hls/.m3u8" -c:a aac -ar 44100 -ab 128k -ac 2 -strict -2 -flags +global_header -bsf:a aac_adtstoasc -f flv "rtmp://a.rtmp.youtube.com/live2/live_key"
    
  • DNS解析测试:在PHP容器内执行nslookup a.rtmp.youtube.com可获取多个IP地址,说明DNS解析功能正常:
    nslookup a.rtmp.youtube.com
    Server:         240b:11:cc40:d500:23a:9dff:fe92:75a8
    Address:        240b:11:cc40:d500:23a:9dff:fe92:75a8#53
    
    Non-authoritative answer:
    Name:   a.rtmp.youtube.com
    Address: 74.125.203.134
    ...
    

请问是什么原因导致Docker容器内的FFmpeg推流YouTube Live时出现域名解析失败?如何解决该问题,使FFmpeg命令可正常使用域名?


原因分析与解决办法

核心原因

你使用的是静态编译版FFmpeg(从johnvansickle下载的),这类静态编译包默认禁用了系统DNS解析库,改用内置的解析逻辑,但在Docker容器的网络环境下,内置逻辑无法正常读取系统DNS配置,导致域名解析失败。而容器内的nslookup用的是系统自带的解析工具,所以能正常工作;主机上的FFmpeg是动态编译,依赖系统DNS库,因此也没问题。

解决办法

方法1:改用动态编译版FFmpeg替换静态版

修改Dockerfile,通过系统包管理器安装FFmpeg(动态编译,依赖系统库):

FROM php:apache
COPY --from=composer /usr/bin/composer /usr/bin/composer
# 替换静态FFmpeg为系统包
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg && \
    rm -rf /var/lib/apt/lists/*

重新构建PHP容器:docker-compose build php,之后再运行FFmpeg命令即可正常解析域名。

方法2:给静态FFmpeg指定DNS服务器

如果坚持使用静态FFmpeg,可以在FFmpeg命令中手动指定DNS服务器,强制其使用正确的解析地址:

ffmpeg -re -i "/var/www/html/hls/.m3u8" -c:a aac -ar 44100 -ab 128k -ac 2 -strict -2 -flags +global_header -bsf:a aac_adtstoasc -bufsize 3000k -f flv -dns 8.8.8.8 "rtmp://a.rtmp.youtube.com/live2/live_key"

这里用了Google的公共DNS(8.8.8.8),也可以替换成你容器内nslookup显示的服务器地址。

方法3:配置Docker容器的DNS优先级

检查Docker的DNS配置,确保容器优先使用IPv4 DNS而非IPv6:

  1. 在docker-compose.yml的php服务中添加DNS配置:
services:
  php:
    # ... 其他配置
    dns:
      - 8.8.8.8
      - 8.8.4.4
  1. 重启容器:docker-compose down && docker-compose up -d
    静态FFmpeg可能会优先尝试IPv6解析,而部分网络环境下IPv6不通,指定IPv4 DNS可以避免这个问题。

内容的提问来源于stack exchange,提问作者Jun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:24:56