QT聊天机器人(百度语音+青云客API)

文章目录

  • 效果
  • 前期准备
  • 设计
  • 功能
  • ?代码
    • 文字聊天代码
    • 语音聊天代码
  • 一些细节
  • 可以改进的地方

代码已上传到github: https://github.com/HMY777/RobotChat

效果

  1. 运行界面: 请无视这个简陋的布局
    在这里插入图片描述

  2. 文字聊天:
    在这里插入图片描述
    在这里插入图片描述

  3. 语音聊天:
    为了压缩GIF大小已经裁剪过,实际上一次对话没有这么快
    在这里插入图片描述

前期准备

  • 图灵机器人100条/天,根本不够聊啊,换成青云客API,无限制
  • 接入用百度语音,方便,快
    了解一下QT HTTP,post,get操作就行了
    ?
    青云客API文档
    百度语音API文档

设计

因为是计网的课设要赶时间所以我做得很简陋(其实是菜),所有操作都在MainWindow.cpp里面完成,一共就这几个类
在这里插入图片描述

功能

  • 文字聊天功能
    这个只涉及到图灵的API,具体流程是

    • 输入文本,按发送按钮
    • 槽函数里面发送get命令来获取请求(官方
  • 语音聊天功能

    • 录音
    • 百度API识别语音获得文本
    • 文本发送给图灵机器人获得回答文本
    • 显示回答文本和调用百度语音API播放音频

流程图,功能之后跟的是函数名。在这里插入图片描述
在这里插入图片描述

下面是代码,有一些是get比较适合,有一些是post比较适合,视情况采用就好。
? HTTP GET POST区别

?代码

文字聊天代码

青云客api get就好

//直接聊天
void MainWindow::on_SendBtn_clicked()
{QString Url="http://api.qingyunke.com/api.php?key=free&appid=0&msg="+ui->InputTextEdit->toPlainText();QUrl url;url.setUrl(Url);QNetworkRequest request(url);QNetworkAccessManager *manager=new QNetworkAccessManager(this);connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(Tuling_replyFinish(QNetworkReply*)));manager->get(request);
}

相应的槽函数,想做的好一点可以多加几个if处理异常

//解析图灵API返回的json数据
void MainWindow::Tuling_replyFinish(QNetworkReply *reply)
{QString data=reply->readAll();//读取回话信息qDebug()<<"这是返回的结果 "+data;QJsonParseError json_error;//一定要toUtf8 否则会出错!QJsonDocument json=QJsonDocument::fromJson(data.toUtf8(),&json_error);//判断有没有错if(json_error.error==QJsonParseError::NoError){if(json.isObject()){QJsonObject jsonObj=json.object();//取到text内容if(jsonObj.contains("content")){qDebug()<<"成功获取text";QJsonValue text_value=jsonObj.take("content");if(text_value.isString()){tuling_get_ans=text_value.toVariant().toString();tuling_get_ans.replace("br","\n");qDebug()<<"!!!返回的ans:"<<tuling_get_ans;}}}}reply->deleteLater();ui->OutputTextEdit->setText(tuling_get_ans);}

语音聊天代码

一些需要用到的声明和初始化

	//用于播放音频QMediaPlayer* media_player;//用于设置audio_inputQAudioDeviceInfo SpeechCurrentDevice;//用于录音,数据存储在JsonBuffer里面QAudioInput* audio_input=NULL;QBuffer* JsonBuffer=NULL;void MainWindow::AudioInit()
{const auto &&availableDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);if(!availableDevices.isEmpty()){SpeechCurrentDevice = 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");audio_input = new QAudioInput(SpeechCurrentDevice, format, this);}
}

JsonBuffer是 QBuffer* JsonBuffer=NULL;,好像每次new一个都比较慢,建议放在外面new,我因为环境原因没法测试语音功能,想改良可以自己试一下

//当按下录音按钮后 开始录音
void MainWindow::on_VoiceBtn_pressed()
{JsonBuffer=new QBuffer;JsonBuffer->open(QIODevice::ReadWrite);qDebug()<<"录音设备访问成功...";audio_input->start(JsonBuffer);qDebug()<<"录音设备运行成功...";
}//松开按钮后,结束录音,发送请求
void MainWindow::on_VoiceBtn_released()
{qDebug()<<"结束录音哦~~~";audio_input->stop();const auto &sendData=JsonBuffer->data();JsonBuffer->deleteLater();QNetworkRequest request(QUrl(p_BaiduVoice->VOP_URL));request.setRawHeader("Content-Type", "application/json");qDebug()<<"jason_speech:request设置头成功 ...";QNetworkAccessManager *manager=new QNetworkAccessManager(this);connect(manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(Baidu_VoiceToText_replyFinish(QNetworkReply *)));//这里应该放在百度类里面QJsonObject append;//设置json请求格式append["format"] = "pcm";append["rate"] = 8000;append["channel"] = 1;append["token"] = p_BaiduVoice->Access_Token;append["lan"] = "zh";append["cuid"] = p_BaiduVoice->MAC_cuid;append["speech"] = QString(sendData.toBase64());append["len"] = sendData.size();//发送HTTP post请求manager->post(request,QJsonDocument(append).toJson());
}
//声音转成文本
void MainWindow::Baidu_VoiceToText_replyFinish(QNetworkReply *reply)
{qDebug()<<"进到槽函数了哦~~";QByteArray JsonStr=reply->readAll();qDebug()<<"返回信息 "<<JsonStr;QJsonObject acceptedData(QJsonDocument::fromJson(JsonStr).object());if(acceptedData.contains("err_no")){QJsonValue version_value = acceptedData.take("err_no");if(version_value.isDouble()){int version = version_value.toVariant().toInt();if(version == 3301)QMessageBox::information(NULL,tr("识别失败"),tr("请等待一秒后开始录音,确认录音质量良好"));}}if(!acceptedData["result"].isNull()){QString message=acceptedData["result"].toArray()[0].toString();ui->InputTextEdit->setText(message);changeBaiduAudioAns(message);}
}
//当声音识别成文本后,发射信号到此函数,然后将文本发送给图灵机器人
void MainWindow::voice_post_Tuling_slot()
{qDebug()<<"successes get voice_post_Tuling_slot";QString Url="http://api.qingyunke.com/api.php?key=free&appid=0&msg="+this->voice_get_ans;QUrl url;url.setUrl(Url);QNetworkRequest request(url);QNetworkAccessManager *manager=new QNetworkAccessManager(this);//处理获得文本,连接到voice_Tuling_replyFinish函数connect(manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(voice_Tuling_replyFinish(QNetworkReply *)));manager->get(request);
}
//走语音识别的流程 这是将语音识别文本发送给图灵机器人,然后解析json
void MainWindow::voice_Tuling_replyFinish(QNetworkReply *reply)
{qDebug()<<"测试走到voice_Tuling_replyFinish...";QString data=reply->readAll();//读取回话信息qDebug()<<"这是返回的结果 "+data;QString tstr;QJsonParseError json_error;//一定要toUtf8 否则会出错!QJsonDocument json=QJsonDocument::fromJson(data.toUtf8(),&json_error);//判断有没有错if(json_error.error==QJsonParseError::NoError){if(json.isObject()){QJsonObject jsonObj=json.object();//取到text内容if(jsonObj.contains("content")){qDebug()<<"成功获取text";QJsonValue text_value=jsonObj.take("content");if(text_value.isString()){tstr=text_value.toVariant().toString();}}}}reply->deleteLater();//    获得返回文本后this->setUIString(tstr);
}

最后一步 直接从网页上播放音频

//获得图灵机器人的回答后再播放这个回答
void MainWindow::Baidu_TextToVoice_replyFinish()
{//最后一步 播放文本音频//设置url以及必要的请求格式QByteArray url="http://tsn.baidu.com/text2audio?";url.append(QString("&lan=zh"));//本机MAC地址
//    url.append(QString("&cuid=A0-8C-FD-1D-CF-0E"));url.append(QString("&cuid="+p_BaiduVoice->MAC_cuid));url.append("&ctp=1");url.append(QString("&tok="+p_BaiduVoice->Access_Token));url.append(QString("&pit=5"));url.append(QString("&per=4"));url.append(QString("&tex="));url.append(QUrl::toPercentEncoding(this->UI_ANS_String));qDebug()<<url;//播放url里面的音频media_player->setMedia(QUrl::fromLocalFile(url));media_player->play();
}

一些细节

百度的Token时间只有一个月,把上次获取token的日期写在.ini文件里面,每次判断是否需要刷新token

bool MainWindow::JudgeTokenTime() 
{//https://blog.csdn.net/qq_18286031/article/details/78538769 时间互转QSettings *setting=new QSettings("GetTokenTime.ini",QSettings::IniFormat);//当前时间QDateTime current_date_time=QDateTime::currentDateTime();QDateTime file_date_time;//读取的文件时间QString file_date_str=setting->value("/TIME/last_time").toString();file_date_time=QDateTime::fromString(file_date_str,"yyyy-MM-dd");//    qDebug()<<"file_date_time"<<file_date_time;uint stime = file_date_time.toTime_t();uint etime = current_date_time.toTime_t();int ndaysec = 24*60*60;int Day= (etime - stime)/(ndaysec) + ((etime - stime)%(ndaysec)+(ndaysec-1))/(ndaysec) - 1;//Token 有效期内if(Day<30)    return true;else{//写时间setting->beginGroup("TIME");setting->setValue("last_time",current_date_time.toString("yyyy-MM-dd"));setting->endGroup();return false;}
}
void MainWindow::TokenInit()
{if(JudgeTokenTime()) return;QUrl url=QUrl(p_BaiduVoice->Get_Token_URL+"?grant_type=client_credentials"+"&client_id="+p_BaiduVoice->API_KEY+"&client_secret="+p_BaiduVoice->Secret_Key);QNetworkAccessManager *manager=new QNetworkAccessManager(this);QNetworkRequest request(url);connect(manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(get_Token_slot(QNetworkReply *)));manager->get(request);
}void MainWindow::get_Token_slot(QNetworkReply *reply)
{QByteArray JsonStr=reply->readAll();qDebug()<<JsonStr; QJsonObject acceptedData(QJsonDocument::fromJson(JsonStr).object());if(acceptedData.contains("access_token")){QJsonValue json_value = acceptedData.take("access_token");p_BaiduVoice->Access_Token=json_value.toString();qDebug()<<"success get token:"<<p_BaiduVoice->Access_Token;}
}

百度语音还需要唯一标识符即MAC地址来POST,下面是获得MAC的方法

//获取本机MAC地址
void MainWindow::getMacAddress()
{QList<QNetworkInterface> nets = QNetworkInterface::allInterfaces();// 获取所有网络接口列表int nCnt = nets.count();for(int i = 0; i < nCnt; i ++){// 如果此网络接口被激活并且正在运行并且不是回环地址,则就是我们需要找的Mac地址if(nets[i].flags().testFlag(QNetworkInterface::IsUp) && nets[i].flags().testFlag(QNetworkInterface::IsRunning) && !nets[i].flags().testFlag(QNetworkInterface::IsLoopBack)){p_BaiduVoice->MAC_cuid = nets[i].hardwareAddress();break;}}p_BaiduVoice->MAC_cuid.replace(":","-");qDebug()<<"自动获取的MAC地址 "<<p_BaiduVoice->MAC_cuid;
}

可以改进的地方

QT可以获取麦克风音量,然后开一个线程判断当前麦克风是否超过某个值,超过了就开始录音,然后识别…这样更智能,不用按按钮说话。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/18190.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序和百度的语音识别接口

介绍 因为项目需要,使用到了微信小程序和百度的语音接口 现在将项目中的一个小模块拿出来单独分享. 技术关键字 微信小程序百度语音接口nodejs,expressfluent-ffmegp 环境 windows 10vs code 1.20.1微信小程序开发工具 1.02.1802270花生壳-提供域名和内容穿透-用于方便本地…

你想不到,韩国女团最喜欢的英文单词是这些

如果你也想赚钱&#xff0c;实现财务自由&#xff0c;但接触不到优质的人脉和资源&#xff0c;可以到公June浩&#xff1a;成长home&#xff0c;发"资源" &#xff0c;就会看到我吐血整理的168条保姆级零基础吸金秘籍&#xff0c;跟着我一起亲历毕业5年、创业3年、从…

太逼真!这个韩国虚拟女团你追不追?

“她们看上去太像真人了”&#xff0c; 韩国虚拟女团MAVE的首支MV和打歌舞台引发网友阵阵惊呼。现在&#xff0c;她们的舞蹈已经有真人在挑战了。 这一组虚拟人的“逼真”倒不在脸&#xff0c;主要是MAVE女团的舞台动作接近自然&#xff0c;不放近景看&#xff0c;基本可以达到…

NBA球星数据可视化分析-FineBI

目录 一、实验&#xff08;实训&#xff09;目的 二、实验&#xff08;实训&#xff09;原理或方法 三、仪器设备、材料 四、实验&#xff08;实训&#xff09;步骤 五、实训记录及结果 <---------------------------------木易白驹----------------------------------…

【第十一届泰迪杯数据挖掘挑战赛】A 题:新冠疫情防控数据的分析 思路+代码(持续更新)

【第十一届泰迪杯数据挖掘挑战赛】A 题&#xff1a;新冠疫情防控数据的分析 思路代码&#xff08;持续更新&#xff09; 问题背景解决问题代码下载数据分析Task1Task2Task3Task4 问题背景 自 2019 年底至今&#xff0c;全国各地陆续出现不同程度的新冠病毒感染疫情&#xff0c;…

【数据博彩】如何使用大数据机器学习预测NBA比赛结果?

引言 伴随着大数据时代的来临&#xff0c;机器学习、深度学习、人工智能等越来越多的出现在我们的视野中&#xff0c;数据技术正在颠覆着包括体育和博彩在内的各行各业&#xff0c;本文着手于使用大数据机器学习预测NBA比赛结果&#xff0c;希望给相关行业从业者和爱好者带来启…

用Python采集球员信息,成功预测到了球赛胜负?

前言 嗨嗨&#xff0c;最近看球赛的朋友多吗 emm怎么说&#xff0c;我对这个虽然兴趣不是很大 但是还是想跟朋友赌赌&#xff0c;自己对这些球员也不是很熟悉&#xff0c;索性叫我的好同事帮我用Python采集了各国球员的一些信息&#xff0c;没料到竟预测成功了&#xff01; …

大火的ChatGPT能为自动驾驶带来什么?

/导读/ 最近的科技圈&#xff0c;大家都被微软推出的ChatGPT刷屏&#xff0c;作为工智能公司OpenAI于2022年11月推出的聊天机器人&#xff0c;其能够通过学习和理解人类的语言来进行对话&#xff0c;还能根据聊天的上下文进行互动&#xff0c;甚至能完成撰写邮件、视频脚本、文…

神器Ai工具箱全集,不用找了你想要的Ai都在这里。

周报生成器 https://weeklyreport.avemaria.fun/zh AI写作 README 生成器 https://readme.rustc.cloud/zh AI写作 AI做决定 https://rationale.jina.ai AI助手 AI自动后端 https://www.autobackend.dev AI代码 AI上色 https://palette.fm AI图设 AI简历 https:…

AI面试必刷算法题 附答案和解析 --持续更新中

面试中发现很多同学一股脑优化、润色项目经历&#xff0c;但聊到基本的算法&#xff0c;反而会一脸懵X&#xff0c;得空整理下算法题给大家&#xff0c;希望对你有帮助。 1. tail(head(tail(C))) ( ) 已知广义表: A(a,b), B(A,A), C(a,(b,A),B), 求下列运算的结果:&#xff08…

google大模型Bard下场【谷歌版本的ChatGPT】

本文需要会可学上网&#xff0c;不会直接拉到底部 google大模型开始下场了https://bard.google.com/,点击链接用谷歌账户登录就能使用 步骤 第一步&#xff1a;如果你有谷歌账号&#xff0c;你所做的就只是登录【一个谷歌账号&#xff0c;可以帮你在大部分地方免登录&#x…

当 chatGPT 被职场 PUA ,笑麻了

大家最近是不是被 chatGPT 刷屏了&#xff1f;简单来说&#xff0c;chatGPT 是一个智能聊天引擎。 那 chatGPT 和小爱同学、 siri 有什么区别呢&#xff1f; 如果体验过的朋友&#xff0c;能感受到区别还是很大&#xff0c;chatGPT 的智能表现过于优秀&#xff0c;远远超过了这…

关于ChatGPT中文版,看看Openai官网怎么说!

目前&#xff0c;OpenAI官网上仅提供了英文版的ChatGPT模型和API。这意味着官方只提供了英文对话生成的支持和资源。对于中文用户来说&#xff0c;OpenAI官网上并没有官方发布的ChatGPT中文版本。 然而&#xff0c;尽管OpenAI官网未发布ChatGPT中文版&#xff0c;一些第三方开发…

您遇到过网页抓取时被封IP的情况吗?

​网站如何检测网络爬虫&#xff1f; 网络爬取和网络抓取相辅相成&#xff0c;对于公共数据收集来说至关重要。电子商务企业会使用网络抓取工具从各个网站收集新数据。然后&#xff0c;将抓取到的信息用于改进业务和营销策略。 对于那些不知道如何避免抓取网站时被封IP的人来说…

检查IP或端口是否被封

遇到IP连接超时&#xff0c;想要确认是否被封&#xff0c;可通过以下几个方式检验&#xff1a; IP可用性检测工具 - Tools大全在线工具 Ping, mtr, dig and TCP port check from multiple locations 端口扫描 - 站长工具

爬虫ip在使用中被封了如何解决 ?

爬虫是最近几年非常热门的互联网抓取技术&#xff0c;能够帮助数据公司进行大数据分析&#xff0c;极大的降低人工成本。 那么在爬虫进行批量采集的时候&#xff0c;有时候ip地址也会被封&#xff0c;这具体是什么原因引起的&#xff1f; 为了能够高效的爬虫工作&#xff0c;…

如何预防服务器IP被封

一:被流量攻击封堵 在日常使用服务器时&#xff0c;一定要及时的注意网络流量攻击&#xff0c;一旦自己的网站遭到攻击&#xff0c;而服务器的IP是没有防御的&#xff0c;可能就会导致服务器IP遭到封堵&#xff0c;IP被封堵&#xff0c;一般情况下是封堵3个小时左右&#xff0…

IP被封检测和端口被封检测方法分享

国外VPS的IP被封一直是比较热门的话题&#xff0c;我们在使用国外VPS搭建网站或者学习Linux技术时首先要保证IP可用性&#xff0c;以及端口的可访问性&#xff0c;老王自己就有好几台国外VPS&#xff0c;这里分享下自己平常检测IP是否被封&#xff0c;以及端口是否被封的方法。…

研报精选230512

目录 【行业230512山西证券】有色金属行业周报&#xff1a;基本金属普跌&#xff0c;锂价持续回弹 【行业230512湘财证券】新材料行业周报&#xff1a;五一前后各板块震荡下行&#xff0c;节后稀土价格跌后企稳&#xff0c;锂源现止跌迹象 【行业230512山西证券】基础化工2022年…

2023年,我的儿子刚从美国名校毕业,就失业了...

前不久&#xff0c;朋友圈里一篇名为《2023年&#xff0c;我的儿子刚从美国名校毕业&#xff0c;就失业了…》的文章火爆全网。 故事里的男孩出生于一个中产阶级家庭&#xff0c;从每年12万的幼儿园开始一路接受了优质教育&#xff0c;最终不负众望从美国前50名校的商学院毕业…