QT语音识别


语音识别



1.录音文件audio.h编写

#ifndef AUDIO_H
#define AUDIO_H

#include <QObject>
#include <QAudioInput>
#include <QFile>
#include <QAudioDeviceInfo>
#include <QMessageBox>

class audio : public QObject
{
    Q_OBJECT
public:
    explicit audio(QObject *parent = nullptr);
    void startRecord(QString filename);   //开始录音
    void stopRecord();                    //停止录音
    ~audio();
signals:
public slots:

private:
    QAudioInput *m_audioInput;           //录音对象
    QFile       *m_file;                 //
};
#endif // AUDIO_H

2.录音文件audio.cpp编写

#include "audio.h"

audio::audio(QObject *parent) : QObject(parent)
{

}

void audio::startRecord(QString filename)
{
       // 判断本地设备是否支持该格式
        QAudioDeviceInfo audioDeviceInfo = QAudioDeviceInfo::defaultInputDevice();
        // 判断本地是否有录音设备;
        if (!audioDeviceInfo.isNull())
            {
                m_file = new QFile;
                m_file->setFileName(filename);
                m_file->open(QIODevice::WriteOnly | QIODevice::Truncate);

                // 设置音频文件格式;
                QAudioFormat format;
                // 设置采样频率;
                format.setSampleRate(16000);
                // 设置通道数;
                format.setChannelCount(1);
                // 设置每次采样得到的样本数据位值;
                format.setSampleSize(16);
                // 设置编码方法;
                format.setCodec("audio/pcm");
                // 设置采样字节存储顺序;
                //format.setByteOrder(QAudioFormat::LittleEndian);
                // 设置采样类型;
                //format.setSampleType(QAudioFormat::UnSignedInt);

                // 判断当前设备设置是否支持该音频格式(重点);
                if (!audioDeviceInfo.isFormatSupported(format))
                {
                    format = audioDeviceInfo.nearestFormat(format);
                 }
                // 创建录音对象;
                m_audioInput = new QAudioInput(format, this);
                //开始录音
                m_audioInput->start(m_file);
            }
            else
            {
                // 没有录音设备;
                QMessageBox::information(NULL, tr("Record"), tr("Current No Record Device"));
            }
        }

void audio::stopRecord()
{
    //停止录音
    m_audioInput->stop();
    //关闭文件
    m_file->close();
    //删除文件对象
    delete m_file;  //删除只是删除了指针指向的内存空间,没有删除指针,需要将指针指为NULL
    m_file = NULL;

}
audio::~audio()
{
    delete m_audioInput;
    delete m_file;
}

3.语音识别文件speech.h编写

#ifndef SPEECH_H
#define SPEECH_H

#include <QObject>
#include "http.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QHostInfo>
#include <QFile>
#include <QMessageBox>
#include <QIODevice>
//获取access_token相关
const QString baiduTokenUrl = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2&";
const QString client_id = "1jkwFvYSqCWwlWyNfcPwT21l";
const QString client_secret = "yeWjdAwXXICGCmLRLTSqcYFS0VEBSFS1";

//语音识别相关
const QString baiduSpeechurl = "http://vop.baidu.com/server_api?dev_pid=1537&cuid=%1&token=%2"; //普通话测试


class speech : public QObject
{
    Q_OBJECT
public:
    explicit speech(QObject *parent = nullptr);
    QString speechIdentify(QString filename);  //开始识别

    QString getJsonvalue(QByteArray ba,QString key);
signals:

public slots:
private:
    QString  accessToken;
};
#endif // SPEECH_H

4.语音识别文件speech.cpp编写

#include "speech.h"


//构造函数
speech::speech(QObject *parent) : QObject(parent)
{

}


QString speech::speechIdentify(QString filename)
{
    //获取token
    QString tokenUrl = QString(baiduTokenUrl).arg(client_id).arg(client_secret);

    QMap<QString, QString> headers;
    headers.insert(QString("Content-Type"), QString("audio/pcm;rate=16000"));
    QByteArray requestdata;   //发送的内容
    QByteArray replydata;     //服务器返回的内容
    http httputil;
    bool success = httputil.postSyn(tokenUrl, headers, requestdata, replydata);
    if (success)
    {
        QString key = "access_token";
        accessToken  = getJsonvalue(replydata, key);  //获取到access_token(通过json数据格式解析)
        //qDebug() << accessToken << endl;
    }
    else
        return "";

    //语言识别
    QString baiduSpeech = QString(baiduSpeechurl).arg("LAPTOP-71LN9B3Q").arg(accessToken);

    //把文件 转化为QByteArray
    QFile file;
    file.setFileName(filename);
    file.open(QIODevice::ReadOnly);
    requestdata =file.readAll();
    file.close();
    replydata.clear();

    //再次发起http请求
    bool result = httputil.postSyn(baiduSpeech, headers, requestdata, replydata);
    if (result)
    {
        QString key = "result" ;
        QString text = getJsonvalue (replydata, key) ;
        return text;
    }
    else
    {
        QMessageBox::warning(NULL,"识别提示","识别失败");

    }

    return "";

}

QString speech::getJsonvalue(QByteArray ba, QString key)
{

    QJsonParseError parseError;
    QJsonDocument jsonDocument = QJsonDocument::fromJson(ba, &parseError);

    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(); //转换成JsonArray
                    QJsonValue jv = arr.at(0);          //获取第1个元素
                    return jv. toString();
                  }
               }
            }
        }
     return "";
}

5.http请求http.h文件编写

#ifndef HTTP_H
#define HTTP_H

#include <QObject>
#include <QMap>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QEventLoop>
class http : public QObject
{
    Q_OBJECT
public:
    explicit http(QObject *parent = nullptr);
    bool postSyn(QString url, QMap<QString, QString> headerdata, QByteArray requestData, QByteArray &replydata);
signals:

public slots:
};
#endif // HTTP_H

6.http请求http.cpp文件编写

#include "http.h"

http::http(QObject *parent) : QObject(parent)
{

}

bool http::postSyn( QString url, QMap<QString, QString> headerdata, QByteArray requestData, QByteArray &replydata)
{
//发送请求的对象
    QNetworkAccessManager manager;
//请求对象
    QNetworkRequest request;
    request.setUrl(url);

    QMapIterator<QString, QString> it(headerdata);  //迭代器
    while (it.hasNext())                            //遍历Map
    {
        it.next();
        request.setRawHeader(it.key().toLatin1(),it.value().toLatin1());
    }

    QNetworkReply *reply = manager.post(request, requestData) ;
    QEventLoop l;
    //一旦服务器返回,reply会发出信号
    connect(reply, &QNetworkReply::finished, &l, &QEventLoop::quit);
    l.exec();
    //死循环,reply发出信号, 结束循环

    if (reply != nullptr && reply->error() == QNetworkReply::NoError)
    {
        replydata = reply->readAll(); //读取服务 器返回的数据
        qDebug() << replydata;
        return true;
    }
    else
    {
        qDebug() << "请求失败";
        return false;
    }
}

7.窗口文件widget.h文件编写

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "audio.h"
#include "speech.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_pressed();

    void on_pushButton_released();

    void on_clearbutton_clicked();

private:
    Ui::Widget *ui;
    audio Audiodevice;     //创建录音设备对象
    speech m_speech;
};
#endif // WIDGET_H

8.窗口文件widget.cpp文件编写

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->pushButton->setText("按住说话");
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_pressed()
{
    ui->pushButton->setText("松开识别");
    //开始录音
    Audiodevice.startRecord("D:\\1.pcm");
}

void Widget::on_pushButton_released()
{
    //停止录音
    Audiodevice.stopRecord();
    //修改按钮文件
    ui->pushButton->setText("开始识别");
    //开始识别
    QString text = m_speech.speechIdentify("D:\\1.pcm");
    if(text != "")
    {
        ui->textEdit->setText(text);
        ui->pushButton->setText("按住说话");
    }
    else
        QMessageBox::warning(NULL,"错误提示","识别失败");
}

void Widget::on_clearbutton_clicked()
{
    ui->textEdit->clear();
}

9.项目框架

在这里插入图片描述

10.ui界面

在这里插入图片描述

  • 6
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值