为 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 函数中简化此操作。
目前我正在考虑做以下事情
- 使用Python将MP3文件保存到S3存储桶
- 让 Elastic Transcoder 以 22050 采样率将该 MP3 转换为 PCM(但所有其他设置都设置为 Lex 需要)
- Lambda 从 S3 读回转码后的文件
- 使用wave(导入wav)库读取文件,然后以16000的采样率写入文件(这是我不确定的步骤)
- Post 文件(具有正确的采样率)到 Lex
当然这里会有一些延迟问题,但只要它们不是太严重,我愿意忍受它们。对于我认为相当简单的任务来说,这似乎过于复杂。然而,这是我迄今为止想出的最好的,但即使要证明它也需要几个小时的工作,我已经花了好几天的时间。
所以主要问题是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 秒,因此对于生产级解决方案来说可能不可接受,但足以满足我的需求。
感谢以下来源
我有一个解决方案将驻留在用户的本地移动设备上,我希望它 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 函数中简化此操作。
目前我正在考虑做以下事情
- 使用Python将MP3文件保存到S3存储桶
- 让 Elastic Transcoder 以 22050 采样率将该 MP3 转换为 PCM(但所有其他设置都设置为 Lex 需要)
- Lambda 从 S3 读回转码后的文件
- 使用wave(导入wav)库读取文件,然后以16000的采样率写入文件(这是我不确定的步骤)
- Post 文件(具有正确的采样率)到 Lex
当然这里会有一些延迟问题,但只要它们不是太严重,我愿意忍受它们。对于我认为相当简单的任务来说,这似乎过于复杂。然而,这是我迄今为止想出的最好的,但即使要证明它也需要几个小时的工作,我已经花了好几天的时间。
所以主要问题是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 秒,因此对于生产级解决方案来说可能不可接受,但足以满足我的需求。
感谢以下来源