我有一个驻留在用户本地移动设备上的解决方案,我希望它使用 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 似乎没有 native 解压 MP3 的能力。我读过这会很慢,不值得做。
导入库
使用 ffmpeg-python 或 ffmpy - 但这涉及创建部署包或类似的东西。我可以走这条路,但这对于我想做的事情来说似乎过于复杂。
使用 Python 以外的东西
我选择了 Python,因为我更熟悉在 Lambda 中使用它进行编码,但也许 C#、Node、Java 8 有一些可用的东西可以使这在 Lambda 函数中变得容易。
目前我正在考虑执行以下操作
当然这里会有一些延迟问题,但只要它们不太严重,我愿意忍受它们。对于我认为相当简单的任务来说,这似乎过于复杂。然而,这是迄今为止我想出的最好的,但即使证明它也需要几个小时的工作,我已经花了好几天的时间。
所以主要的问题是是否可以在 AWS Lambda 中使用 Python Wave 库以这种方式修改采样率?
如果没有,有没有办法通过创建部署包、使用我尚未研究的 AWS 功能或用 Python 以外的其他方式来解决这个问题?
问题是这个应用程序的 Lex 部分应该是一个不错的功能,它不是主要功能,但它占用了大部分开发时间,我非常接近放弃它,但我想我会先在这里问。
最佳答案
所以花了一段时间,但有办法做到这一点。
我解决它的方法是将文件保存到 s3,然后通过 Elastic Transcoder 运行以获取 wav 文件(1 个 channel ,22050 采样率)。
然后使用以下 var 值
这段代码应该把它降到 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 秒,因此对于生产级解决方案可能 Not Acceptable ,但它足以满足我的需求。
感谢以下来源
关于amazon-web-services - 用于为 Lex 转换 MP3 输入的 AWS Lambda 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52242737/