1. 工程.pro 配置:
QT += multimedia texttospeech network
2.用windows上可用的麦克风进行录音:
audio.h 文件:
- #ifndef AUDIO_H
- #define AUDIO_H
-
- #include
-
- #include
//查询音频设备 - #include
//音频输入 - #include
//音频存储 -
- #include
-
- #include
-
- #include
- #include
-
- class Audio : public QObject
- {
- Q_OBJECT
- public:
- explicit Audio(QObject *parent = nullptr);
-
- signals:
-
- public slots:
-
- public:
- void startAudio(QString fileName);//初始化
-
- void stopAudio();//停止录音
-
- QString startSpeech();//开始录音并识别
-
- private:
- QString AudioFileName;//用于记录音频文件名
- QFile *AudioFile;//用于操作音频文件
-
- QAudioInput *AudioDevice;//音频设备对象
-
- Speech *speech;//语音识别对象
-
- };
-
- #endif // AUDIO_H
audio.cpp文件:
- #include "audio.h"
-
- Audio::Audio(QObject *parent) : QObject(parent)
- {
- speech = new Speech(this);
- }
-
- void Audio::startAudio(QString fileName)
- {
- if(fileName.isEmpty())
- {
- QMessageBox::warning(NULL,"警告(Audio)","无音频文件名");
- return;
- }
- QAudioDeviceInfo device = QAudioDeviceInfo::defaultInputDevice();//用于检测音频设备状态信息
- if(device.isNull())
- {
- QMessageBox::warning(NULL,"警告(Audio)","无音频设备");
- }else{
- /* 记录录音文件 */
- AudioFileName = fileName;
- /* 音频编码要求 */
- QAudioFormat m_format;
- /* 设置采样频率 */
- m_format.setSampleRate(16000);
- /* 设置通道数 */
- m_format.setChannelCount(1);
- /* 设置位深 */
- m_format.setSampleSize(16);
- /* 设置编码格式 */
- m_format.setCodec("audio/pcm");//http上传推荐pcm格式;也可封装成json上传
-
- /* 判断设备是否支持该格式 */
- if(!device.isFormatSupported(m_format))
- {
- /* 寻找最接近的格式 */
- m_format = device.nearestFormat(m_format);
- }
-
- //打开文件,创建一个音频文件
- AudioFile = new QFile;
- AudioFile->setFileName(fileName);
- AudioFile->open(QIODevice::WriteOnly);
-
- /* 创建录音对象 */
- AudioDevice = new QAudioInput(m_format,this);
- AudioDevice->start(AudioFile);
- }
-
- }
-
- QString Audio::startSpeech()
- {
- if(AudioFileName.isEmpty())//检查录音文件是否存在
- {
- QMessageBox::warning(NULL,"警告","文件不存在");
- return QString("");
- }
- return speech->speechIdentify(AudioFileName); //语音识别,并返回识别后的结果,调用speech中的函数
- }
-
- void Audio::stopAudio()
- {
- /* 停止录音 */
- AudioDevice->stop();
-
- /* 关闭文件 */
- AudioFile->close();
-
- /* 删除文件对象指针并置空 */
- delete AudioFile;
- AudioFile = nullptr;
-
-
- }
3. 通过把录音文件 通过http请求百度云语音库的方式 ,进行语音转文字
http.h文件:
- #ifndef HTTP_H
- #define HTTP_H
-
- #include
-
- #include
//发送请求 - #include
//请求内容 - #include
//返回的结果 -
- #include
-
- class Http : public QObject
- {
- Q_OBJECT
- public:
- explicit Http(QObject *parent = nullptr);
-
- signals:
-
- public slots:
- static bool http_postRequst(QString Url, QMap
header, QByteArray &requestData, QByteArray &replyData) ; - };
-
- #endif // HTTP_H
http.cpp文件:
- #include "http.h"
-
- Http::Http(QObject *parent) : QObject(parent)
- {
-
- }
- bool Http::http_postRequst(QString Url, QMap
header, QByteArray &requestData, QByteArray &replyData) - {
- QNetworkAccessManager manager; //请求者
- QNetworkRequest request; //请求内容
-
- request.setUrl(Url); //获取token值时,参数只需要url和接收token值即可
-
- QMapIterator
it(header) ; - while (it.hasNext()) {//判断header中是否有内容,并读取
- it.next();
- request.setRawHeader(it.key().toLatin1(),it.value().toLatin1());
- }
-
- /* 发送请求等待响应 */
- QNetworkReply *Reply = manager.post(request,requestData);//发送请求
- QEventLoop l;
- connect(Reply,&QNetworkReply::finished,&l,&QEventLoop::quit); //等待响应
- l.exec();//阻塞等待响应
-
- if(Reply != nullptr && Reply->error() == QNetworkReply::NoError)
- {
- replyData = Reply->readAll();//读取http请求后的结果
- return true;
- }
- return false;
- }
请求语句的实现与replyData的解析 :
speech.h文件:
- #ifndef SPEECH_H
- #define SPEECH_H
-
- #include
-
- #include "http.h"
-
- #include
-
- #include
-
- #include
- #include
-
- #include
- #include
- #include
- #include
-
- #include
-
- #include
-
- #include
-
- const QString BaiduSpeechUrl = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2"; //获取token请求的Url,注册百度语音识别可获得,免费180天
- const QString BaiduSpeechClientID = "5VAJlZ5OMInnkkfzLlaWDktx"; //AK
- const QString BaiduSpeechClientSecret = "JWNha3VuBFpotrXBag2Tf3ALWUCOwFuO"; //SK
-
- //语音识别的Url
- //const QString BaiduSpeechSatrtUrl = "https://vop.baidu.com/server_api?dev_pid=80001&cuid=%1&token=%2";//短语音识别极速版
- const QString BaiduSpeechSatrtUrl = "https://vop.baidu.com/server_api?dev_pid=1537&cuid=%1&token=%2"; //短语音识别标准版
- //80001识别普通话 %1:本机唯一标识(本机标识) %2:获取的token
-
- class Speech : public QObject
- {
- Q_OBJECT
- public:
- explicit Speech(QObject *parent = nullptr);
-
- signals:
-
- public slots:
-
- public:
- QString speechIdentify(QString audioFile);
-
- private:
- QString getJsonValue(QByteArray &data, QString &key);
-
- private:
- QString accessToken;
-
- };
-
- #endif // SPEECH_H
speech.cpp文件:
- #include "speech.h"
-
- Speech::Speech(QObject *parent) : QObject(parent)
- {
-
- }
-
- QString Speech::speechIdentify(QString audioFile)
- {
- if(audioFile.isEmpty())
- {
- QMessageBox::warning(NULL,"警告(speech)","文件不存在");
- return QString("");
- }
-
- /* 组装access token的Url */
- QString TokenUrl = QString(BaiduSpeechUrl).arg(BaiduSpeechClientID).arg(BaiduSpeechClientSecret);
-
- /**************获取token值时不用参数,但自定义http函数需要传入**************/
- QMap
header; - header.insert(QString("Content-Type"),QString("audio/pcm;rate=16000"));//Content-Type: audio/pcm;rate=16000键值对 PCM方式上传音频
-
- QByteArray requestData;//用于存放上传的数据,即录音信息
- QByteArray replyData;//定义存放Http请求结果的字节数组
- /**************获取token值不用的参数,但自定义http_postRequst函数需要传入**************/
-
- //获取token值,获取一次使用30天
- if(accessToken.isEmpty() == true)//如果还未获取token值
- {
- bool ret = Http::http_postRequst(TokenUrl, header, requestData, replyData);
- if(ret)
- {
- QString key = "access_token";
- accessToken = getJsonValue(replyData,key);
- replyData.clear();
- qDebug() << "获取的token ——" << accessToken;//调试
- }
- }
-
-
- /* 识别语音请求 将获取的token值组装到新的url中用于发送语音识别请求*/
- QString speechUrl = QString(BaiduSpeechSatrtUrl).arg(QHostInfo::localHostName()).arg(accessToken);
-
- qDebug()<<"speechUrl"<
-
- /* 把录音文件转换成QByteArray */
- QFile file;
- file.setFileName(audioFile);//获取保存的录音文件
- file.open(QIODevice::ReadOnly);
- requestData = file.readAll();//读取录音文件中的内容
- file.close();
-
- if(requestData.isEmpty())
- {
- return QString("语音数据为空");
- }
-
- /* 再次发送请求 语音识别请求 */
- bool ret = Http::http_postRequst(speechUrl, header, requestData, replyData);
- if(ret)
- {
- QString key = "result";
- //解析获取的json信息为QString
- qDebug()<<"hello xjh "<
- QString text = getJsonValue(replyData,key);//自定义函数,下方
- return text;//返回识别后的结果
- }else{
- QMessageBox::warning(NULL,"警告(speech)","识别失败");
- }
- return QString("");
- }
-
-
- QString Speech::getJsonValue(QByteArray &data, QString &key) //自定义json解析函数
- {
- QJsonParseError parseError;//json错误判定对象
- QJsonDocument jsonDocument = QJsonDocument::fromJson(data,&parseError);//转换成json文档
- QString retStr = "";
- if(parseError.error == QJsonParseError::NoError)//判断无误
- {
- if(jsonDocument.isObject())
- {
- /* 将jsonDocument 转换成json对象 */
- QJsonObject jsonObj = jsonDocument.object();
-
- if(jsonObj.contains(key))
- {
- QJsonValue jsonVal = jsonObj.value(key);
- if(jsonVal.isString())
- {
- return jsonVal.toString();
- }
- else if(jsonVal.isArray())//检查是否为数组
- {
- QJsonArray arr = jsonVal.toArray();
- for(int index = 0; index
size(); index++) - {
- QJsonValue subValue = arr.at(index);
- if(subValue.isString())
- {
- retStr += subValue.toString()+" ";
- }
- }
- return retStr;
- }
- }
- else
- {
- qDebug() << "不包含关键字:" << key;
- }//contains(key)
- }
- else
- {
- qDebug() << "不是json对象";
- }//isObject
- }
- else
- {
- qDebug() << "未成功解析JSON";
- }//NoError
- qDebug() << "未成功解析JSON:" << data.data();
- return QString("");
- }
-
4.主窗体上实现申明调用:
头文件:
#include
#include
#include "audio.h"//语音识别
申明:
Audio *my_audio;
QTextToSpeech *my_say;
初始化:
my_audio = new Audio;//语音识别对象
my_say = new QTextToSpeech;//文字转语音 播放
按键实现调用:
void MainWindow::on_btnStartSpeak_clicked()
{
if(speakStatus==false)//开始
{
ui->btnStartSpeak->setText("结束语音");
ui->btnStartSpeak->setStyleSheet(ui->btnStartSpeak->styleSheet()+ "QToolButton{ color: red;}");
speakStatus=true;
my_audio->startAudio("audiofile");
ui->textEditReco->setText("");
}
else
{
ui->btnStartSpeak->setText("开始语音");
ui->btnStartSpeak->setStyleSheet(ui->btnStartSpeak->styleSheet()+ "QToolButton{color: blue;}");
speakStatus=false;
my_audio->stopAudio();
QString retStr = my_audio->startSpeech();//识别结果
my_say->say(retStr);//播放出来
qDebug() << retStr;
ui->textEditReco->setText(retStr);//显示出来
}
}
实验效果:
-
相关阅读:
OpenStack云平台部署
C++排序问题,关于代码的修改补充
centos8 yum install failed to set locale, defaulting to C
系统软硬件
何时以及如何使用try、catch和throw关键字
JVM 基本概念
【CSDN】如何开启CSDN文章下的显示微信公众号、微信号、官方网站、QQ号、QQ群 ?
RabbitMQ运维-持久化机制和内存磁盘的监控
C++中String类详解以及仿写
SpringBoot下Gradle-多环境打包配置详解
-
原文地址:https://blog.csdn.net/chilian12321/article/details/139435136