amazon-web-services - 用于为 Lex 转换 MP3 输入的 AWS Lambda 代码
问题描述
我有一个驻留在用户本地移动设备上的解决方案,我希望它使用 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 函数中变得容易。
目前我正在考虑执行以下操作
- 使用 Python 将 MP3 文件保存到 S3 存储桶
- 让 Elastic Transcoder 以 22050 采样率将该 MP3 转换为 PCM(但所有其他设置都设置为 Lex 需要)
- Lambda 从 S3 读回转码文件
- 使用wave(import wav)库读取文件,然后以16000的采样率写入文件(这是我不确定的步骤)
- 将文件(以正确的采样率)发布到 Lex
当然这里会有一些延迟问题,但只要它们不太严重,我愿意忍受它们。对于我认为相当简单的任务来说,这似乎过于复杂。然而,这是迄今为止我想出的最好的,但即使要证明这一点也需要花费数小时的工作,而且我已经花了好几天的时间。
所以主要的问题是是否可以在 AWS Lambda 中使用 Python Wave 库以这种方式修改采样率?
如果没有,是否有办法通过创建部署包、使用我尚未研究的 AWS 功能或在 Python 以外的其他东西中更简洁地执行此操作来解决此问题?
问题是这个应用程序的 Lex 部分应该是一个不错的选择,它不是主要功能,但它占用了大部分开发时间,我非常接近放弃它,但我想我会先在这里问。
解决方案
所以花了一段时间,但有办法做到这一点。
我解决它的方法是将文件保存到 s3,然后通过 Elastic Transcoder 运行以获取 wav 文件(1 个通道,22050 采样率)。
然后使用以下 var 值
- 无速率=22050
- 出价=16000
- 频道内=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 秒,因此对于生产级解决方案来说可能是不可接受的,但它足以满足我的需求。
感谢以下来源
推荐阅读
- azure-ad-b2c - 登录 Azure B2C 页面上的内容安全策略错误
- swiftui - 如何在 swiftui 中为子视图设置私有状态变量?
- javascript - 从新创建的 div 创建一个新的 div
- javascript - 如何更改数组中除第一个元素之外的所有元素以仅显示差异
- html - @media 规则的问题
- cryptography - 如果已知模数长度,如何计算 rsa 密钥的字节长度
- android - ADB 如何查找设置和提取坐标以便我可以通过编程方式执行点击?
- hive - 在 Impala 中通过正则表达式选择列?
- javascript - 检查一个 HTML 字符串是否只有元素子元素(或元素之间的空格)并且没有元素是未知的
- git - 将文件提交到 git 但之后不允许更改