循环下载多个音频文件失败(python)
Posted
技术标签:
【中文标题】循环下载多个音频文件失败(python)【英文标题】:downloading multiple audio files in a loop failed (python) 【发布时间】:2021-07-01 07:17:11 【问题描述】:我正在尝试使用 python 中的循环从 AWS polly(文本到语音服务)下载 mp3 文件 我使用的代码如下:
for i in range(0, 3):
filename = str(i) + ".mp3"
response = polly_client.synthesize_speech(VoiceId='Joanna',
OutputFormat='mp3',
Text = "blah blah blah"
file = open(filename, 'wb')
file.write(response['Audiostream'].read())
file.close()
这最终给了我 1kb 的文件,这意味着每个文件中没有任何内容.. 我可以做些什么来改进代码,以便循环暂停,直到每个音频文件都下载完成..
提前谢谢你。
【问题讨论】:
如果您在任何循环之外对单个文件执行此操作,是否可以按预期工作? 是的,它工作正常 我相信我需要使用子进程...但我不知道如何.. 嗯,我认为你不需要subprocess
。我没有 AWS 凭证,否则我会自己尝试,但仅从查看文档来看,response["AudioStream"]
是一个 botocore.response.StreamingBody
对象,它代表一个实时的异步套接字连接,数据可以通过该连接流式传输。您的循环运行得如此之快,以至于一旦有机会首先开始读取,套接字实际上就关闭了。似乎存在这些特殊的 waiter
对象,它们等待异步进程 - 不确定它们是如何工作的,但值得研究。
您还可以为synthesize_speech
方法设置自定义InvocationType
关键字参数。将其从Event
更改为RequestResponse
具有将一些异步函数更改为同步函数的效果,但同样,我对AWS 了解不多。
【参考方案1】:
我找到了解决这个问题的方法,但方式有点不同..
正如我所猜测的,使用子进程函数可能是关键..
在子进程中使用命令(aws 命令行)可生成良好的 mp3 文件。
代码如下
import pandas as pd
import subprocess
import codecs
for i in range (0,3):
word = 'blah blah blah'
file_name = '0' + str(i) + '.mp3'
print(word)
command = 'aws polly synthesize-speech --text-type ssml --output-format "mp3" --voice-id "Salli" --text "<speak>' + word + '</speak>" ' + file_name
print(command)
subprocess.call(command, shell=True)
【讨论】:
【参考方案2】:看看这个来自亚马逊的example。它演示了使用with closing(...)
来确保正确关闭响应流。
这里有一些代码,未经测试,应该适合你:
from contextlib import closing
for i in range(3):
filename = f'i.mp3'
response = polly_client.synthesize_speech(VoiceId='Joanna',
OutputFormat='mp3',
Text = "blah blah blah"
if 'AudioStream' in response:
with closing(response['AudioStream']) as stream, open(filename, 'wb') as file:
while data := stream.read():
file.write(data)
else:
print(f'Problem streaming audio: response=')
【讨论】:
不幸的是,这也不起作用..这种情况导致所有三个文件都是 0kb。 但是,我找到了另一种方法。我使用命令和子进程而不是直接在 Python 中处理它。它有效。不过感谢您的帮助。 @JohnLee:我认为您应该进一步探索文档。使用 subprocess 不是处理文件的好方法。问题基本上是您的代码没有读取完成返回的流 - 单个读取操作可能只会导致 1K 的数据。您应该遍历流,直到读取 0 个字节。 @JohnLee:我已经更新了我的答案以循环流数据直到它被关闭。以上是关于循环下载多个音频文件失败(python)的主要内容,如果未能解决你的问题,请参考以下文章