当前位置: 首页 > 知识库问答 >
问题:

如何在Django视图中异步生成Google文本到语音音频文件,以便在网页中使用?

夏立果
2023-03-14

我的一个网页在本地加载大约需要3秒,在Heroku上实时加载需要15秒。我认为问题在于我进行了多少次同步GoogleTTS(文本到语音)API调用和同步数据库/AmazonS3写入。

我认为异步编码会有所帮助,但我不完全确定如何实现它。以下是视图中发生的情况:

# views.py 

def convert_str_to_audio_info_if_necessary(audio_str):
    audio_info =  AudioInfo.objects.get_by_text(audio_str)
    if audio_info is None:
        audio_content = synthesize_text(audio_str) # returns audio file from Google
        # WAIT for the response to come back from Google's API
        new_audio = ContentFile(audio_content, 'audio.wav') # converts to file Python can read
        audio_info = AudioInfo.objects.create_problem_audio(text=audio_str, audio=new_audio, duration=get_audio_file_duration(new_audio))
        # WAIT for the audio file to be written to my S3 bucket
    return audio_info

def slow_loading_view(request):
    for i in range(100):
        audio_str = str(i)
        audio_info = convert_str_to_audio_info_if_necessary(audio_str)
        context[audio_str] = audio_info
    # Now I would like to pass this data in my context to use in the webpage
    return render(request, 'my_page.html', context)

在我的模型中:

# models.py

class AudioInfoManager(models.Manager):

    def get_by_text(self, text):
        qs = self.get_queryset().filter(text=text) 
        if len(qs) == 0:
            return None
        return qs[0]

    def create_problem_audio(self, text, audio, duration):
        already_created_entry = self.get_by_text(text)
        if already_created_entry != None:
            return already_created_entry
        problem_audio = self.create(text=text, audio=audio, duration=duration)
        return problem_audio


class AudioInfo(models.Model):
    text            = models.TextField(unique=True)
    audio           = models.FileField(upload_to=upload_audio_info_path)
    duration        = models.FloatField()

    objects         = AudioInfoManager()

如你所见,视图中有很多等待(空闲时间),所以理想情况下,我可以1)异步发送所有谷歌应用编程接口请求来生成音频文件,然后在我将所有这些音频文件返回后2)异步将这些音频文件写入数据库和S3桶,然后一旦它们都被写入,3)查询数据库中的数据,并将数据作为上下文传递给我的网页。

Django中的所有异步库(如芹菜和Redis Queue)似乎只对后台任务有帮助(在呈现视图网页之前不需要完成的任务,例如发送电子邮件、将数据写入网页中不需要的数据库等)。也许asyncio或Django通道是解决方案?Django是一个同步框架,所以我不确定是否允许异步更新数据库。

对我应该做什么有什么建议吗?

共有1个答案

赵禄
2023-03-14

我同意,考虑到当前的实现,这看起来不像是任务队列的用例。

正如你提到的,写作确实是花费时间最多的。

有几种不同的方法,可以结合使用:

  • 在内存缓存中避免重新计算(Redis,Memcached)
  • UI上的句柄(一个操作转换为音频,另一个操作在DB写入期间使用加载条)
  • 异步写入(收集音频文件以写入、发送并与正在写入的用户通信);如果您能够使用支持异步的较新版本的Django,我将访问与Python3.7版本相关联的asyncio库

就用户界面而言,可能类似于在Gmail中添加多个附件。

 类似资料:
  • 我正在使用GoogleAppis包中的Google Speech To Text API。但我没有找到任何文档(用于dart

  • 使用Microsoft语音API转录中/大型音频文件(每个文件约6-10分钟)的最佳方式是什么?比如批量音频文件转录? 我使用了https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/speech-to-text-sample中提供的代码,用于连续转录语音,但它在某个时候停止转录。转录有任何限制吗?我只使用免

  • 问题内容: 我正在尝试将freetts用于一个简单的Java应用程序,但是我遇到了一个问题,谁能告诉我如何在我的程序中将输出的语音(从文本转换为语音)保存为wave文件。我想通过代码做到这一点。 这是示例提供的示例helloworld应用程序 这段代码可以正常工作,我想将输出保存为磁盘上的音频文件。 谢谢普兰尼 问题答案: 我想出了方法,您只需要简单地使用传递文件名和文件类型,样本声明就应该像这样

  • 我对javascript和discord.js很陌生,有人知道如何让机器人加入一个频道,播放一个文件然后离开吗? 以下是我尝试过的: 现在,它将发送消息加入语音通道,而不管我是否在其中,如果我在其中,它就不会加入语音通道并播放文件。任何帮助都很感激。

  • Enunciate目前没有gradle插件(https://jira.codehaus.org/browse/ENUNCIATE-815). 有没有办法手动触发Gradle的文档构建?

  • 如何让音频文件连续重复?现在音乐只播放一次,就是这样。我试图让声音一遍又一遍地重复。我是否必须以另一种方式获取音频文件,或者有更简单的方法? 代码: 我怎么称呼它: