如何实现多个Docker容器的音频分别独立通过RTP流输出
多Docker容器独立音频RTP推流解决方案
问题核心
所有容器共享宿主机PulseAudio服务的默认输出sink,音频全部混合到同一条流中,因此推流时只能拿到混合音频。只需给每个容器分配专属独立虚拟音频sink,隔离音频输出路径即可解决。
操作步骤
宿主机创建专属虚拟音频sink
提前在宿主机为每个容器创建独立的null sink,不同sink使用不同的唯一命名:# 为容器1创建专属sink pactl load-module module-null-sink sink_name=container_sink_1 sink_properties=device.description="容器1音频输出" # 为容器2创建专属sink pactl load-module module-null-sink sink_name=container_sink_2 sink_properties=device.description="容器2音频输出" # 更多容器按规则命名依次创建即可不需要使用的sink可以执行
pactl unload-module <对应模块ID>卸载。启动容器时指定专属输出sink
在原有启动命令中新增PULSE_SINK环境变量,指定当前容器要使用的专属sink,以容器1为例:sudo docker run -it \ --device /dev/snd \ -e PULSE_SERVER=unix:${XDG_RUNTIME_DIR}/pulse/native \ -e PULSE_SINK=container_sink_1 \ -v ${XDG_RUNTIME_DIR}/pulse/native:${XDG_RUNTIME_DIR}/pulse/native \ -v ~/.config/pulse/cookie:/root/.config/pulse/cookie \ --group-add $(getent group audio | cut -d: -f3) \ ubuntu:16.04 /bin/bash启动其他容器时只需修改
PULSE_SINK的值为对应预先创建的sink名即可,此时容器内所有音频应用默认都会输出到指定的专属sink,不会和其他容器音频混合。修改FFmpeg推流命令抓取独立流
推流时不要抓取默认pulse源,改为抓取对应sink的monitor源,每个sink的monitor源默认和sink绑定,只会输出该sink的独立音频,容器1的推流命令修改为:ffmpeg -f pulse -i container_sink_1.monitor -acodec libmp3lame -ab 128k -ac 2 -ar 48000 -c:a libopus -f rtp rtp://$IP:4001其他容器推流时修改输入源为对应sink的monitor、更换不同的推流端口即可。
批量使用优化
如果需要频繁启动销毁大量容器,可以编写配套脚本,启动容器前自动生成唯一sink名、创建sink,容器退出后自动卸载对应sink即可实现自动化调度。
内容的提问来源于stack exchange,提问作者Sina Zand Karimi
相关产品推荐
相关产品推荐

