I am retrieving the sound from:
http://translate.google.com/translate_tts
and writing it to a WAV file, when i double-click the file the sound plays ok, but when i use the WAVE module from python to open it, it gives me this error:
wave.Error: file does not start with RIFF id
I want to know if there is a way for openning this file, or if it is possible to play the sound without writing it before.
Here is the relevant code:
url = "http://translate.google.com/translate_tts?tl=%s&q=%s" % (lang, text)
hrs = {"User-Agent":
"Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"}
request = urllib.request.Request(url, headers = hrs)
page = urllib.request.urlopen(request)
fname = "Play"+str(int(time.time()))+".wav"
file = open(fname, 'wb')
file.write(page.read())
file.close()
And the code that reads this file is:
INPUT_FRAMES_PER_BLOCK = 1024
wf = wave.open(fname, 'r')
pa = pyaudio.PyAudio()
stream = pa.open(format=pa.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(INPUT_FRAMES_PER_BLOCK)
while data != '':
stream.write(data)
data = wf.readframes(INPUT_FRAMES_PER_BLOCK)
stream.stop_stream()
stream.close()
pa.terminate()
Thanks in advance!
I am using Python 3 BTW.
You have this error because you're trying to play a file that isn't a WAV.
The sound generated by Google Translate is encoded as an MP3.
As for how to play an MP3 sound with Python, I'd recommend you read this StackOverflow question.
(Basically you have to install some library like Pyglet)
Alternatively, if you want a wav file, you could install something to convert it to a wav file. Pymedia is a good module for that. The pymedia version made for current versions of python could be difficult to find, however, I have found a good place to get it at: http://www.lfd.uci.edu/~gohlke/pythonlibs/#pymedia
Here is a function that will convert the mp3 file to a wav file, and save a wav file in your file system:
def dumpWAV( name ):
import pymedia.audio.acodec as acodec
import pymedia.muxer as muxer
import time, wave, string, os
name1= str.split( name, '.' )
name2= string.join( name1[ : len( name1 )- 1 ] )
# Open demuxer first
dm= muxer.Demuxer( name1[ -1 ].lower() )
dec= None
f= open( name, 'rb' )
snd= None
s= " "
while len( s ):
s= f.read( 20000 )
if len( s ):
frames= dm.parse( s )
for fr in frames:
if dec== None:
# Open decoder
dec= acodec.Decoder( dm.streams[ 0 ] )
r= dec.decode( fr[ 1 ] )
if r and r.data:
if snd== None:
snd= wave.open( name2+ '.wav', 'wb' )
snd.setparams( (r.channels, 2, r.sample_rate, 0, 'NONE','') )
snd.writeframes( r.data )
You may want to just play the mp3, but it is significantly easier to play a wav file in python. For example, pygame's support of mp3 files is limited, but it can always play a wav file.
Related
I'm currently working on a project where I request a phone call (Mp3) and have to make an automatic transcript through a python script.
I'm using the Azure Speech to text services and got that all working, but that service only supports a Wav. file and I am still stuck at that part.
import azure.cognitiveservices.speech as speechsdk
import time
from os import path
from pydub import AudioSegment
import requests
import hashlib
OID = ***
string = f"***"
encoded = string.encode()
result = hashlib.sha256(encoded)
resultHash = (result.hexdigest())
r = requests.get(f"***", headers={f"***":f"{***}"})
Telefoongesprek = r
# converts audio file (mp3 to Wav.)
#src = Telefoongesprek
#dst = "Telefoongesprek #****.wav"
#sound = AudioSegment.from_mp3(src)
#sound.export(dst, format="wav")
def speech_recognize_continuous_from_file():
speech_config = speechsdk.SpeechConfig(subscription="***", region="***")
speech_config.speech_recognition_language = "nl-NL"
audio_config = speechsdk.audio.AudioConfig(filename="Telefoongesprek #****.wav")
speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_config)
done = False
def stop_cb(evt):
print('CLOSING on {}'.format(evt))
nonlocal done
done = True
all_results = []
def handle_final_result(evt):
all_results.append(evt.result.text)
#speech_recognizer.recognizing.connect(handle_final_result)
speech_recognizer.recognized.connect(handle_final_result)
speech_recognizer.session_started.connect(handle_final_result)
speech_recognizer.session_stopped.connect(handle_final_result)
speech_recognizer.canceled.connect(handle_final_result)
speech_recognizer.session_stopped.connect(stop_cb)
speech_recognizer.canceled.connect(stop_cb)
speech_recognizer.start_continuous_recognition()
while not done:
time.sleep(.5)
speech_recognizer.stop_continuous_recognition()
print(all_results)
speech_recognize_continuous_from_file()
Thats the code im using without all the keys and encryption, and everthing works apart from the convert from MP3 to Wav.
is there any way I can save the requested file locally in this script and pass it through in:
audio_config = speechsdk.audio.AudioConfig(filename="Telefoongesprek #****.wav"). or do I have to save it to the pc and do it another way.
I have been stuck on this problem for over a week and have tried many different ways.
Thanks in advance!
Beau van der Meer
You should be able to save the response data ( you can access the raw bytes with r.content) to a .mp3 file locally and then pass that file path to pydub.
with open('path/to/local/file.mp3', 'wb') as f:
f.write(r.content)
Another option is to use the module io.BytesIO from the standard library.
If you pass it raw bytes, e g import io; f = io.BytesIO(r.content), it will give you a object that behaves like an open filehandle back, which you can pass to functions accepting files. I didn't check that pydub method you are trying to use accepts filehandles or only paths, so you have to check that first.
I'm trying to write a python script that will play mp3 from Soundcloud URL
This is what I've already done:
from urllib.request import urlopen
url = "soundcloud.com/artist/song.mp3"
u = urlopen(url)
data = u.read(1024)
while data:
player.play(data)
data = u.read(1024)
I tried pyaudio with many options like changing formats, channels, rate.
and I just get strange sound from the speakers, I searched Google for pyaudio playing mp3 and didn't found any information.
I tried pygame by creating Sound object by passing the bytes from the mp3 and then just by executing the play function. I am not getting any errors: the script runs but nothing is playing.
I'm working with Python 3 and Ubuntu.
If you happen to have VLC installed (or are willing to install it), then this should work:
import vlc
p = vlc.MediaPlayer("http://your_mp3_url")
p.play()
This has the advantage that it works with everything VLC works with, not just MP3. It can also be paused if you want to.
You can install vlc for python using
pip install python-vlc
Check if you can download file manually using that URL. If its protected site with username/passwd, you may need to take care of that first.
If not, here is a working code that downloads file from url using urllib2 and then plays it using pydub.
Its a two step process where first mp3 file is downloaded and saved to file and then played using external player.
import urllib2
from pydub import AudioSegment
from pydub.playback import play
mp3file = urllib2.urlopen("http://www.bensound.org/bensound-music/bensound-dubstep.mp3")
with open('./test.mp3','wb') as output:
output.write(mp3file.read())
song = AudioSegment.from_mp3("./test.mp3")
play(song)
** Update **
You did mention that you need streaming from web. In that case you may want to look at GStreamer with Python Bindings
Here is a SO link for that.
Sorry but I do not have Python3 to test here, to stream mp3 using pyaudio you will need decode it in PCM data, I know that pymedia can do it, but it is too old and just support python27.
To do this the right way you will need to know some attributes of your audio, things like samplerate, number of channels, bit resolution, to set it in the pyaudio.
I can show how I do it using python27 + pyaudio, first I will show how it is done to stream .wav
from urllib2 import urlopen
#to python3.x
#from urllib.request import urlopen
import pyaudio
pyaud = pyaudio.PyAudio()
srate=44100
stream = pyaud.open(format = pyaud.get_format_from_width(1),
channels = 1,
rate = srate,
output = True)
url = "http://download.wavetlan.com/SVV/Media/HTTP/WAV/NeroSoundTrax/NeroSoundTrax_test4_PCM_Mono_VBR_8SS_44100Hz.wav"
u = urlopen(url)
data = u.read(8192)
while data:
stream.write(data)
data = u.read(8192)
choose large buffer, python is slow in while loop, i did it using chunks of size 8192, note that format, channels and rate are the rigth attributes for this wav file, so for .wav we not need decode, it is a PCM data, now for mp3 we will need decode and put in PCM format to stream.
Lets try using pymedia
from urllib2 import urlopen
import pyaudio
import pymedia.audio.acodec as acodec
import pymedia.muxer as muxer
dm= muxer.Demuxer( 'mp3' )
pyaud = pyaudio.PyAudio()
srate=44100
stream = pyaud.open(format = pyaud.get_format_from_width(2),
channels = 1,
rate = srate,
output = True)
url = "http://www.bensound.org/bensound-music/bensound-dubstep.mp3"
u = urlopen(url)
data = u.read(8192)
while data:
#Start Decode using pymedia
dec= None
s= " "
sinal=[]
while len( s ):
s= data
if len( s ):
frames= dm.parse( s )
for fr in frames:
if dec== None:
# Open decoder
dec= acodec.Decoder( dm.streams[ 0 ] )
r= dec.decode( fr[ 1 ] )
if r and r.data:
din = r.data;
s=""
#decode ended
stream.write(din)
data = u.read(8192)
This may be secret, because I never saw anyone showing how this can be done in python, for python3 I not know anything that can decode .mp3 into pieces like pymedia do.
Here these two codes are streming and working for .wav and .mp3
I am trying to generate a wav file with G. 711 alaw companding from a mp3 file using Pydub library. The wav file is getting generated but it is not resampled to frequency 8 kHz. I have tried following code:
from_path = '/home/nikhil/Music/m1.mp3' #this is a mp3 file
to_path = '/home/nikhil/Music/m1.wav' #resulted file
from_format = 'mp3'
to_format = 'wav'
params = ["-acodec", "pcm_alaw", "-ar", "8000"]
AudioSegment.from_file(from_path, from_format).export(to_path, format=to_format, parameters=params)
Can someone help me?
I was looking over the code in the export method and I realized that ffmpeg is not used when the output format is "wav".
Since wav is used internally it just writes the in-memory version of the audio directly to disk (this was done to make ffmpeg an optional dependency, if you only need wav support you don't need to install it).
I have 2 ideas that may allow you to get around this issue:
Use a different format kwarg, like "pcm". I'm not sure if this will work, and I don't have ffmpeg on my current machine to test, but definitely worth a try.
from_path = '/home/nikhil/Music/m1.mp3' #this is a mp3 file
to_path = '/home/nikhil/Music/m1.wav' #resulted file
from_format = 'mp3'
to_format = 'pcm'
params = ["-acodec", "pcm_alaw", "-ar", "8000"]
AudioSegment.from_file(from_path, from_format).export(to_path, format=to_format, parameters=params)
Use pydub's internal mechanism for resampling to 8kHz: Again, I can't test this right at the moment...
from_path = '/home/nikhil/Music/m1.mp3' #this is a mp3 file
to_path = '/home/nikhil/Music/m1.wav' #resulted file
seg = AudioSegment.from_mp3(from_path)
seg = seg.set_frame_rate(8000)
seg.export(to_path, format="wav")
import pyaudio
import wave
chunk = 1024
wf = wave.open('yes.mp3', 'rb')
p = pyaudio.PyAudio()
stream = p.open(
format = p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
data = wf.readframes(chunk)
while data != '':
stream.write(data)
data = wf.readframes(chunk)
stream.close()
p.terminate()
No matter how I put this, while trying multiple methods I seem to keep getting the following error in terminal:
raise Error, 'file does not start with RIFF id'
I would use pyglet but media and all other modules aren't detected even though I'm able to import pyglet.
Any help?
You're using wave to attempt to open a file that is not wav. Instead, you're attempting to open an mp3 file. The wave module can only open wav files, so you need to convert the mp3 to wav. Here's how you can use pyglet to play an mp3 file:
import pyglet
music = pyglet.resource.media('music.mp3')
music.play()
pyglet.app.run()
It would be much simpler than the method you're trying. What errors are you getting with pyglet?
So, I've been trying to make a simple downloader that downloads my zip file.
Code looks like this:
import urllib2
import os
import shutil
url = "https://dl.dropbox.com/u/29251693/CreeperCraft.zip"
file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open('c:\CreeperCraft.zip', 'w+')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size)
file_size_dl = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8)*(len(status)+1)
print status,
f.close()
And the problem is, it downloads the file to the correct path, but when I open the file, its damaged, only 1 picture appears and when you click on it, it says File Damaged.
Please help.
f = open('c:\CreeperCraft.zip', 'wb+')
You are using "w+" as flag, Python opens the file in text mode:
Python on Windows makes a distinction between text and binary files;
the end-of-line characters in text files are automatically altered
slightly when data is read or written. This behind-the-scenes
modification to file data is fine for ASCII text files, but it’ll
corrupt binary data like that in JPEG or EXE files.
http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files
Also, note that you should escape the backslash or use raw strings, therefore use open('c:\\CreeperCraft.zip', 'wb+').
I also would recommend that you do not copy raw byte strings by hand, but use shutil.copyfileobj - it makes your code more compact and easier to understand. I also like to use the with statement that automatically cleans up resources (i.e. that closes files:
import urllib2, shutil
url = "https://dl.dropbox.com/u/29251693/CreeperCraft.zip"
with urllib2.urlopen(url) as source, open('c:\CreeperCraft.zip', 'w+b') as target:
shutil.copyfileobj(source, target)
import posixpath
import sys
import urlparse
import urllib
url = "https://dl.dropbox.com/u/29251693/CreeperCraft.zip"
filename = posixpath.basename(urlparse.urlsplit(url).path)
def print_download_status(block_count, block_size, total_size):
sys.stderr.write('\r%10s bytes of %s' % (block_count*block_size, total_size))
filename, headers = urllib.urlretrieve(url, filename, print_download_status)