如何在docker中使用alsa声音and/orsnd_pcm_open?

How to use alsa sound and/or snd_pcm_open in docker?

我是 运行 Ubuntu 12.04 Docker 容器,位于 Ubuntu 16.04 主机上。一些测试代码我有练习 'snd_pcm_open'/'snd_pcm_close' 与 SND_PCM_STREAM_PLAYBACK 和 SND_PCM_STREAM_CAPTURE 流类型的操作。

我不需要任何实际的 sound/audio 功能,只需获得具有有效句柄的 'snd_pcm_open' return 0,然后 'snd_pcm_close' 到 return 0在同一个手柄上就足以满足我的目的。我不想修改代码,因为它已经有一些不太好的平台依赖开关,而且我不是维护者。

我正在使用简单代码并将其编译为 'g++ alsa_test.cpp -lasound'

#include <stdio.h>
#include <alsa/asoundlib.h>

int main() {
    snd_pcm_t* handle;
    snd_pcm_stream_t stream_type[]= {SND_PCM_STREAM_PLAYBACK, SND_PCM_STREAM_CAPTURE};

    printf("\nstarting\n");
    for (unsigned char i = 0; i < sizeof(stream_type) / sizeof(stream_type[0]); ++i) {
        printf(">>>>>>>>\n\n");
        int deviceResult = snd_pcm_open(&handle, "default" , stream_type[i], 0);
        printf("\n%d open: %d\n", stream_type[i], deviceResult);

        if (deviceResult >= 0) {
            printf("attempting to close %d\n", stream_type[i]);
            snd_pcm_drain(handle);
            deviceResult = snd_pcm_close(handle);
            printf("%d close: %d\n\n", stream_type[i], deviceResult);
        }
        printf("<<<<<<<<\n\n");
    }

    return 0;
}

它在主机上工作得很好,但尽管我尝试了所有不同的东西,'snd_pcm_open' returns '-2' 对于容器中的两种流类型。

我尝试安装 'libasound2.dev',但 'modinfo soundcore' 是空的,并且“/dev/snd”不存在。

还尝试了 运行 具有以下选项的容器,尽管对于这样一个简单的目的来说感觉像是一个巨大的杀伤力 --privileged --cap-add=ALL -v /dev:/dev -v /lib/modules:/lib/modules

在容器中添加这些额外参数后,以下命令在主机和容器中生成相同的输出。

root@31142791f82d:/export# modinfo soundcore
filename:       /lib/modules/4.4.0-59-generic/kernel/sound/soundcore.ko
alias:          char-major-14-*
license:        GPL
author:         Alan Cox
description:    Core sound module
srcversion:     C941364F5CD0B525693B243
depends:        
intree:         Y
vermagic:       4.4.0-59-generic SMP mod_unload modversions 
parm:           preclaim_oss:int
root@31142791f82d:/export# ls -l /dev/snd/
total 0
drwxr-xr-x  2 root root      100 Feb  2 21:10 by-path
crw-rw----+ 1 root audio 116,  2 Feb  2 07:42 controlC0
crw-rw----+ 1 root audio 116,  7 Feb  2 07:42 controlC1
crw-rw----+ 1 root audio 116, 12 Feb  2 21:10 controlC2
crw-rw----+ 1 root audio 116,  6 Feb  2 07:42 hwC0D0
crw-rw----+ 1 root audio 116, 11 Feb  2 07:42 hwC1D0
crw-rw----+ 1 root audio 116,  3 Feb  2 07:42 pcmC0D3p
crw-rw----+ 1 root audio 116,  4 Feb  2 07:42 pcmC0D7p
crw-rw----+ 1 root audio 116,  5 Feb  2 07:42 pcmC0D8p
crw-rw----+ 1 root audio 116,  9 Feb  2 10:44 pcmC1D0c
crw-rw----+ 1 root audio 116,  8 Feb  2 07:42 pcmC1D0p
crw-rw----+ 1 root audio 116, 10 Feb  2 21:30 pcmC1D1p
crw-rw----+ 1 root audio 116, 14 Feb  2 21:10 pcmC2D0c
crw-rw----+ 1 root audio 116, 13 Feb  2 21:10 pcmC2D0p
crw-rw----+ 1 root audio 116,  1 Feb  2 07:42 seq
crw-rw----+ 1 root audio 116, 33 Feb  2 07:42 timer

容器只有 'root' 用户,所以访问权限也不成问题。

实现此功能的最简单且最简单的方法是什么?我宁愿摆脱特权模式和 dev/modules 映射到容器,但是,这些容器不能从外部世界访问,并且仅 created/destroyed 用于一些短期任务。所以,安全并不是一个大问题。

提前致谢。

如果您实际上不需要设备正常工作,请使用 null 设备而不是 default

要使 null 插件成为默认插件,请将其放入容器的 /etc/asound.conf 或用户的 ~/.asoundrc:

pcm.!default = null;