为 Lex 转换 MP3 输入的 AWS Lambda 代码

AWS Lambda code to convert MP3 input for Lex

我有一个解决方案将驻留在用户的本地移动设备上,我希望它 post 使用 AWS REST API 向 Lex 发送音频内容。问题在于该解决方案无法流式传输音频(向上或向下)并且几乎没有本地音频处理功能。然而,Lex 有非常具体的输入要求,也有流输出。

因此,访问将通过 API 网关作为代理,使用 Lambda (Python 2.7) 函数来处理音频问题。

输出全部处理完毕,Lambda 代码将 AudioStream 保存到一个文件中并将该文件作为响应正文发送,这工作正常。但是我无法让输入工作。

输入音频是作为 POST 请求正文发送的 MP3 文件,我需要将其转换为 Lex 可接受的格式。

我研究了以下方法

原生 AWS
使用 S3 和 Elastic Transcoder - 转码为 PCM 时允许的最低采样率为 22050,但 Lex 要求 16000,这似乎也不允许转码为 Opus 格式

使用 MediaConvert - 看不到转换为 PCM 或 Opus 的设置

原生 Python
Python 似乎没有本机解压 MP3 的能力。我读到这会很慢,不值得做。

导入库
使用 ffmpeg-python 或 ffmpy - 但这涉及创建部署包或类似的东西。我可以走这条路,但这对我想做的事情来说真的太复杂了。

使用Python
以外的东西 我选择 Python 是因为我更熟悉在 Lambda 中使用它进行编码,但也许 C#、Node、Java 8 有一些可用的东西可以在 Lambda 函数中简化此操作。

目前我正在考虑做以下事情

当然这里会有一些延迟问题,但只要它们不是太严重,我愿意忍受它们。对于我认为相当简单的任务来说,这似乎过于复杂。然而,这是我迄今为止想出的最好的,但即使要证明它也需要几个小时的工作,我已经花了好几天的时间。

所以主要问题是PythonWave库是否可以在AWS Lambda中使用这种方式修改采样率?

如果没有,有没有一种方法可以通过创建部署包、使用我尚未研究过的 AWS 功能或使用 Python 以外的更简洁的方法来解决此问题?

问题是这个应用程序的 Lex 部分应该是一个不错的选择,它不是主要功能,但它占用了大部分开发时间,我非常接近放弃它,但我想我会先在这里问一下。

所以花了一段时间,但有办法做到这一点。

我解决的方法是将文件保存到s3,然后运行通过Elastic Transcoder得到一个wav文件(1通道22050采样率)。

然后使用以下变量值

  • inrate=22050
  • 超过=16000
  • inchannels=2
  • 外渠道=1

并且这段代码应该可以降低到 16000

import audioop
import wave

s_read = wave.open(src, 'r')
s_write = wave.open(dst, 'w')

n_frames = s_read.getnframes()
data = s_read.readframes(n_frames)

converted = audioop.ratecv(data, 1, inchannels, inrate, outrate, None)

s_write.setparams((outchannels, 2, outrate, 0, 'NONE', 'Uncompressed'))
s_write.writeframes(converted[0])

s_read.close()
s_write.close()

该文件随后被 Lex 接受并得到预期的响应。

此方法有一些明显的延迟,根据 CloudWatch Logs,处理通常大约需要 7-10 秒,因此对于生产级解决方案来说可能不可接受,但足以满足我的需求。

感谢以下来源