Delphi使用百度语音合成服务
简介
百度语音合成服务,基于HTTP请求的REST API接口,将文本转换为可以播放的音频文件。
合成的文件格式为 mp3,pcm(8k及16k),wav(16k),具体见aue参数
- 多音字可以通过标注自行定义发音。格式如:重(chong2)报集团。
- 目前只有中英文混合这一种语言,优先中文发音。示例: " I bought 3 books” 发音 “three”; “ 3 books are bought” 发音 “三”; “我们买了 3 books” 发音“三”
文档地址:http://ai.baidu.com/docs#/TTS-API/top
调用流程
创建应用
- 1、登录百度云服务平台,没有账号请先自行注册https://cloud.baidu.com/
- 2、在产品服务——人工智能——百度语音 下创建一个应用,输入应用名称和应用描述,点击创建应用。创建成功后点击查看应用详情。会生成API Key和Secret Key
获取token
function Getaccess_token(grant_type,client_id,client_secret:string):string; //获取token var idhttp2:Tidhttp; authHost:string; tokSl:Tstringlist; begin authHost:= 'http://aip.baidubce.com/oauth/2.0/token'; try tokSl:=Tstringlist.Create; idhttp2:=Tidhttp.Create(nil); toksl.Add('grant_type=' + grant_type); toksl.Add('client_id=' + client_id); toksl.Add('client_secret=' + client_secret); Result:=idhttp2.Post(authHost,toksl); finally toksl.Free; idhttp2.DisposeOf; end; end;
可得到如下结果
{ "access_token": "1.a6b7dbd428f731035f771b8d********.86400.1292922000-2346678-124328", "expires_in": 2592000, "refresh_token": "2.385d55f8615fdfd9edb7c4b********.604800.1293440400-2346678-124328", "scope": "public audio_tts_post ...", "session_key": "ANXxSNjwQDugf8615Onqeik********CdlLxn", "session_secret": "248APxvxjCZ0VEC********aK4oZExMB", }
scope中含有audio_tts_post 表示有语音合成能力,没有该audio_tts_post 的token调用接口会返回502错误。 在结果中可以看见 token = 1.a6b7dbd428f731035f771b8d********.86400.1292922000-2346678-124328,在2592000秒(30天)后过期。
响应数据包如下所示,其中 “access_token” 字段即为请求 REST API 所需的令牌, 默认情况下,Access Token 有效期为30天,开发者需要对 Access Token的有效性进行判断,如果Access Token过期可以重新获取。
请求方式及参数基本说明
语音合成接口支持 POST 和 GET两种方式, 推荐POST方式请求。 正式地址:http://tsn.baidu.com/text2audio 或 https://tsn.baidu.com/text2audio
- 1、POST 方式(推荐), 文本小于2048个中文字或者英文数字。
- 2、GET 方式,拼接后的url总长度不多于1000个字符,不推荐长文本合成使用。
请求方式和参数
参数 | 可需 | 描述 |
---|---|---|
tex | 必填 | 合成的文本,使用UTF-8编码。小于2048个中文字或者英文数字。(文本在百度服务器内转换为GBK后,长度必须小于4096字节) |
tok | 必填 | 开放平台获取到的开发者access_token(见上面的“鉴权认证机制”段落) |
cuid | 必填 | 用户唯一标识,用来计算UV值。建议填写能区分用户的机器 MAC 地址或 IMEI 码,长度为60字符以内 |
ctp | 必填 | 客户端类型选择,web端填写固定值1 |
lan | 必填 | 固定值zh。语言选择,目前只有中英文混合模式,填写固定值zh |
spd | 选填 | 语速,取值0-15,默认为5中语速 |
pit | 选填 | 音调,取值0-15,默认为5中语调 |
vol | 选填 | 音量,取值0-15,默认为5中音量 |
per | 选填 | 发音人选择, 0为普通女声,1为普通男生,3为情感合成-度逍遥,4为情感合成-度丫丫,默认为普通女声 |
aue | 选填 | 3为mp3格式(默认); 4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k); 注意aue=4或者6是语音识别要求的格式,但是音频内容不是语音识别要求的自然人发音,所以识别效果会受影响。 |
function GetMidString(s: string; d: string; c: string): string; // 取字符串中间 var i, n: Integer; begin try i := pos(d, s); n := pos(c, copy(s, i + 1, Length(s) - i)); Result := copy(s, i + Length(d), n - Length(d)); except Result := ''; end; end; function NBGetAdapterAddress(ID: integer): String; //用于得到一个cuid用户唯一标识 Var NC: TNCB; ADAPTE: TADAPTERSTATUS; LANAENU: TLANAENUM; intId: integer; cR: AnsiChar; strTem: String; Begin Result := ''; Try ZeroMemory(@NC, SizeOf(NC)); NC.ncb_command := Chr(NCBENUM); cR := NetBios(@NC); // Reissue enum command NC.ncb_buffer := @LANAENU; NC.ncb_length := SizeOf(LANAENU); cR := NetBios(@NC); If Ord(cR) <> 0 Then exit; ZeroMemory(@NC, SizeOf(NC)); NC.ncb_command := Chr(NCBRESET); NC.ncb_lana_num := LANAENU.lana[ID]; cR := NetBios(@NC); If Ord(cR) <> 0 Then exit; ZeroMemory(@NC, SizeOf(NC)); NC.ncb_command := Chr(NCBASTAT); NC.ncb_lana_num := LANAENU.lana[ID]; StrPCopy(NC.ncb_callname, '*'); NC.ncb_buffer := @ADAPTE; NC.ncb_length := SizeOf(ADAPTE); cR := NetBios(@NC); strTem := ''; For intId := 0 To 5 Do strTem := strTem + InttoHex(integer(ADAPTE.adapter_address[intId]), 2); Result := strTem; except Result := 'Error'; End; end; procedure TForm2.Button1Click(Sender: TObject);//具体调用 var str1, str3, str4: string; str2: string; res: Tmemorystream; authHost:string; tokSl:Tstringlist; tex, tok, cuid: string; spd, pit, vol, per: string; grant_type,client_id,client_secret:string; begin if Memo1.Text = '' then showmessage('请先输入要转换的文字!') else if Edit1.Text = '' then showmessage('请先选择语音保存地址!') else begin if not internetcheckconnection('http://www.baidu.com', 1, 0) then showmessage('联网失败,请先检查网络连接!') else if Length(Memo1.Text) > 512 then showmessage('一次转换文字不要超过512个文字,否则可能出错!') else begin cuid := NBGetAdapterAddress(0); spd := ComboBox1.Text; pit := ComboBox2.Text; vol := ComboBox3.Text; per := inttostr(ComboBox4.ItemIndex); Filename := FormatDateTime('yyyy年mm月dd日 hh时nn分ss秒', now()) + '转换语音.mp3'; grant_type:='client_credentials';//grant_type: 必须参数,固定为client_credentials client_id:='你的应用的API Key';//必须参数,应用的API Key client_secret:='你的应用的Secret Key';//必须参数,应用的Secret Key tok :=GetMidString(Getaccess_token(grant_type,client_id,client_secret),'access_token":"','",'); //如果直接使用,注意token会在30天后过期 res := Tmemorystream.Create; IdHTTP1.Response.ContentType := 'Content-Type:audio/mp3'; IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded'; str := ('http://tsn.baidu.com/text2audio?tex=' + Memo1.Text + '&lan=zh&cuid=' + cuid + '&ctp=1&tok=' + tok + '&spd=' + spd + '&pit=' + pit + '&vol=' + vol + '&per=' + per); IdHTTP1.Get(Tiduri.UrlEncode(UTF8Encode(str)), res); //POST 方式(推荐), 文本小于2048个中文字或者英文数字。GET 方式,拼接后的url总长度不多于1000个字符,不推荐长文本合成使用。 res.SaveToFile(Edit1.Text + Filename); //如果不需要保存到本地,上边可以不用下载下来,下边的直接改成MediaPlayer1.Filename := Tiduri.UrlEncode(UTF8Encode(str)) + '.mp3'; MediaPlayer1.DeviceType :=dtAutoSelect; if (MediaPlayer1.DeviceID <> 0) then begin if (MediaPlayer1.Mode = mpplaying) then MediaPlayer1.Stop; end; MediaPlayer1.Enabled := true; MediaPlayer1.Filename := Edit1.Text + Filename; MediaPlayer1.Open; MediaPlayer1.Play; end; end; end;