功能:发一段音频给百度,百度返回一段文字给你。
结果图:
语音识别一般分在线和离线两种。本文说的是在线过程。录制一段音频文件->baidu,baidu ->返回一段文字给你。
1.注册账户
2.录制音频文件
3.发送http请求
4.解析json数据
1.百度注册账户+创建应用+API文档
https://console.bce.baidu.com/ai/#/ai/speech/overview/index
https://cloud.baidu.com/doc/SPEECH/s/ek38lxj1u
请AK和SK请自行注册
const QString baiduSpeechTokenUrl = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2";
const QString speech_client_AK= "yLnualRuHnCcZDi2B3wEZ1rs";
const QString speech_client_SK= "LA55muGIGSWZPBkcQWnjA9AmlKeSRGLA";
const QString BaiduSpeechVideoUrl = "https://vop.baidu.com/pro_api?dev_pid=1537&cuid=%1&token=%2";
2.录制音频文件
1.一般支持的音频格式:pcm、wav、amr、m4a
2.编码要求:采样率 16000、16bit、单声道
3.发送http请求
3.1向 baiduSpeechTokenUrl 发请求得access_token (参数为:AK,SK)
QString m_accessToken,m_text; QString TokenUrl = QString(baiduSpeechTokenUrl).arg(speech_client_AK).arg(speech_client_SK); QMap<QString ,QString>header; header.insert(QString("Content-Type") ,QString("audio/pcm;rate=16000")); QByteArray requestData; QByteArray replyData; myhttp m_http; bool ret; if(m_accessToken.isEmpty() == true) { ret = m_http.post_sync(TokenUrl ,header ,requestData ,replyData); if(ret) { QString key = "access_token"; m_accessToken = getJsonValueBtn(replyData ,key); replyData.clear(); qDebug() << "获取的token" << m_accessToken; } else { } }
下图为返回结果
3.2 向BaiduSpeechVideoUrl 发请求得文本(参数为:access_token,录音文件流)
发送代码:
QString speechUrl = QString(BaiduSpeechVideoUrl).arg(QHostInfo::localHostName()).arg(m_accessToken); ret = m_http.post_sync(speechUrl ,header ,requestData ,replyData); if(ret) { QString key = "result"; m_text = getJsonValueBtn(replyData ,key); replyData.clear(); qDebug() << "得到的文本结果:" << m_text; }
3.3 post代码:
bool myhttp::post_sync(QString Url ,QMap<QString ,QString>header ,QByteArray &requestData ,QByteArray &replyData) { //QNetworkAccessManager Url QNetworkRequest QNetworkReply QNetworkAccessManager m_manager; QNetworkRequest m_request; m_request.setUrl(Url); QMapIterator<QString ,QString> it(header); while(it.hasNext()) { it.next(); m_request.setRawHeader(it.key().toLatin1() ,it.value().toLatin1()); } QNetworkReply *pReply = m_manager.post(m_request ,requestData); QEventLoop l; connect( pReply ,&QNetworkReply::finished ,&l ,&QEventLoop::quit); l.exec(); if(pReply != nullptr && pReply->error() == QNetworkReply::NoError) { replyData = pReply->readAll(); qDebug()<<"replyData:"<<replyData; return true; } return false; }
4.解析json数据
JSON | RAW | |
---|---|---|
编码 | 读取二进制后base64编码 | 读取直接放在Body中 |
数据长度 | 数据增大1/3 | |
len =原始大小 | 音频文件大小 Content-Length | |
header | Content-Type:application/json | Content-Type: audio/pcm;rate=16000 |
url:cuid | ||
token: | APPID ,API KEY,Secret KEY | |
dev_pid | 1537(普通话) | |
QString mySpeech::getJsonValue(QByteArray &data, QString &key) { QString ansstr=""; QJsonParseError parseError; QJsonDocument jsonDocument = QJsonDocument::fromJson(data, &parseError); if(parseError.error == QJsonParseError::NoError) { if(jsonDocument.isObject()) { QJsonObject jsonObj = jsonDocument.object(); if(jsonObj.contains(key)) { QJsonValue jsonVal = jsonObj.value(key); if(jsonVal.isString()) { return jsonVal.toString(); } if(jsonVal.isArray()) { QJsonArray arr = jsonVal.toArray(); for(int index = 0;index < arr.size();index++) { QJsonValue subValue = arr.at(index); if(subValue.isString()) { ansstr += subValue.toString() + " "; } } return ansstr; } } else { qDebug() << "不包含关键字:" << key; }//contains(key) } else { qDebug() << "不是json对象"; }//isObject } else { qDebug() << "未成功解析JSON"; }//NoError qDebug() << "未成功解析JSON:"<< data.data(); return QString(""); return ansstr; } 点击并拖拽以移动