I try to use Baidu Voice Cloud API to implement a desktop service including TTS. MP3 has been successfully retrieved and cached in cStringIO, but I don’t know how to play it. Code playback throws an error.
Refer to the pywave/pyaudio/pyglet and other methods mentioned in http://guzalexander.com/2012/....
code show as below:
#!/usr/bin/env python #encoding=utf-8 #import wave import pyaudio import pyglet import urllib, urllib2, pycurl import base64 import json import cStringIO import binascii ## get access token by api key & secret key def get_token(): apiKey = "xxxxxxxxxx" secretKey = "yyyyyyyyyyyyyyyyyyyyy" auth_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey; res = urllib2.urlopen(auth_url) json_data = res.read() return json.loads(json_data)['access_token'] def dump_res(buf): #print buf pass ## post audio to server def use_cloud(token): fp = wave.open('vad_0.wav', 'rb') nf = fp.getnframes() f_len = nf * 2 audio_data = fp.readframes(nf) cuid = "xxxxxxxxxx" #my xiaomi phone MAC srv_url = 'http://vop.baidu.com/server_api' + '?cuid=' + cuid + '&token=' + token http_header = [ 'Content-Type: audio/pcm; rate=8000', 'Content-Length: %d' % f_len ] c = pycurl.Curl() c.setopt(pycurl.URL, str(srv_url)) #curl doesn't support unicode #c.setopt(c.RETURNTRANSFER, 1) c.setopt(c.HTTPHEADER, http_header) #must be list, not dict c.setopt(c.POST, 1) c.setopt(c.CONNECTTIMEOUT, 30) c.setopt(c.TIMEOUT, 30) c.setopt(c.WRITEFUNCTION, dump_res) c.setopt(c.POSTFIELDS, audio_data) c.setopt(c.POSTFIELDSIZE, f_len) c.perform() #pycurl.perform() has no return val def get_audio(token): cuid = "00030DAF5784" # MAC address text = "从前有座山,山上有个庙,庙里有个老和尚和小和尚,老和尚对小和尚说:" #baidu_url = "http://tsn.baidu.com/text2audio?tex=" + urllib.urlencode(text) + "&lan=zh&cuid=" + cuid + "&ctp=1&tok=" + token baidu_url = "http://tsn.baidu.com/text2audio?tex=" + urllib.quote(text) + "&lan=zh&cuid=" + cuid + "&ctp=1&tok=" + token print("URL:\t{0}".format(baidu_url)) buf = cStringIO.StringIO() c = pycurl.Curl() c.setopt(c.URL, str(baidu_url)) #curl doesn't support unicode #c.setopt(c.HTTPHEADER, http_header) #must be list, not dict #c.setopt(c.GET, 1) c.setopt(c.WRITEFUNCTION, buf.write) c.setopt(c.CONNECTTIMEOUT, 30) c.setopt(c.TIMEOUT, 30) c.setopt(c.WRITEFUNCTION, dump_res) c.perform() #pycurl.perform() has no return val #print "type:\t{0}".format(c.CONTENT_TYPE) print(c.getinfo(c.CONTENT_TYPE)) #print buf.getvalue() song = pyglet.media.load(buf) song.play() buf.close() if __name__ == "__main__": token = get_token() print("token:\t{0}".format(token)) #use_cloud(token) get_audio(token)
The error thrown is as follows:
Traceback (most recent call last): File "C:\BOM_Planner\source\soldering_assistant_mvp.py", line 87, in get_audio(token) File "C:\BOM_Planner\source\soldering_assistant_mvp.py", line 79, in get_audio song = pyglet.media.load(buf) File "C:\Python27\lib\site-packages\pyglet\media\__init__.py", line 1429, in load source = get_source_loader().load(filename, file) File "C:\Python27\lib\site-packages\pyglet\media\__init__.py", line 1410, in load return riff.WaveSource(filename, file) File "C:\Python27\lib\site-packages\pyglet\media\riff.py", line 185, in __init__ file = open(filename, 'rb') TypeError: coercing to Unicode: need string or buffer, cStringIO.StringO found
If you write Python3, pygame is recommended. You can use pygame.mixen.music to play local mp3 files.
At that time, I also searched a lot without success, so I finally used pygame to play it.
This is an example I wrote. You can take a look. I saved the online music to a local mp3 file and then played it. There is relevant information in the readme.
https://github.com/kompasim/p...
If it is a Linux environment, there are many solutions. If you want to achieve cross-platform, it is recommended to use pygame.