QT 使用百度语音识别--生成文本

打印 上一主题 下一主题

主题 1937|帖子 1937|积分 5811

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 工程.pro 设置:

QT      += multimedia texttospeech network

2.用windows上可用的麦克风举行灌音:
audio.h 文件:
  1. #ifndef AUDIO_H
  2. #define AUDIO_H
  3. #include <QObject>
  4. #include <QAudioDeviceInfo> //查询音频设备
  5. #include <QAudioInput> //音频输入
  6. #include <QAudioFormat> //音频存储
  7. #include <QFile>
  8. #include <speech.h>
  9. #include <QMessageBox>
  10. #include <QDebug>
  11. class Audio : public QObject
  12. {
  13.     Q_OBJECT
  14. public:
  15.     explicit Audio(QObject *parent = nullptr);
  16. signals:
  17. public slots:
  18. public:
  19.     void startAudio(QString fileName);//初始化
  20.     void stopAudio();//停止录音
  21.     QString startSpeech();//开始录音并识别
  22. private:
  23.     QString AudioFileName;//用于记录音频文件名
  24.     QFile *AudioFile;//用于操作音频文件
  25.     QAudioInput *AudioDevice;//音频设备对象
  26.     Speech *speech;//语音识别对象
  27. };
  28. #endif // AUDIO_H
复制代码
audio.cpp文件:
  1. #include "audio.h"
  2. Audio::Audio(QObject *parent) : QObject(parent)
  3. {
  4.     speech = new Speech(this);
  5. }
  6. void Audio::startAudio(QString fileName)
  7. {
  8.     if(fileName.isEmpty())
  9.     {
  10.         QMessageBox::warning(NULL,"警告(Audio)","无音频文件名");
  11.         return;
  12.     }
  13.     QAudioDeviceInfo device = QAudioDeviceInfo::defaultInputDevice();//用于检测音频设备状态信息
  14.     if(device.isNull())
  15.     {
  16.         QMessageBox::warning(NULL,"警告(Audio)","无音频设备");
  17.     }else{
  18.         /* 记录录音文件 */
  19.         AudioFileName = fileName;
  20.         /* 音频编码要求 */
  21.         QAudioFormat m_format;
  22.         /* 设置采样频率 */
  23.         m_format.setSampleRate(16000);
  24.         /* 设置通道数 */
  25.         m_format.setChannelCount(1);
  26.         /* 设置位深 */
  27.         m_format.setSampleSize(16);
  28.         /* 设置编码格式 */
  29.         m_format.setCodec("audio/pcm");//http上传推荐pcm格式;也可封装成json上传
  30.         /* 判断设备是否支持该格式 */
  31.         if(!device.isFormatSupported(m_format))
  32.         {
  33.             /* 寻找最接近的格式 */
  34.             m_format = device.nearestFormat(m_format);
  35.         }
  36.         //打开文件,创建一个音频文件
  37.         AudioFile = new QFile;
  38.         AudioFile->setFileName(fileName);
  39.         AudioFile->open(QIODevice::WriteOnly);
  40.         /* 创建录音对象 */
  41.         AudioDevice = new QAudioInput(m_format,this);
  42.         AudioDevice->start(AudioFile);
  43.     }
  44. }
  45. QString Audio::startSpeech()
  46. {
  47.     if(AudioFileName.isEmpty())//检查录音文件是否存在
  48.     {
  49.         QMessageBox::warning(NULL,"警告","文件不存在");
  50.         return QString("");
  51.     }
  52.     return speech->speechIdentify(AudioFileName); //语音识别,并返回识别后的结果,调用speech中的函数
  53. }
  54. void Audio::stopAudio()
  55. {
  56.     /* 停止录音 */
  57.     AudioDevice->stop();
  58.     /* 关闭文件 */
  59.     AudioFile->close();
  60.     /* 删除文件对象指针并置空 */
  61.     delete AudioFile;
  62.     AudioFile = nullptr;
  63. }
复制代码
3. 通过把灌音文件 通过http哀求百度云语音库的方式 ,举行语音转笔墨
http.h文件:
  1. #ifndef HTTP_H
  2. #define HTTP_H
  3. #include <QObject>
  4. #include <QNetworkAccessManager> //发送请求
  5. #include <QNetworkRequest>              //请求内容
  6. #include <QNetworkReply>                //返回的结果
  7. #include <QEventLoop>
  8. class Http : public QObject
  9. {
  10.     Q_OBJECT
  11. public:
  12.     explicit Http(QObject *parent = nullptr);
  13. signals:
  14. public slots:
  15.     static bool http_postRequst(QString Url, QMap<QString,QString>header, QByteArray &requestData, QByteArray &replyData);
  16. };
  17. #endif // HTTP_H
复制代码
http.cpp文件:
  1. #include "http.h"
  2. Http::Http(QObject *parent) : QObject(parent)
  3. {
  4. }
  5. bool Http::http_postRequst(QString Url, QMap<QString, QString> header, QByteArray &requestData, QByteArray &replyData)
  6. {
  7.     QNetworkAccessManager manager; //请求者
  8.     QNetworkRequest request;                //请求内容
  9.     request.setUrl(Url);                            //获取token值时,参数只需要url和接收token值即可
  10.     QMapIterator<QString, QString> it(header);
  11.     while (it.hasNext()) {//判断header中是否有内容,并读取
  12.         it.next();
  13.         request.setRawHeader(it.key().toLatin1(),it.value().toLatin1());
  14.     }
  15.     /* 发送请求等待响应 */
  16.     QNetworkReply *Reply = manager.post(request,requestData);//发送请求
  17.     QEventLoop l;
  18.     connect(Reply,&QNetworkReply::finished,&l,&QEventLoop::quit); //等待响应
  19.     l.exec();//阻塞等待响应
  20.     if(Reply != nullptr && Reply->error() == QNetworkReply::NoError)
  21.     {
  22.         replyData = Reply->readAll();//读取http请求后的结果
  23.         return true;
  24.     }
  25.     return false;
  26. }
复制代码
哀求语句的实现与replyData的解析 :
speech.h文件:
  1. #ifndef SPEECH_H
  2. #define SPEECH_H
  3. #include <QObject>
  4. #include "http.h"
  5. #include <QFile>
  6. #include <QMap>
  7. #include <QByteArray>
  8. #include <QMessageBox>
  9. #include <QJsonDocument>
  10. #include <QJsonObject>
  11. #include <QJsonArray>
  12. #include <QJsonValue>
  13. #include <QHostInfo>
  14. #include <QDebug>
  15. #include <QMessageBox>
  16. const QString BaiduSpeechUrl = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2"; //获取token请求的Url,注册百度语音识别可获得,免费180天
  17. const QString BaiduSpeechClientID = "5VAJlZ5OMInnkkfzLlaWDktx";                                 //AK
  18. const QString BaiduSpeechClientSecret = "JWNha3VuBFpotrXBag2Tf3ALWUCOwFuO";     //SK
  19. //语音识别的Url
  20. //const QString BaiduSpeechSatrtUrl = "https://vop.baidu.com/server_api?dev_pid=80001&cuid=%1&token=%2";//短语音识别极速版
  21. const QString BaiduSpeechSatrtUrl = "https://vop.baidu.com/server_api?dev_pid=1537&cuid=%1&token=%2";  //短语音识别标准版
  22. //80001识别普通话  %1:本机唯一标识(本机标识)  %2:获取的token
  23. class Speech : public QObject
  24. {
  25.     Q_OBJECT
  26. public:
  27.     explicit Speech(QObject *parent = nullptr);
  28. signals:
  29. public slots:
  30. public:
  31.     QString speechIdentify(QString audioFile);
  32. private:
  33.     QString getJsonValue(QByteArray &data, QString &key);
  34. private:
  35.     QString accessToken;
  36. };
  37. #endif // SPEECH_H
复制代码
speech.cpp文件:
  1. #include "speech.h"
  2. Speech::Speech(QObject *parent) : QObject(parent)
  3. {
  4. }
  5. QString Speech::speechIdentify(QString audioFile)
  6. {
  7.     if(audioFile.isEmpty())
  8.     {
  9.         QMessageBox::warning(NULL,"警告(speech)","文件不存在");
  10.         return QString("");
  11.     }
  12.     /* 组装access token的Url */
  13.     QString TokenUrl = QString(BaiduSpeechUrl).arg(BaiduSpeechClientID).arg(BaiduSpeechClientSecret);
  14.     /**************获取token值时不用参数,但自定义http函数需要传入**************/
  15.     QMap<QString, QString>header;
  16.     header.insert(QString("Content-Type"),QString("audio/pcm;rate=16000"));//Content-Type: audio/pcm;rate=16000键值对       PCM方式上传音频
  17.     QByteArray requestData;//用于存放上传的数据,即录音信息
  18.     QByteArray replyData;//定义存放Http请求结果的字节数组
  19.     /**************获取token值不用的参数,但自定义http_postRequst函数需要传入**************/
  20.     //获取token值,获取一次使用30天
  21.     if(accessToken.isEmpty() == true)//如果还未获取token值
  22.     {
  23.         bool ret = Http::http_postRequst(TokenUrl, header, requestData, replyData);
  24.         if(ret)
  25.         {
  26.             QString key = "access_token";
  27.             accessToken = getJsonValue(replyData,key);
  28.             replyData.clear();
  29.             qDebug() << "获取的token ——" << accessToken;//调试
  30.         }
  31.     }
  32.     /* 识别语音请求    将获取的token值组装到新的url中用于发送语音识别请求*/
  33.     QString speechUrl = QString(BaiduSpeechSatrtUrl).arg(QHostInfo::localHostName()).arg(accessToken);
  34.     qDebug()<<"speechUrl"<<speechUrl;
  35.     /* 把录音文件转换成QByteArray */
  36.     QFile file;
  37.     file.setFileName(audioFile);//获取保存的录音文件
  38.     file.open(QIODevice::ReadOnly);
  39.     requestData = file.readAll();//读取录音文件中的内容
  40.     file.close();
  41.     if(requestData.isEmpty())
  42.     {
  43.         return QString("语音数据为空");
  44.     }
  45.     /* 再次发送请求       语音识别请求 */
  46.     bool ret = Http::http_postRequst(speechUrl, header, requestData, replyData);
  47.     if(ret)
  48.     {
  49.         QString key = "result";
  50.         //解析获取的json信息为QString
  51.           qDebug()<<"hello xjh "<<replyData;
  52.         QString text = getJsonValue(replyData,key);//自定义函数,下方
  53.         return text;//返回识别后的结果
  54.     }else{
  55.         QMessageBox::warning(NULL,"警告(speech)","识别失败");
  56.     }
  57.     return QString("");
  58. }
  59. QString Speech::getJsonValue(QByteArray &data, QString &key)    //自定义json解析函数
  60. {
  61.     QJsonParseError parseError;//json错误判定对象
  62.     QJsonDocument jsonDocument = QJsonDocument::fromJson(data,&parseError);//转换成json文档
  63.     QString retStr = "";
  64.     if(parseError.error == QJsonParseError::NoError)//判断无误
  65.     {
  66.         if(jsonDocument.isObject())
  67.         {
  68.             /*  将jsonDocument 转换成json对象 */
  69.             QJsonObject jsonObj = jsonDocument.object();
  70.             if(jsonObj.contains(key))
  71.             {
  72.                 QJsonValue jsonVal = jsonObj.value(key);
  73.                 if(jsonVal.isString())
  74.                 {
  75.                     return jsonVal.toString();
  76.                 }
  77.                 else if(jsonVal.isArray())//检查是否为数组
  78.                 {
  79.                     QJsonArray arr = jsonVal.toArray();
  80.                     for(int index = 0; index<arr.size(); index++)
  81.                     {
  82.                         QJsonValue subValue = arr.at(index);
  83.                         if(subValue.isString())
  84.                         {
  85.                             retStr += subValue.toString()+" ";
  86.                         }
  87.                     }
  88.                     return retStr;
  89.                 }
  90.             }
  91.             else
  92.             {
  93.                 qDebug() << "不包含关键字:" << key;
  94.             }//contains(key)
  95.         }
  96.         else
  97.         {
  98.             qDebug() << "不是json对象";
  99.         }//isObject
  100.     }
  101.     else
  102.     {
  103.         qDebug() << "未成功解析JSON";
  104.     }//NoError
  105.     qDebug() << "未成功解析JSON:" << data.data();
  106.     return QString("");
  107. }
复制代码
4.主窗体上实现申明调用:
头文件:
#include <QTextToSpeech>
#include <QVoice>
#include "audio.h"//语音识别
申明:
Audio *my_audio;
QTextToSpeech *my_say;
初始化:
  1. my_audio = new Audio;//语音识别对象
  2. my_say = new QTextToSpeech;//文字转语音 播放
复制代码
按键实现调用:
   
void MainWindow:n_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);//表现出来
      }
}
  实行效果:
 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我可以不吃啊

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表