循环下载多个音频文件失败(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)的主要内容,如果未能解决你的问题,请参考以下文章

Python 实现 m3u8 视频下载

加载资源失败:下载多个文件时,Safari 浏览器中的帧加载中断

Python文件下载失败

傻瓜式下载“喜马拉雅”音频文件

Python解析Wav文件并绘制波形的方法

什么小程序可以设置多个音频