【发布时间】:2017-12-19 13:55:13
【问题描述】:
我正在尝试使用来自 Github(来自 DeepHorizons)的 tts 模块制作一个具有文本到语音功能的程序。因为我希望能够在程序说话时停止程序,所以我将音频录制到文件中然后播放。为了能够多次创建同名文件(比如.wav),我需要删除旧的。问题是我无法删除它,因为它正在被使用(PermissionError: [WinError 32] The process cannot access the file because it is being used by another process),但它只发生在它第二次说话时——第一次时间,它退出 pygame 并删除文件;第二次,它可能不会退出 pygame,因为它给了我错误。我已经尝试过一些库(如 pyaudio 或 pygame),但它们都不能在播放后完全关闭音频文件。顺便说一句,我正在使用 Windows。 我的主要功能的代码是这样的(使用pygame,因为我更熟悉它):
import os
import datetime
import time
import tts.sapi
import pygame
voice = tts.sapi.Sapi()
directory_uncom=os.getcwd()
if not "speech" in directory_uncom:
directory=directory_uncom+"/speech"
else:
directory=directory_uncom
def speak(say):
global directory
global voice
commands_read=open(directory+"/commands.txt","r")
lines3=commands_read.read().splitlines()
lines3[0]="stop_speaking=false"
commands_write=open(directory+"/commands.txt","w")
commands_write.write(lines3[0])
for i in lines3[1:]:
commands_write.write("\n"+i)
commands_write.close()
stop=lines3[0][14:]
voice.create_recording("say.wav", say)
pygame.mixer.init(22000)
pygame.mixer.music.load("say.wav")
pygame.mixer.music.play()
while pygame.mixer.music.get_busy() == True and stop=="false":
commands_read=open(directory+"/commands.txt","r")
lines3=commands_read.read().splitlines()
stop=lines3[0][14:]
pygame.quit()
os.remove("say.wav")
speak("hello") #In this one, it does everything correctly.
speak("hello") #In this one, it gives the error.
我做错了什么?或者谁能告诉我一个更好的方法来做到这一点?
提前致谢。
编辑 -> 我找到了一个“替代方案”,如下所示:
voice.create_recording("say.wav", say)
with open("say.wav") as say_wav_read:
say_wav= mmap.mmap(say_wav_read.fileno(), 0, access=mmap.ACCESS_READ)
pygame.mixer.init(22000)
pygame.mixer.music.load(say_wav)
pygame.mixer.music.play()
while pygame.mixer.music.get_busy() == True and stop=="false":
commands_read=open(directory+"/commands.txt","r")
lines3=commands_read.read().splitlines()
stop=lines3[0][14:]
pygame.quit()
say_wav_read.close()
现在它可以覆盖文件了(不再需要os.remove(),因为pygame只需要关闭文件而我不需要删除它——它只是被覆盖了),但是有一个问题:它卡住并循环句子的同一部分(例如:你好,你好吗 -> ow are y / ow are y / ow are y / ...)。有什么办法可以解决这个问题?
使用第一个“替代”并且没有 os.remove(),它会给出以下错误:_ctypes.COMError: (-2147287038, None, (None, None, None, 0, None))。可能是因为文件仍处于打开状态(pygame)。所以 os.remove() 根本没有必要。更好的选择?
【问题讨论】:
-
按这个顺序(用那些命令),它仍然只第一次起作用,第二次,它不能删除它。 pygame.mixer.music.stop() pygame.mixer.stop() pygame.mixer.quit() pygame.quit()
-
此文件由
voice.create_recordingco 创建,可能需要类似于voice.close()的内容 -
我试过不播放文件(只是创建它然后删除它),它工作得很好。问题似乎出在我播放文件时。它仍然是第二次打开(我不知道为什么)然后脚本无法删除它。
-
我找到了一种使用 with 语句关闭文件的方法:with open("say.wav") as say_wav_read: say_wav= mmap.mmap(say_wav_read.fileno(), 0, access=mmap. ACCESS_READ) 然后 pygame 加载并播放文件。最后: pygame.quit() say_wav.close() os.remove("say.wav") 可以,但是有一个问题,就是有时候会卡住,循环句子的同一部分(例如:你好,你好吗 -> 你好/你好/你好/你好/ ...)永远。可能不应该……你知道为什么会这样吗?或者也许是更好的选择?
标签: python python-3.x audio pygame text-to-speech