Python - 音频文件未关闭 -> os.remove()

Python - audio file not being closed -> os.remove()

我正在尝试使用来自 Github(来自 DeepHorizo​​ns)的 tts 模块制作一个具有文本到语音功能的程序。因为我希望能够在程序说话时停止程序,所以我正在将音频录制到一个文件中,然后进行播放。为了能够多次创建相同名称的文件 (say.wav),我需要删除旧文件。问题是我无法删除它,因为它正在被使用(PermissionError: [WinError 32] 该进程无法访问该文件,因为它正在被另一个进程使用),但它只发生在它第二次说话时 - 第一次时间,它退出 pygame 并删除文件;第二次,它可能没有退出 pygame,因为它给了我错误。我试过一些库(如 pyaudio 或 pygame),但其中 none 可以在播放后完全关闭音频文件。顺便说一下,我正在使用 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.

我做错了什么?或者谁能​​告诉我更好的方法?

提前致谢。

编辑 -> 我找到了一个 "alternative" 如下:

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 / ...)。有什么办法可以解决这个问题吗?

有第一个 "alternative" 而没有 os.remove(),它给出了这个错误:_ctypes.COMError: (-2147287038, None, (None , None, None, 0, None))。可能是因为文件仍处于打开状态 (pygame)。所以 os.remove() 根本没有必要。更好的选择?

最后我找到了一个类似于我第一个帖子的方法。如果 OP 想要播放的声音不能作为声音而不是音乐播放,我从某个问题的评论中读到一个问题。我在 Pygame 文档中搜索了一个名为 Sound 的模块(顺便说一句,它只适用于 OGG 和未压缩的 WAV 文件)。我用过它,现在它成功关闭了文件(不知道为什么)并且它不会循环播放正在说的内容。在文档中,他们说音乐是流式传输的,不会一次加载。我注意到,当我命令程序停止说话时,错误开始了(可能是某些损坏,我不知道),所以我认为这是导致循环的问题。它没有关闭的原因,我不知道,但它现在关闭了,没有循环,所以现在它工作得很好!最终代码是这样的:

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)
    sound=pygame.mixer.Sound("say.wav")
    sound.play()
    while pygame.mixer.get_busy() == True and stop=="false":
        commands_read=open(directory+"/commands.txt","r")
        lines3=commands_read.read().splitlines()
        stop=lines3[0][14:]
    else:
        sound.stop()
        pygame.quit()