Qt:使用百度語音識別REST API,做全平臺語音識別
阿新 • • 發佈:2019-01-01
百度語音開發介紹文件:
使用語音識別,需要在百度申請一個應用,然後拿到API Key和Secret Key,然後才可以使用語音識別
ps:我的示例裡面有放了一組可用的Key,但是僅供各位測試使用,有需要開發App的請自行申請,放在示例中的Key我可能隨時會撤銷。
ps:編譯需要開啟C++11的支援
ps:我寫示例在OS X下是沒問題的。但是當我移植到Windows下的時候,在重新整理token那一步有問題,貌似和https有關,等到我想到解決方法的時候回來更新。
ps:示例裡,在重新整理token的地方我直接寫了apikey的明文字串,應該替換成m_apiKey,請手動替換。本頁面中我已經更改了。
直接上程式碼
.h標頭檔案部分
class BaiduVop: public QObject { Q_OBJECT private: QAudioDeviceInfo m_currentDevice; QString m_apiKey; QString m_secretKey; QString m_token; QAudioInput *m_audioInput = NULL; QByteArray m_buf; QBuffer *m_buffer = NULL; JasonQt_Net::HTTP m_http; public: BaiduVop(const QString &apiKey, const QString &secretKey); void setDevice(const QAudioDeviceInfo &device); public slots: bool refreshToken(void); bool start(void); std::pair<bool, QString> finish(void); };
.cpp實現檔案
BaiduVop::BaiduVop(const QString &apiKey, const QString &secretKey): m_apiKey(apiKey), m_secretKey(secretKey) { const auto &&availableDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); if(!availableDevices.isEmpty()) { m_currentDevice = availableDevices.first(); QAudioFormat format; format.setSampleRate(8000); format.setChannelCount(1); format.setSampleSize(16); format.setSampleType(QAudioFormat::SignedInt); format.setByteOrder(QAudioFormat::LittleEndian); format.setCodec("audio/pcm"); m_audioInput = new QAudioInput(m_currentDevice, format, this); } } void BaiduVop::setDevice(const QAudioDeviceInfo &device) { m_currentDevice = device; } bool BaiduVop::refreshToken(void) { QNetworkRequest request(QUrl(QString("https://openapi.baidu.com/oauth/2.0/token?"))); QByteArray append = QString("grant_type=client_credentials&client_id=%1&client_secret=%2&").arg(m_apiKey, m_secretKey).toLatin1(); QByteArray buf; request.setRawHeader("Content-Type", "application/json"); const auto &&flag = m_http.post(request, append, buf, 15000); if(!flag) { return false; } const auto &&data = QJsonDocument::fromJson(buf).object(); if(data.isEmpty() || !data.contains("access_token")) { return false; } m_token = data["access_token"].toString(); return true; } bool BaiduVop::start(void) { if(m_token.isEmpty()) { qDebug("BaiduVop::start fail, Need refresh token befor start."); return false; } m_buffer = new QBuffer; m_buffer->open(QIODevice::ReadWrite); m_audioInput->start(m_buffer); return true; } std::pair<bool, QString> BaiduVop::finish(void) { m_audioInput->stop(); const auto &sendData = m_buffer->data(); m_buffer->deleteLater(); QNetworkRequest request(QUrl("http://vop.baidu.com/server_api")); QJsonObject append; request.setRawHeader("Content-Type", "application/json"); append["format"] = "pcm"; append["rate"] = 8000; append["channel"] = 1; append["token"] = m_token; append["lan"] = "zh"; append["cuid"] = "JasonQt"; append["speech"] = QString(sendData.toBase64()); append["len"] = sendData.size(); QByteArray buf; m_http.post(request, QJsonDocument(append).toJson(), buf, 15000); QJsonObject acceptedData(QJsonDocument::fromJson(buf).object()); if(buf.isEmpty() || acceptedData.isEmpty() || !acceptedData.contains("result")) { return { false, buf }; } const auto &&message = acceptedData["result"].toArray()[0].toString(); return { true, message.mid(0, message.size() - 1) }; }
其中有幾個http的介面已經被我封裝了,需要自行開發的請更改程式碼或者直接下載我的示例,裡面有完整的工程。
可以到下方連結中下載