I want to make WAVE files by using gTTS module.
I downloaded gTTS module from https://pypi.python.org/pypi/gTTS`
I could make some files by it and stream the sounds by clicking these files.
But I want to know what kind of files can gTTS save?
Here is the sample code:
import tempfile
from gtts import gTTS
tts = gTTS(text='hello', lang='en', slow=True)
tts.save("hello.wav")
f = tempfile.TemporaryFile()
tts.write_to_fp(f)
f.close()
When I used the soundfile with my code, I couldn't make it.
from PySide import QtGui
from PySide import QtCore
import sys
import os
class HelloSpeaker(QtGui.QPushButton):
def __init__(self,parent=None):
super(HelloSpeaker,self).__init__(parent=None)
self.setText("Stream")
self.connect(self,QtCore.SIGNAL("clicked()"),self.play_sound)
def play_sound(self):
sound = QtGui.QSound(os.getcwd()+"hello.wav")
sound.play(os.getcwd()+"hello.wav")
def main():
try:
QtGui.QApplication([])
except Exception as e:
print(28,e)
hello = HelloSpeaker()
hello.show()
sys.exit(QtGui.QApplication.exec_())
if __name__ == "__main__":
main()
Yes, I found out some QSound-questions in stack overflow.
QSound don't work because of some unknown reasons.
For example:
QSound::play("soundpath") call works but a QSound object doesn't
Playing sound with Pyqt4 and QSound
QT5 QSound does not play all wave files
Other persons are bothered.
But I don't ascribed to QSound and I doubt that gTTS can't make .wav files.
because
import wave
wf = wave.open("hello.wav", "rb")
result:
wave.Error: file does not start with RIFF id
I heard this error shows this file is not a wave file.
So I wonder that gTTS don't make ".wav" files.
(But I can play it by ITunes , other players.)
Can gTTS make "mp3" files only?
environment:
python 3.6.3 pyside1.2.4
gTTS only saves the bytes directly without doing any conversion, and these bytes are encoded in mp3, you can verify it by checking the source code:
....
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=InsecureRequestWarning)
r = requests.get(self.GOOGLE_TTS_URL,
params=payload,
headers=headers,
proxies=urllib.request.getproxies(),
verify=False)
if self.debug:
print("Headers: {}".format(r.request.headers))
print("Request url: {}".format(r.request.url))
print("Response: {}, Redirects: {}".format(r.status_code, r.history))
r.raise_for_status()
for chunk in r.iter_content(chunk_size=1024): # write the bytes directly
fp.write(chunk)
...
Related
Our script which uses the following libraries
import os
import sys
from random import sample as rand_sample
import PySimpleGUI as sg
from gtts import gTTS
from Levenshtein import ratio
from cryptography.fernet import Fernet
import platform
import webbrowser
from hashlib import sha1
from getpass import getuser
from socket import gethostname
import clipboard
import wavio
import sounddevice as sd
import soundfile as sf
import speech_recognition as sr
import wave
from playsound import playsound
from difflib import get_close_matches
import json
import urllib.request
from ssl import _create_unverified_context
class audio():
def __init__(mic,path):
mic.fs=44100
mic.path=path
def recordAudio(mic,time):
recording=sd.rec(int(time*mic.fs),samplerate=mic.fs,channels=1)
sd.wait()
return recording
def save(mic,filename,recording):
wavio.write(mic.path+filename,recording, mic.fs, sampwidth=2)
def play(mic,filename):
data,fs = sf.read(mic.path+filename,dtype='float32')
sd.play(data,fs)
status=sd.wait()
def getText(mic,filename): #use google speech recongition to convert
# print (mic,filename)
r = sr.Recognizer()
hellow=sr.AudioFile(mic.path+filename)
with hellow as source:
r.adjust_for_ambient_noise(source, duration = 1)
audio = r.record(source)
try:
s = r.recognize_google(audio)
return(s)
except:
return ('error reading speech...')
return ""
Can access microphone when run the app bundle via terminal (Permission is granted for it screenshot attached)
however when we package it using pyinstaller using this command
pyinstaller --noupx --onedir --onefile --windowed interview.spec interview.py
It is successfully converted into an app and we can launch it with double click. But it cannot access micriphone, nor does it asks for permission. Do we have to add some specific python snippet to ask for permission? Looking forward to your suggestions and help as i am clueless in this.
System:
macOS Big Sur
Version 11.5.2
In the end just ended up writing a script and putting an icon on it, so user can double click on it and start using the app. Though in Big Sur you have to do chmod 755 to it in almost every new pc it is copied to.
#!/bin/bash
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
cd "${DIR}"
./interview.app/Contents/MacOS/interview
I'm trying to read a .txt file using Google's text-to-speech API. But, when I try to run it, it gives an error that I can't quite fathom. So your help will be greatly appreciated!
My Python code:
#Import the required module for text
from gtts import gTTS
#required to play the converted file
import os
#The file you want to convert
with open('/Users/humma/Desktop/python_projects/flowers.txt', 'r') as myFile:
fileRead = myFile.read()
#passing file and language to the engine
myObj = gTTS(text = fileRead, lang = 'en-US', slow = False)
myObj.save('flowers.mp3')
os.system("flowers.mp3")
The error I get:
File "c:/Users/humma/Desktop/python_projects/txt-to-speech/txt-to-spch.py", line 12, in <module>
myObj.save('flowers.mp3')
File "C:\ProgramData\Anaconda3\lib\site-packages\gtts\tts.py", line 312, in save
self.write_to_fp(f)
File "C:\ProgramData\Anaconda3\lib\site-packages\gtts\tts.py", line 294, in write_to_fp
raise gTTSError(tts=self, response=r)
gtts.tts.gTTSError: 200 (OK) from TTS API. Probable cause: Unknown
Thank you in advance for your time :)
from gtts import gTTS
from io import BytesIO
from pygame import mixer
import time
def speak():
mp3_fp = BytesIO()
tts = gTTS('You need to read documetation properly', lang='en')
tts.write_to_fp(mp3_fp)
tts.save("Audio.mp3")
return mp3_fp
mixer.init()
sound = speak()
sound.seek(0)
mixer.music.load(sound, "mp3")
mixer.music.play()
It was lang = 'en-US' that caused the error. It's simply: lang = 'en'
I have a lot of text-to-speech audio files that I need to save but often, the files get lost.
Currently I'm using
import gtts
from playsound import playsound
def say(speech):
tts = gtts.gTTS(speech)
tts.save("audio.mp3")
playsound("audio.mp3")
Is there any way that I can save the mp3 to wherever I desire?
You can just paste content of new audio file into another file like below:
import gtts
from playsound import playsound
def say(speech):
tts = gtts.gTTS(speech)
tts.save("audio.mp3")
playsound("audio.mp3")
# PLACE CONTENT INTO NEW FILE => S T A R T
main_file = open("audio.mp3", "rb").read()
dest_file = open('path/to_your/file_name.mp3', 'wb+')
dest_file.write(main_file)
dest_file.close()
# PLACE CONTENT INTO NEW FILE => E N D
or
import gtts
from playsound import playsound
import shutil
def say(speech):
tts = gtts.gTTS(speech)
tts.save("audio.mp3")
playsound("audio.mp3")
# PLACE CONTENT INTO NEW FILE => S T A R T
shutil.move("audio.mp3", "path/to_your/file_name.mp3")
# PLACE CONTENT INTO NEW FILE => E N D
You can just put the directory you need in the brackets when you save tts as mp3 file:
tts.save("directory/that/you/want/audio.mp3")
I did like this: s.save("your folder name/audio.mp3")
I am getting an error when writing to an audio file.
Basically, I am overwriting the data in the mp3 whenever my function gets called and then playing it.
It works the first time through, but then gives me [Errno 13] Permission denied: 'file.mp3' then on.
Here is the code:
def speech(self, response):
audio_file = "response.mp3"
tts = gTTS(text=str(response), lang="en")
tts.save(audio_file)
pygame.mixer.init()
pygame.mixer.music.load(audio_file)
pygame.mixer.music.play()
Error is on the tts.save line.
More info:
Traceback (most recent call last):
File "myprojectpath", line 63, in speech
tts.save(audio_file)
File "C:\Python35\lib\site-packages\gtts\tts.py", line 93, in save
with open(savefile, 'wb') as f:
Thanks!
from gtts import gTTS
import playsound
import os
x = ['sunny', 'sagar', 'akhil']
tts = 'tts'
for i in range(0,3):
tts = gTTS(text= x[i], lang = 'en')
file1 = str("hello" + str(i) + ".mp3")
tts.save(file1)
playsound.playsound(file1,True)
print 'after'
os.remove(file1)
change the file name every time you save it, this worked for me.
You should name your file for a unique name each time , so the solution that I realized is to name your file with date like this ==>
date_string = datetime.now().strftime("%d%m%Y%H%M%S")
filename = "voice"+date_string+".mp3"
tts.save(filename)
playsound.playsound(filename)
You can create another file in the same folder, just copy and rename it.
File you want to use: ("C:/.../file.mp3")
copied file: ("C:/.../file_copy.mp3")
You can change the file loaded in mixer.music.load("C:/.../file.mp3") to mixer.music.load("C:/.../file_copy.mp3") and delete delete the ("C:/.../file.mp3") without problem using this:
from pygame import mixer
import os
mixer.music.load("C:/.../file.mp3")
mixer.music.play()
mixer.music.load("C:/.../file_copy.mp3")
os.remove("C:/.../file.mp3")
but the code above will remove the file before even playing it, so you can use a method to await it play:
from pygame import mixer
import os
mixer.music.load("C:/.../file.mp3")
mixer.music.play()
while mixer.music.get_busy(): # check if the file is playing
pass
mixer.music.load("C:/.../file_copy.mp3")
os.remove("C:/.../file.mp3")
try to save the fi open an other file whitout playing, then you will have the permission to delete it here is the talk function:
def Talk (mytext, language= "fr" ):
myobj = gTTS(text=mytext, lang=language, slow=False)
myobj.save("1.mp3")
mixer.init()
mixer.music.load("1.mp3")
mixer.music.set_volume(1)
mixer.music.play()
mixer.music.get_endevent()
while mixer.music.get_busy():
continue
mixer.music.load("Talker\empty.mp3")
os.remove("1.mp3")
You are getting this error because the mixer is not releasing that audio file. If you want to mixer release that file you can load a useless or empty file into a mixer. Then you can overwrite that audio file.
E. g.. Mixer.load("C:/...../empty.mp3")
After this previously loaded file is released.
if you don't want the file before saved anymore, you can delete the audio file before saving the next file. so, you can save the new file with the same name.
bellow is the code I ran successfully
import speech_recognition as ram
from playsound import playsound
from gtts import gTTS
import os
r=ram.Recognizer()
with ram.Microphone() as source:
while True:
r.adjust_for_ambient_noise(source,duration=1)
print("I'm Listening....")
playsound('audio/listen.mp3')
audio=r.listen(source, timeout=5)
text=r.recognize_google(audio)
tts = gTTS("Boss. you said "+str(text)+". i'm opening it")
tts.save('audio/text.mp3')
print("you said "+text+".")
playsound('audio/text.mp3')
os.remove('audio/text.mp3')
a much better solution is this, if i had the time i would also calculate the probability of ever landing a same file
from gtts import gTTS
from playsound import playsound
import random
import os
#creating a super random named file
r1 = random.randint(1,10000000)
r2 = random.randint(1,10000000)
randfile = str(r2)+"randomtext"+str(r1) +".mp3"
tts = gTTS(text='hey, STOP It!!', lang='en', slow=True)
tts.save(randfile)
playsound(randfile)
print(randfile)
os.remove(randfile)
I have faced the same problem, then figure it out that the file is pointing to the previous position so I have to release it. It works fine and important thing is that it does not create an mp3 file also. If you don't release it, it will work fine for the first time and save the audio file then the error occurs for the second time.
from gtts import gTTS
import os
import playsound
def tts(text, lang):
file = gTTS(text = text, lang = lang)
file.save("audio/speak_func.mp3")
playsound.playsound('audio/speak_func.mp3', True)
os.remove("audio/speak_func.mp3")
Basically what i want is TTS in python 3...
I already tried pyttsx but aparently it only works with python 2
I already tried other things too...
Now i'm trying with the api from voicerss.org but i can't figure out how can HTTP GET it and then play it with python with pyglet...
here is my code so far:
import pyglet
import urllib3
http = urllib3.PoolManager()
speechrequest = http.request('GET', 'http://api.voicerss.org/?key=04f49802d32d442ca997d4d2ea76d3d5&hl=pt-pt&c=wav&src=texto')
speech = pyglet.media.load(speechrequest)
speech.play()
pyglet.app.run()
The errors are:
Traceback (most recent call last):
File "C:/Users/Diogo/Documents/test.py", line 6, in <module>
speech = pyglet.media.load(speechrequest)
File "C:\Users\Diogo\AppData\Local\Programs\Python\Python35\lib\site-packages\pyglet\media\__init__.py", line 1429, in load
source = get_source_loader().load(filename, file)
File "C:\Users\Diogo\AppData\Local\Programs\Python\Python35\lib\site-packages\pyglet\media\__init__.py", line 1410, in load
return riff.WaveSource(filename, file)
File "C:\Users\Diogo\AppData\Local\Programs\Python\Python35\lib\site-packages\pyglet\media\riff.py", line 185, in __init__
file = open(filename, 'rb')
TypeError: invalid file: <urllib3.response.HTTPResponse object at 0x0000002EB0730D30>
i guess its not returning an wav file to python don't know why because. If i enter 'http://api.voicerss.org/?key=04f49802d32d442ca997d4d2ea76d3d5&hl=pt-pt&c=wav&src=texto' in internet explorer it returns a wav file...
So, my questions are:
what i am doing wrong with the code or if is impossible this way how can python speak?
Please be patient with me, i'm only 18 years old and i can't speak english properly, because i'm portuguese...
You could save the remote wav file locally and play it using a default application:
#!/usr/bin/env python3
from urllib.request import urlretrieve
import webbrowser
filename = 'speech.wav'
urlretrieve("http://api.voicerss.org/?key=04f49802d32d442ca997d4d2ea76d3d5"
"&hl=pt-pt&c=wav&src=texto", filename)
webbrowser.open(filename) # play the file using default application
On Windows, you could use os.startfile() instead of webbrowser.open() or to play the wav file directly in Python without an external application:
import winsound
winsound.PlaySound('speech.wav', winsound.SND_FILENAME)
Your code have at least two issues:
You should pass a filename (a string) to pyglet.media.load() function, not an HTTPResponse object.
pyglet may fail to play it anyway: I get pyglet.media.riff.RIFFFormatException: Size of format chunk is incorrect. error on my system.
You could also play a remote wav file without saving it to disk i.e., you can play streaming content:
#!/usr/bin/env python3
from urllib.parse import quote
from urllib.request import urlopen
api_key = open('api.key', encoding='ascii').read().strip()
language = 'pt-pt'
text = quote("1 2 3")
playwav(urlopen('https://api.voicerss.org/?c=wav&f=8khz_8bit_mono&ssml=false&'
'key={api_key}&src={text}&hl={language}'.format(**vars())))
where playwav():
import wave
from contextlib import closing
import pyaudio # Windows: py -m pip install pyaudio
# $ sudo apt-get install python{,3}-pyaudio
player = None
def playwav(path_or_file):
global player
if player is None:
player = pyaudio.PyAudio()
with closing(wave.open(path_or_file, 'rb')) as wavfile, \
closing(player.open(
format=player.get_format_from_width(wavfile.getsampwidth()),
channels=wavfile.getnchannels(),
rate=wavfile.getframerate(),
output=True)) as stream:
while True:
data = wavfile.readframes(1024) # read 1024 frames at once
if not data: # EOF
break
stream.write(data)