現在語音聊天機器人是一度火熱,網上也有其他編程軟件的語音聊天機器人,但是沒有Qt的(或許是博主沒找到),故在此發一篇關於Qt如何編寫語音聊天機器人詳解。代碼中運用到了一些常見的命令,比如正則表達式、獲取時間等,希望大家喜歡。
注:Aili_Xiao首發博客園及CSDN博客
新增附件:百度語音識別 百度語音識別1.1
好多人私聊說需要語音識別的教程,因為時間關系,教程就不寫了直接將語音識別源碼放附件中,有需要的看附件。
2018/11/21注:修訂百度語音識別,重新上傳
2018/11/14注:經過網友反映附件有可能出錯,請注意Qt版本和QSslSocket類加載。測試附件Qt版本為5.9.2,其他版本使用時請注意QSslSocket調用是否成功。附件中的百度Key明顯是錯誤的,請換成自己的Key進行使用!!!
前期准備:聊天機器人(圖靈和小i等,這里采用的圖靈),語音服務(百度語音和訊飛語音,這里采用的是百度語音)。跳過前期准備
圖靈機器人:http://www.tuling123.com/
圖靈機器人注冊示意圖:
圖靈機器人登陸示意圖,可以選擇第三方登錄。
圖靈機器人創建示意圖以及能力購買
百度語音注冊示意圖:
百度語音創建應用示意圖:
只進行前兩步 ,我們的百度語音的應用就創建好了,然后刷新一下就可以看到,我們創建的應用,之后我們開通服務。
兩個服務都選上,其實我們今天就只講語音合成。
好了以上是前期的准備工作。當我們創建好了,那就開始我們今天的正題,Qt編寫語音聊天機器人。
===正文開始===
一、獲取API數據:
記錄圖靈機器人的API接口:在圖靈機器人界面點擊設置然后往下翻,將API地址,APIkey記錄下來,secret是加密的我們可以不打開后面的開關
記錄百度語音的API接口:(因為我們是在PC端進行的,所以不能使用Android或者ISO的服務)
在應用管理點擊 查看key,將APP ID,API Key,和Secret Key都記錄下來。
此時我們打開百度語音的“文檔中心”,找到今天我們要使用的“語音合成”點開,之后找到“語音合成 REST API”。使用語音功能我們需要權威的認證,所以我們需要認證,點開“鑒權認證機制”,照着文章所說我們取得Access Token,也可以直接編輯下面的鏈接然后填入自己百度API Key和Secret Key,復制到瀏覽器打開鏈接就可以獲得Access Token。
https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=API Key&client_secret= Secret Key
Access_token = 24.b9ff177ff09b5133f0a84bc04d631703.2592000.1504956436.282335-9993948
這個是我獲取的,到這里第一步的過程已經結束。
二、打開Qt Creator新建項目為ChatRobots,我們這里采用無ui設計。

編輯ChatRobots.pro文件:編輯過后Ctrl+S保存
1 QT += core gui network script multimedia
編輯widget.h文件
1 #ifndef WIDGET_H 2 #define WIDGET_H 3 //作者:夜瀟 4 #include <QWidget> 5 #include <QtNetwork> 6 #include <QMediaPlayer> 7 8 #include <QLineEdit> 9 #include <QLabel> 10 #include <QPushButton> 11 #include <QListWidget> 12 #include <QGridLayout> 13 14 #include <QRegExp> 15 #include <QRegExpValidator> 16 #include <QStringList> 17 18 #include <QTimer> 19 #include <QTime> 20 21 static const QString TuLing_URL = "http://www.tuling123.com/openapi/api"; 22 static const QString TuLing_APIKEY = "填寫你的圖靈API_KEY"; 23 static const QString baidu_URL = "http://tsn.baidu.com/text2audio?"; 24 static const QString baidu_token = "填寫你的百度權威認證:Access_token"; 25 26 class Widget : public QWidget 27 { 28 Q_OBJECT 29 30 public: 31 Widget(QWidget *parent = 0); 32 ~Widget(); 33 private: 34 QLabel *labelInput,*labelOut,*labellink; 35 QLineEdit *lineEdit; //發送內容 36 QPushButton *BtnFaSong; 37 QListWidget *lineEdit1; //聊天內容 38 QGridLayout *mainlayout; 39 QString URl,baidu_Cuid,StrMac; 40 QString text; 41 QString StrTemp; 42 QMediaPlayer *player; //語音播放 43 private slots: 44 void on_btnSend_clicked(); 45 void replyFinish(QNetworkReply *); 46 //時間 47 void showTime(); 48 //延時 49 void ShowAllDelay(int b); 50 //調用百度語音合成API槽函數 51 void ShowSong(QString bai_tex,QString bai_lan, 52 QString bai_tok,QString bai_ctp,QString bai_cuid,QString bai_spd, 53 QString bai_pit,QString bai_vol,QString bai_per); 54 //獲取本機MAC地址 55 QString getMacAddress(); 56 //轉換MAC地址格式 57 QString tgt_mac(); 58 }; 59 60 #endif // WIDGET_H
編輯widget.cpp文件
1 #include "widget.h" 2 #include "QString" 3 #include <QDebug> 4 5 #include <QJsonDocument> 6 #include <QJsonParseError> 7 #include <QtScript/QScriptEngine> 8 #include <QtScript/QScriptValueIterator> 9 #include <QtScript/QScriptValue> 10 11 Widget::Widget(QWidget *parent) 12 : QWidget(parent) 13 { 14 setWindowTitle("ChatRobots(聊天機器人) —— 作者:夜瀟"); 15 setMinimumSize(520,410); 16 17 labelInput = new QLabel("欲發送內容:"); 18 labellink = new QLabel; 19 labellink ->setOpenExternalLinks(true); 20 labelOut = new QLabel("當前聊天:"); 21 lineEdit = new QLineEdit; 22 lineEdit ->setMinimumHeight(32); 23 lineEdit ->setFocus(); 24 lineEdit ->setClearButtonEnabled(true); 25 lineEdit1 = new QListWidget; 26 lineEdit1 ->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 27 lineEdit1 ->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 28 BtnFaSong = new QPushButton("發送"); 29 BtnFaSong ->setMinimumHeight(32); 30 31 player=new QMediaPlayer(this); 32 33 mainlayout = new QGridLayout(this); 34 mainlayout ->addWidget(labelOut,0,0); 35 mainlayout ->addWidget(labellink,0,1); 36 mainlayout ->addWidget(lineEdit1,1,0,1,2); 37 mainlayout ->addWidget(labelInput,2,0); 38 mainlayout ->addWidget(lineEdit,2,1); 39 mainlayout ->addWidget(BtnFaSong,3,0,1,2); 40 41 connect(BtnFaSong,SIGNAL(clicked(bool)),this,SLOT(on_btnSend_clicked())); 42 QTimer *timer=new QTimer(this); 43 connect(timer,SIGNAL(timeout()),this,SLOT(showTime())); 44 timer->start(1000); 45 showTime(); 46 getMacAddress(); 47 tgt_mac(); 48 } 49 50 Widget::~Widget() 51 { 52 53 } 54 55 void Widget::on_btnSend_clicked() 56 { 57 StrTemp = lineEdit->text(); 58 if(StrTemp.isEmpty()) 59 { 60 StrTemp = "你好"; 61 URl = TuLing_URL + "?key=" + TuLing_APIKEY + "&info=" + StrTemp; 62 } 63 else 64 { 65 URl = TuLing_URL + "?key=" + TuLing_APIKEY + "&info=" + StrTemp; 66 } 67 lineEdit1->addItem(text); 68 lineEdit1->addItem("我:"+StrTemp); 69 lineEdit1 ->setCurrentRow(lineEdit1->count() - 1); 70 QUrl url; 71 url.setUrl(URl); 72 QNetworkRequest request(url); 73 QNetworkAccessManager *manager=new QNetworkAccessManager(this); 74 manager->get(request); 75 connect(manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(replyFinish(QNetworkReply *))); 76 } 77 78 void Widget::replyFinish(QNetworkReply * reply) 79 { 80 QString data=reply->readAll(); 81 QString strText,StrTextUrl; 82 QScriptValue jsontext; 83 QScriptEngine engineText; 84 jsontext=engineText.evaluate("value="+data); 85 StrTextUrl = jsontext.property("url").toString(); 86 QScriptValueIterator iteratorText(jsontext); 87 while(iteratorText.hasNext()) 88 { 89 iteratorText.next(); 90 91 if(iteratorText.name()=="text") 92 { 93 strText=iteratorText.value().toString(); 94 lineEdit1->addItem(text); 95 lineEdit1->addItem("如夢令:"+strText); 96 ShowSong(strText,"zh",baidu_token,"1",StrMac,"5","5","5","0");//默認設置語音:中文,語速語調等為5,講述人:0為女 97 lineEdit1->setWordWrap(true); 98 lineEdit1 ->setCurrentRow(lineEdit1->count() - 1); 99 if(!StrTextUrl.isEmpty()) 100 { 101 labellink->setText(tr("<a href = %1>%2</a>").arg(StrTextUrl).arg(StrTemp)); 102 labellink->show(); 103 ShowAllDelay(30000);//設置延時時間為半分鍾 104 labellink->hide(); 105 } 106 break; 107 } 108 } 109 } 110 111 void Widget::showTime() 112 { 113 QTime time=QTime::currentTime(); 114 text=time.toString("hh:mm:ss"); 115 } 116 117 void Widget::ShowAllDelay(int b) 118 { 119 QTime timer = QTime::currentTime().addMSecs(b); 120 while (QTime::currentTime() < timer) 121 { 122 QCoreApplication::processEvents(QEventLoop::AllEvents,100); 123 } 124 } 125 126 void Widget::ShowSong(QString bai_tex,QString bai_lan,QString bai_tok,QString bai_ctp, 127 QString bai_cuid,QString bai_spd,QString bai_pit,QString bai_vol,QString bai_per) 128 { 129 QByteArray url="http://tsn.baidu.com/text2audio?"; 130 url.append(QString("&lan=%1&cuid=%2&ctp=%3&tok=%4&spd=%5&pit=%6&vol=%7&per=%8").arg(bai_lan).arg(bai_cuid).arg(bai_ctp).arg(bai_tok).arg(bai_spd).arg(bai_pit).arg(bai_vol).arg(bai_per)); 131 url.append("&tex="); 132 url.append(QUrl::toPercentEncoding(bai_tex)); 133 player->setMedia(QUrl::fromLocalFile(url)); 134 player->play(); 135 } 136 137 QString Widget::getMacAddress() 138 { 139 foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) 140 { 141 baidu_Cuid += "Interface:"+interface.hardwareAddress()+"\n"; 142 if (!(interface.flags() & QNetworkInterface::IsRunning)) 143 { 144 baidu_Cuid = interface.hardwareAddress(); 145 return baidu_Cuid; 146 } 147 } 148 } 149 150 QString Widget::tgt_mac() 151 { 152 QString str1,str2,str3,str4,str5,str6; 153 QStringList list = baidu_Cuid.split(QRegExp(":"), QString::SkipEmptyParts); //這里采用的正則分割文本 154 str1 = list[0]; 155 str2 = list[1]; 156 str3 = list[2]; 157 str4 = list[3]; 158 str5 = list[4]; 159 str6 = list[5]; 160 StrMac =str1+"-"+str2+"-"+str3+"-"+str4+"-"+str5+"-"+str6; 161 return StrMac; 162 }
以上就是第二部分的內容,下面附上測試圖:當輸入框中沒有內容的時候,默認是發送“你好”問候語。
如果覺得好,就給一個贊吧以及分享給好友!如有疑問留言,或者發送郵箱:1285015525@qq.com。