Error while re-opening sound file in python

2019-07-15 07:16发布

问题:

I was in the process of making a program that simply repeats any text you enter, and seemed to be working when I first tested it. The problem is that the second time I attempt to type anything, it crashes and says that permission was denied to the sound file I was recording it to. I believe it is because the file was already opened, but none the less I do not know how to fix it. I am using the gTTS and Pygame modules.

from gtts import gTTS
from tempfile import TemporaryFile
from pygame import mixer

#Plays Sound
def play():
    mixer.init()
    mixer.music.load("Speech.mp3")
    mixer.music.play()
#Voice
def voice(x):
    text = gTTS(text= x, lang= 'en')
    with open("Speech.mp3", 'wb') as f:
        text.write_to_fp(f)
        f.close()
    play()

#Prompts user to enter text for speech
while True:
    voice_input = input("What should Wellington Say: ")
    voice(voice_input)

回答1:

Figured it out. I added this function:

def delete():
    sleep(2)
    mixer.music.load("Holder.mp3")
    os.remove("Speech.mp3")

And call it after .play(), so it now simply deletes the file when it is done and then re-creates it when you need to use it next.



回答2:

To expand on my comment above (with help from this thread), I think play() may be locking the file. You can manually try the following:

def play():
    mixer.init()
    mixer.music.load("Speech.mp3")
    mixer.music.play()
    while pygame.mixer.music.get_busy(): 
        pygame.time.Clock().tick(10)

or

def play():
    mixer.init()
    mixer.music.load("Speech.mp3")
    mixer.music.play()
    mixer.music.stop()

But this second fix might have the consequence of not hearing anything played back.



回答3:

I fixed the problem by writing to a temporary file and using os.rename:

from gtts import gTTS
from pygame import mixer
import os

play_name = 'Speech.mp3'
save_name = "%s.%s" % (play_name, '.tmp')

def play():
    mixer.music.load(play_name)
    mixer.music.play()

def voice(x):
    text = gTTS(text=x, lang='en')
    with open(save_name, 'wb') as tmp_file:
        text.write_to_fp(tmp_file)
    os.rename(save_name, play_name)

try:
    mixer.init()
    while True:
        voice_input = raw_input("What should Wellington Say: ")
        voice(voice_input)
        play()
except KeyboardInterrupt:
    pass

I ran a test where I typed in a very long sentence and then another sentence while the first one was playing and everything still worked.