是否可以在 Google 云上使用 Docker 部署的 Python Web 应用程序中生成声音?

Is it possible to generate sound within a Python web application deployed with Docker on Google Cloud?

我构建了一个简单的网络应用程序,用于测试用户的听力频率范围。它内置于 JustPy 框架中,并使用 pysinewave(依次基于 sounddevice)连续生成声音。我已将它部署在 Google 云上的 Docker 容器中,网站部分工作正常,但声音生成部分出现问题。以下是调试器输出的一部分:

500 Server Error
PortAudioError: Error querying device -1

Traceback

File /usr/local/lib/python3.10/site-packages/sounddevice.py, line 564, in query_devices ‒

561.     device = _get_device_id(device, kind, raise_on_error=True)

562.     info = _lib.Pa_GetDeviceInfo(device)

563.     if not info:

564.         raise PortAudioError('Error querying device {}'.format(device))

565.     assert info.structVersion == 2

566.     name_bytes = _ffi.string(info.name)

567.     try:

File /usr/local/lib/python3.10/site-packages/sounddevice.py, line 2654, in _get_stream_parameters ‒

2651.         samplerate = default.samplerate

2652.

2653.     device = _get_device_id(device, kind, raise_on_error=True)

2654.     info = query_devices(device)

2655.     if channels is None:

2656.         channels = info['max_' + kind + '_channels']

2657.     try:

File /usr/local/lib/python3.10/site-packages/sounddevice.py, line 811, in __init__ ‒

808.                 samplerate = isamplerate

809.         else:

810.             parameters, self._dtype, self._samplesize, samplerate = \

811.                 _get_stream_parameters(kind, device, channels, dtype, latency,

812.                                        extra_settings, samplerate)

813.             self._device = parameters.device

814.             self._channels = parameters.channelCount

File /usr/local/lib/python3.10/site-packages/sounddevice.py, line 1488, in __init__ ‒

1485.         Stream, RawOutputStream

1486.

1487.         

1488.         _StreamBase.__init__(self, kind='output', wrap_callback='array',

1489.                              **_remove_self(locals()))

1490.

1491.     def write(self, data):

File /usr/local/lib/python3.10/site-packages/pysinewave/sinewave.py, line 21, in __init__ ‒

18.                                     samplerate=samplerate)

19.

20.         # Create the output stream

21.         self.output_stream = sd.OutputStream(channels=1, callback= lambda *args: self._callback(*args), 

22.                                 samplerate=samplerate)

23.

24.     def _callback(self, outdata, frames, time, status):

File /app/./soundgen.py, line 7, in __init__ ‒

4. class SoundGen(SineWave):

5.

6.     def __init__(self, freq, vol):

7.         super().__init__(pitch=9, pitch_per_second=10000, decibels=-30, decibels_per_second=10000)

8.         self.set_frequency(freq)

9.         self.set_volume(vol)

10.         self.volume = self.sinewave_generator.amplitude

File /app/./main.py, line 23, in serve ‒

20.     def serve(cls, req):

21.

22.         # sine wave generator

23.         sound = SoundGen(440, 0.15)

24.

25.         freq_dict = cls.gen_freq_dict()

26.

我在 Dockerfile 中使用以下命令安装了额外的库(基于 中的答案):

RUN apt-get update
RUN apt-get install libasound-dev libportaudio2 libportaudiocpp0 portaudio19-dev -y

但显然,这还不够。我是否缺少一个重要的库来让它工作,或者这种功能——通过托管在远程服务器上的网络应用程序在用户的浏览器中生成声音——不可能以这种方式实现?

重申一下:应用程序在 运行 本地运行时完全正常,使用 JustPy 生成的前端部分(禁用声音功能)在 Google 云端部署时也运行良好。

非常感谢您的建议。

在我看来,您想部署一个在 用户的 设备上播放音频的网络应用程序。当您在云端托管您的应用程序时,运行您的应用程序的服务器将是您使用 SoundGen class 的后端。当你触发它发出声音时,它会搜索音频设备 - 在云服务器中不可用,因此它会抛出异常。

如果您在您的 计算机上托管您的应用程序,docker 运行时能够访问您的音频外围设备并播放您想要的声音。您可能想要做的是将声音生成从后端代码移到前端部分。在触发时(例如按钮单击),仅使用前端代码在客户端设备(浏览器)上播放您想要的声音。不幸的是,我不熟悉 JustPy,所以我无法为您编写示例代码,但希望这仍然对您有所帮助。