Delphi调用百度语音识别服务
简介
百度语音识别通过 REST API 的方式给开发者提供一个通用的 HTTP 接口。 上传需要完整的录音文件,录音文件时长不超过60s。百度语音提供2种识别模型:
- 搜索模型: 效果同手机百度搜索的语音输入。适合于短语识别,没有逗号。
- 输入法模型:效果同百度输入法的语音输入。适合于长句识别,有逗号。
文档地址:http://ai.baidu.com/docs#/ASR-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过期可以重新获取。
语音格式
格式支持:pcm(不压缩)、wav(不压缩,pcm编码)、amr(压缩格式)。推荐pcm 采样率 :16000 固定值。 编码:16bit 位深的单声道。
百度服务端会将非pcm格式,转为pcm格式,因此使用wav、amr会有额外的转换耗时。
请求方式
如果您的音频在本地,需要将音频数据放在body中。(推荐方式) 音频在本地,有JSON和raw两种方式提交。这两种提交方式,均不是浏览器表单的提交
一、json 方式,上传本地文件
- 音频文件,读取二进制内容后, base64 放在speech参数内。
- 音频文件的原始大小, 即二进制内容的字节数,填写“len”字段
由于使用json格式, header为:
Content-Type:application/json
注意 由于base64编码后,数据会增大1/3。
二、raw方式,上传本地文件(本文使用这种方式)
- 音频文件,读取二进制内容后,直接放在body中。
- Content-Length的值即为音频文件的大小。(一般代码会自动生成)。
由于使用raw方式, 采样率和文件格式需要填写在Content-Type中
Content-Type: audio/pcm;rate=16000
识别语言及模型选择
dev_pid | 语言 | 模型 | 是否有标点 | 备注 |
---|---|---|---|---|
1536 | 普通话(支持简单的英文识别) | 搜索模型 | 无标点 | 支持自定义词库 |
1537 | 普通话(纯中文识别) | 输入法模型 | 有标点 | 不支持自定义词库 |
1737 | 英语 | 有标点 | 不支持自定义词库 | |
1637 | 粤语 | 有标点 | 不支持自定义词库 | |
1837 | 四川话 | 有标点 | 不支持自定义词库 | |
1936 | 普通话远场 | 远场模型 | 有标点 | 不支持 |
目前 API 仅支持整段语音识别的模式,即需要上传完整语音文件进行识别。文件大小不超过10M,时长不超过60s。 语音数据上传POST方式有2种:
- 1、JSON格式POST上传本地文件。
- 2、raw格式POST上传本地文件(本文使用这种方式)
正式地址:http://vop.baidu.com/server_api 或 https://vop.baidu.com/server_api
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 sUrl, sLan, cuid, apiKey, secretKey, token, sR: string; response: TStringStream; Stream: TFileStream; tok,re: string; grant_type,client_id,client_secret:string; begin begin if not internetcheckconnection('http://www.baidu.com', 1, 0) then showmessage('联网失败,请先检查网络连接!') else begin cuid := NBGetAdapterAddress(0); 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天后过期 sR := ''; sLan := 'zh';//en zh //x-flac idHttp1.Request.ContentType := 'audio/wav;rate=16000'; token := tok; Stream := TFileStream.Create('e:\16k.wav', fmShareDenyNone); Stream.Position := 0; sUrl := 'http://vop.baidu.com/server_api?lan='+sLan+'&cuid='+ cuid + '&token='+token; response := TStringStream.create('', tencoding.utf8); idHttp1.Post(sUrl, stream, response); re:= response.DataString; if pos('success',re) > 0 then memo1.Lines.Add(GetMidString(re,'result":["',',"]')) end; end; end;