gTTS 无法保存文件两次
gTTS unable to save file twice
我正在尝试将 gTTS 用作个人助理项目的真实文本转语音模块。查询 google 服务时,我可以保存 mp3 文件并 运行 使用 pygame.
from pygame import mixer
from gtts import gTTS
def speak(data):
tts = gTTS(text=data, lang='en')
tts.save('speech.mp3')
mixer.init()
mixer.music.load('speech.mp3')
mixer.music.play()
在 运行 函数 "speak" 成功输出后,但是当 运行 再次调用它时它失败并出现错误。
Traceback (most recent call last):
File "C:\Users\user1\Desktop\project_ai\assistant.py", line 7, in <module>
text_to_speech.main('hello')
File "C:\Users\user1\Desktop\project_ai\modules\speech_text_synthesis\text_to_speech.py", line 8, in main
tts.save('speech.mp3') File "C:\Users\user1\AppData\Local\Programs\Python\Python36\lib\site-packages\gtts\tts.py", line 246, in save
with open(savefile, 'wb') as f: PermissionError: [Errno 13] Permission denied: 'speech.mp3'
再次尝试将文本保存到另一个 mp3 时发生错误。因此 pygame 无法播放。我知道我可以简单地更改文件名来保存它,但我不想这样做。我怎样才能做到这一点?
这似乎是 pygame 的一个常见问题,至少我在 SO 上发现了一些关于这个主题的已删除问题。
尝试在保存后通过内存映射文件加载文件,而不是仅使用文件名,如下所示:
import mmap
...
def speak(data):
tts = gTTS(text=data, lang='en')
tts.save('speech.mp3')
with open('speech.mp3') as f:
m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
pygame.mixer.music.load(m)
pygame.mixer.music.play()
m.close()
使用上下文管理器确保文件在复制到内存后实际关闭,并且pygame.mixer.music.load
根本不会触及文件。
终于……成功了……
我已经研究这个问题好几个小时了。除了 PyGame(pyaudio、playsound、pyglet 等)之外,我还尝试了多种不同的声音播放器。我走的路和其他人走的路一样。
然后......它击中了我......一条不同的道路......使用两个文件名。(一种称为双缓冲的技术)。
虽然我没有使用这个特定的代码,但我认为我应该使用您的代码给出答案....
from pygame import mixer
from gtts import gTTS
count = 0
def speak(data):
global count
tts = gTTS(text=data, lang='en')
tts.save(f'speech{count%2}.mp3')
mixer.init()
mixer.music.load(f'speech{count%2}.mp3')
mixer.music.play()
count += 1
之所以有效,是因为TTS库在切换到新文件时会释放之前的文件。我们在尝试使用 1 个文件名时面临的问题是我们很难找到释放文件资源的方法。当您切换到另一个文件名时,此方法会释放它。
享受互联网!去制作一些很酷的程序吧!
我正在尝试将 gTTS 用作个人助理项目的真实文本转语音模块。查询 google 服务时,我可以保存 mp3 文件并 运行 使用 pygame.
from pygame import mixer
from gtts import gTTS
def speak(data):
tts = gTTS(text=data, lang='en')
tts.save('speech.mp3')
mixer.init()
mixer.music.load('speech.mp3')
mixer.music.play()
在 运行 函数 "speak" 成功输出后,但是当 运行 再次调用它时它失败并出现错误。
Traceback (most recent call last):
File "C:\Users\user1\Desktop\project_ai\assistant.py", line 7, in <module>
text_to_speech.main('hello')
File "C:\Users\user1\Desktop\project_ai\modules\speech_text_synthesis\text_to_speech.py", line 8, in main
tts.save('speech.mp3') File "C:\Users\user1\AppData\Local\Programs\Python\Python36\lib\site-packages\gtts\tts.py", line 246, in save
with open(savefile, 'wb') as f: PermissionError: [Errno 13] Permission denied: 'speech.mp3'
再次尝试将文本保存到另一个 mp3 时发生错误。因此 pygame 无法播放。我知道我可以简单地更改文件名来保存它,但我不想这样做。我怎样才能做到这一点?
这似乎是 pygame 的一个常见问题,至少我在 SO 上发现了一些关于这个主题的已删除问题。
尝试在保存后通过内存映射文件加载文件,而不是仅使用文件名,如下所示:
import mmap
...
def speak(data):
tts = gTTS(text=data, lang='en')
tts.save('speech.mp3')
with open('speech.mp3') as f:
m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
pygame.mixer.music.load(m)
pygame.mixer.music.play()
m.close()
使用上下文管理器确保文件在复制到内存后实际关闭,并且pygame.mixer.music.load
根本不会触及文件。
终于……成功了……
我已经研究这个问题好几个小时了。除了 PyGame(pyaudio、playsound、pyglet 等)之外,我还尝试了多种不同的声音播放器。我走的路和其他人走的路一样。
然后......它击中了我......一条不同的道路......使用两个文件名。(一种称为双缓冲的技术)。
虽然我没有使用这个特定的代码,但我认为我应该使用您的代码给出答案....
from pygame import mixer
from gtts import gTTS
count = 0
def speak(data):
global count
tts = gTTS(text=data, lang='en')
tts.save(f'speech{count%2}.mp3')
mixer.init()
mixer.music.load(f'speech{count%2}.mp3')
mixer.music.play()
count += 1
之所以有效,是因为TTS库在切换到新文件时会释放之前的文件。我们在尝试使用 1 个文件名时面临的问题是我们很难找到释放文件资源的方法。当您切换到另一个文件名时,此方法会释放它。
享受互联网!去制作一些很酷的程序吧!