在 Ubuntu Docker 映像上录制声音



我想在捕获屏幕时用ffmpeg录制音频。使用alsa时遇到的错误是我的图像没有声卡-f alsa -ac 2 -i hw:0

以下是在新版本的 Ubuntu 上重现的方法

在新的 ubuntu docker 映像中启动会话。

docker pull ubuntu
docker run -it --rm ubuntu

Setup alsa(Advanced Linux Sound Architecture)

apt-get update
apt-get install alsa-utils

列出声卡

aplay -l
# aplay: device_list:268: no soundcards found...

播放此声音将失败,因为此图像没有任何声卡

sudo aplay /usr/share/sounds/alsa/Front_Center.wav

编辑:在阅读了对BMitch关于不需要在本地计算机上播放的第一条评论后

我重新建议使用 pulseaudio,因为它的用户空间代码和不需要内核模块。在我看来,alsa 不太可能为 docker 工作(尽管我可能是错的)

如果我这样做:

apt-get update
apt-get install pulseaudio socat
apt-get install alsa-utils
apt-get install ffmpeg
# Start the pulseaudio server
pulseaudio -D --exit-idle-time=-1
# Load the virtual sink and set it as default
pacmd load-module module-virtual-sink sink_name=v1
pacmd set-default-sink v1
# set the monitor of v1 sink to be the default source
pacmd set-default-source v1.monitor
# Start the ffmpeg capture to an audio file
ffmpeg -f pulse -i default out.mp3

然后在单独的终端中

paplay /usr/share/sounds/alsa/Front_Center.wav

WAV 文件的音频由 ffmpeg 捕获并显示在输出中.mp3

我真的不知道你的X设置是什么样子的,但如果你可以让音频进入脉冲音频,那么ffmpeg将捕获音频,而不需要真正的声卡

原始答案:如果您希望音频到达Mac OS声卡

我最初到达此页面,因为我试图将音频从虚拟机内部播放到 Mac OS。但是,如果您不关心将其从 VM 中取出,那么以下内容就过于复杂了。我把它留在这里,因为这个想法是我最终来到这里的原因

可以在 VM 中使用脉冲音频将 WAV 文件播放到物理声卡。我在Mac OS Sierra上使用docker 17.03.1-ce,并使用brew来安装sox。此设置还需要在 VM 上安装 socat,但我认为具有更多 pulseaduio 知识的人(或者如果我有更多时间)应该能够删除这部分

策略是使用 paplay 通过 pulseaudio 播放 wav 文件,并让 pulseaudio 通过网络在 VM 启动时发布的端口上发送音频。在 Mac 端,您将连接到此已发布的端口,并通过 sox 将数据发送到 Mac。

1.MAC:使用已发布的端口拉取并运行映像

docker pull ubuntu
docker run -it --rm -p 127.0.0.1:3000:3000 ubuntu

2.VM:更新并安装所需的软件包

apt-get update
apt-get install pulseaudio socat
apt-get install alsa-utils

我只为 wav 文件安装 alsa-utils,所以你可以删除它

3.虚拟机:启动脉冲音频服务器

pulseaudio -D --exit-idle-time=-1

这告诉服务器分叉到后台,而不是基于不活动退出

4.VM:为脉冲音频创建"接收器">

接收器是脉冲音频以特定格式发送音频数据的位置:

pacmd load-module module-pipe-sink file=/dev/audio format=s16 rate=44100 channels=2

这会将音频发送到 44100Hz 的签名 16 位 2 通道文件/dev/audio。

5.虚拟机:将文件附加到网络

此文件现在需要"附加"到网络,socat 用于在已发布的地址(注意:此处没有身份验证)处创建一个侦听套接字,该套接字已准备好在 Mac 端连接时发送音频

socat file:/dev/audio tcp-listen:3000

6.MAC:将数据从网络读取到 sox

在 Mac 端,我们现在需要连接到此端口并通过 sox 将详细信息发送到音频驱动程序:

nc 127.0.0.1 3000 | sox -traw -r44100 -b16 -c2 -e signed-integer - -d

默认情况下,Mac 具有 Netcat (NC),因此我在此处使用它连接到已发布的端口,然后将数据通过管道传输到 Sox,并使用 SOX 标志以匹配上面"加载模块"语句中设置的值。

7.虚拟机:玩!

最后,使用脉冲音频包中的暂停播放,可以播放WAV文件:

paplay /usr/share/sounds/alsa/Front_Center.wav

8.MAC:听!在 mac 端,您现在应该在这里播放音频,并能够看到 sox 的输出,其中包括一个小电平表,这应该会移动:

$ nc 127.0.0.1 3000 | sox -traw -r44100 -b16 -c2 -e signed-integer - -d
-: (raw)
File Size: 0
Encoding: Signed PCM
Channels: 2 @ 16-bit
Samplerate: 44100Hz
Replaygain: off
Duration: unknown
In:0.00% 00:00:06.78 [00:00:00.00] Out:299k  [      |      ]        Clip:0

做相反的事情(即将 Mac 音频发送到 VM 上的 pulseaudio)也应该可以通过类似的设置(模块-管道-源?

我还没有针对 ffmpeg 页面上的命令对此进行测试,因为我没有 X 服务器。

我认为关键在于docker run命令以将设备映射到容器中。试试这个:

docker run -ti --rm 
-v /dev/snd:/dev/snd 
--lxc-conf='lxc.cgroup.devices.allow = c 116:* rwm' 
myContainer sh -c "echo run something"`

从这里提取。在此链接上,如果这对您不起作用,则有更多选择。看看吧!

这将比您希望的要困难得多。由于 Docker 在嵌入式 VM 中运行,因此需要首先将声卡映射到 VM。映射到 VM 后,你将能够执行docker run --device=/dev/snd:/dev/snd ...,将设备从 VM 映射到容器中。

问题是第一部分,特别是因为Mac和Linux是不同的操作系统。似乎有一些选项可以安装创建所需跨平台/开发设备的工具。执行此操作后,需要将 VM 配置为将这些设备共享到 VM 中。

sudo adduser $USER audio

usermod --append --groups audio $USER

这两个命令都帮助我在Linux(具体来说就是Ubuntu)中显示声卡。我在 docker 容器中也遇到了同样的错误,并在使用 docker exec 解决问题时将这些添加到自动化脚本中,并且我能够使用 arecord -l 和 aplay -l 命令显示 souncards。

此外,我使用这些命令来安装必要的 alsa 和脉冲音频。

sudo apt-get install alsa alsa-utils alsa-tools
sudo apt install pulseaudio pulseaudio-utils

最新更新