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


    1. 工程.pro 配置:


    QT      += multimedia texttospeech network

    2.用windows上可用的麦克风进行录音:

    audio.h 文件:

    1. #ifndef AUDIO_H
    2. #define AUDIO_H
    3. #include
    4. #include //查询音频设备
    5. #include //音频输入
    6. #include //音频存储
    7. #include
    8. #include
    9. #include
    10. #include
    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
    4. #include //发送请求
    5. #include //请求内容
    6. #include //返回的结果
    7. #include
    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, QMapheader, 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 header, QByteArray &requestData, QByteArray &replyData)
    6. {
    7. QNetworkAccessManager manager; //请求者
    8. QNetworkRequest request; //请求内容
    9. request.setUrl(Url); //获取token值时,参数只需要url和接收token值即可
    10. QMapIterator 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
    4. #include "http.h"
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    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. QMapheader;
    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"<
    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 "<
    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; indexsize(); 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
    #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