当前位置: 首页 > news >正文

做网站联系客服按钮代码烟台seo外包

做网站联系客服按钮代码,烟台seo外包,电商网站建设参考文献,网络科技网站建设实现功能主要思路:在网页端进行语音输入,PC机可以实时接收并播放语音流。 此时,Qt程序做客户端,Web端做服务器,使用QWebSocket进行通讯,实时播放接收的语音流。 功能实现 想要实现该功能,需要…

实现功能主要思路:在网页端进行语音输入,PC机可以实时接收并播放语音流。

此时,Qt程序做客户端,Web端做服务器,使用QWebSocket进行通讯,实时播放接收的语音流。

功能实现

想要实现该功能,需要完成以下两大部分。

第一部分:QWebSocket通讯实现。(简单

第二部分:语音流实时播放功能。(稍微有点难度

接下来对于该功能实现进行具体的讲解。

1:建立通讯

1.1:创建QWebSocket通讯

添加头文件

#include <QWebSocketServer>
#include <QWebSocket>

声明WebSocket对象并响应消息

m_pWebClient = new QWebSocket;
connect(m_pWebClient, &QWebSocket::connected, this, &QWebSocketManager::MsgRecievd_Server_Connected);
connect(m_pWebClient, &QWebSocket::disconnected, this, &QWebSocketManager::MsgRecievd_Server_Disconnected);
connect(m_pWebClient, &QWebSocket::textMessageReceived, this, &QWebSocketManager::MsgRecievd_Server_TextMessageReceived);
connect(m_pWebClient, &QWebSocket::binaryMessageReceived, this, &QWebSocketManager::MsgRecievd_Server_BinaryMessageReceived);

分别响应了:连接、断开、接收字符串内容、接收二进制内容

1.2:建立心跳包

一说到通讯,首先想到的应该是心跳包机制。在与Web通讯也是如此,为了防止掉线,程序中也需要设定一个心跳包机制。

为了保证心跳包有连接,但不频繁发送,可以采用在无数据发送时,采用3秒~10秒之间发送一条。

使用方法:QTimer进行心跳包发送。

在程序使用过程中,不需要精确发送时间,只要在指定时间范围内(3s~10s)发送就可以了。

定义时间更新变量

DWORD m_dwReciveTime;//接收到WebSocket消息的时间

每次接收到web服务端发送数据时,实时更新接收时间。

void QWebSocketManager::MsgRecievd_Server_TextMessageReceived(const QString &message)
{qDebug() << QStringLiteral("接收内容:") << message;m_dwReciveTime = GetTickCount(); //更新接收时间
}
void QWebSocketManager::MsgRecievd_Server_BinaryMessageReceived(const QByteArray &message)
{qDebug() << QStringLiteral("接收内容:") << message;m_dwReciveTime = GetTickCount(); //更新接收时间
}

在项目中重写了两个接收消息,所以都需要实时更新接收时间。

此时需要开启定时器,假设每间隔3秒访问一次,定时器核心代码,如下:

DWORD dwCalc = GetTickCount() - pThis->m_dwReciveTime; //时间差 = 最新时间 - 模拟人上传数据时间
if (dwCalc < g_nWebSocektHeartTime)
{//时间差 < 最小心跳包
}
else if ((dwCalc > g_nWebSocektHeartTime) && (dwCalc < g_nWebSocketLostConnectTime))
{//发送心跳包协议
}
else if(dwCalc > g_nWebSocketLostConnectTime)
{qDebug() << QStringLiteral("连接超时!");
}

注意:这是我在通讯过程中进行了一点点小小优化,大家也可以采用哟~

每次触发定时器时,并没有直接发送心跳包,而是当间隔超过10秒后代表断开连接了。

1.3:接收web端音频流

在1.1中实现了QWebSocket的两个消息数据接收:textMessageReceived、binaryMessageReceived

具体使用哪个消息,需要对应服务端是如何发送的,一般而言,音频流采用二进制流的方式比较安全。

接收语音流数据,实例代码如下:

void QWebSocketManager::MsgRecievd_Server_BinaryMessageReceived(const QByteArray &message)
{//qDebug() << QStringLiteral("MsgRecievd_Server_BinaryMessageReceived,内容:") << message;
}

接收到音频流以后,该如何进行播放呢?

接下来就需要进行第二步重要功能:语音流实时播放功能

2:语音流实时播放功能

在这里我用的是:QAudioOutput类,使用该类方便操作。

2.1:初始化输出音频参数

QAudioFormat audio_out_format; 
//设置录音的格式
audio_out_format.setSampleRate(8000); //采样率
audio_out_format.setChannelCount(1); //通道数
audio_out_format.setSampleSize(16);
audio_out_format.setCodec("audio/pcm"); //编码格式
audio_out_format.setByteOrder(QAudioFormat::LittleEndian); //样本是小端字节顺序
audio_out_format.setSampleType(QAudioFormat::SignedInt); //样本类型QAudioDeviceInfo  info(QAudioDeviceInfo::defaultOutputDevice());m_pAudioOutput = new QAudioOutput(audio_out_format);
m_pStreamOutput = m_pAudioOutput->start();
m_nPeriodSize = m_pAudioOutput->periodSize();

代码分析:

录音的格式要与服务端输入的音频流格式才能保证客户端接收到清晰完整的音频流。

此时,需要注意的是最后一行代码:m_nPeriodSize = m_pAudioOutput->periodSize();

这是实现播放音频流的核心之一!

2.2:播放接收的音频流

针对这部分实现方式,我经历了以下几个步骤,已踩坑,希望对大家有用!

简单有问题的实现方式
void QWebSocketManager::MsgRecievd_Server_BinaryMessageReceived(const QByteArray &message)
{//qDebug() << QStringLiteral("MsgRecievd_Server_BinaryMessageReceived,内容:") << message;m_dwReciveTime = GetTickCount(); //更新接收时间m_pStreamOutput->write(array); //播放音频流
}

接收到音频流就直接播放。使用这种方法会发现,音频是可以播放,但是叽里呱啦的,每次智能听到说话的第一个字,其余的全都听不到了。

此时,你会怀疑是不是服务端传入的音频流不正确呢?因为客户端可以播放声音。如果你沿着这条路走,那你就错了。

原因:之所以只能听到说话的第一个字是因为,频繁地接收数据,上一次接收的音频流还未播放完毕就立刻播放下一条音频流,所以会出现这种问题了。

那么,该如何解决这种问题呢?

在这里就用到了初始化时我所说的核心代码了。

m_nPeriodSize 是每次播放一条完整音频格式的大小,服务端传入的数据大小我们无法控制,但是可以在播放时,每次取m_nPeriodSize 大小的数据进行播放,就能保证数据的完整性。

那么,如何知道上一次播放的音频流已经完成了呢?

使用m_pAudioOutput->bytesFree(),循环进行判断,只有当释放的缓存数小于m_nPeriodSize 才能够继续播放音频流

下面为大家展示有效地实现方法。

复杂有效的实现方式
void QWebSocketManager::MsgRecievd_Server_BinaryMessageReceived(const QByteArray &message)
{//qDebug() << QStringLiteral("MsgRecievd_Server_BinaryMessageReceived,内容:") << message;m_dwReciveTime = GetTickCount(); //更新接收时间{std::lock_guard<std::mutex> lck(m_mutexPcm);  //C11用法m_ArrayAudio.append(message);}if (m_bRunningAudio == false){m_bRunningAudio = true; //开启数据处理线程m_threadAudio = std::thread(&QWebSocketManager::ThreadProcessingPCMData, this, this);}
}

代码解析:

当接收到第一条音频数据时,开启线程,将音频播放处理放到线程中进行判断,只有把上一次播放的音频缓存释放完成后,才能够从缓存m_ArrayAudio中获取m_nPeriodSize大小的数据

线程实现代码,如下:

unsigned int QWebSocketManager::ThreadProcessingPCMData(void* pParam)
{QWebSocketManager* pThis = reinterpret_cast<QWebSocketManager*>(pParam);while (pThis->m_bRunningAudio == true){//只有满足一个完整包数据时,才需要处理if (pThis->m_ArrayAudio.count() >= m_nPeriodSize){if (m_pAudioOutput->bytesFree() < m_nPeriodSize){Sleep(5);continue; //当前音频释放大小 < 固定大小时,不处理}std::lock_guard<std::mutex> lck(m_mutexPcm);  //C11用法QByteArray array = pThis->m_ArrayAudio.mid(0, m_nPeriodSize);pThis->m_pStreamOutput->write(array);pThis->m_ArrayAudio.remove(0, m_nPeriodSize);qDebug() << QStringLiteral("处理一次完整的音频,此时剩余大小 = ") << pThis->m_ArrayAudio.count();}else{Sleep(1000);}}return 0;
}

以上就是核心的实现流程了,如果需要查看原始代码的,请看下面链接

Qt中使用QWebSocket与Web进行通讯,实时语音通话

我是糯诺诺米团,一名C++开发程序媛~

http://www.hkea.cn/news/409481/

相关文章:

  • 企业网站建设三个原则百度指数资讯指数是指什么
  • 房地产集团网站建设方案软文文案案例
  • 阜蒙县建设学校网站是什么北京seo编辑
  • 珠海建设局网站十大经典事件营销案例分析
  • 创建网站开发公司互联网推广引流是做什么的
  • 万盛集团网站建设seo网站推广全程实例
  • 做教育的网站需要资质吗网站怎么开发
  • 微网站怎么做滚动中国万网域名注册官网
  • 个人如何免费建网站seo在线优化工具 si
  • 双线主机可以做彩票网站吗网络推广合作协议
  • 做外贸的b2b网站域名批量查询系统
  • 建设网站需要哪些职位网站建设策划书
  • 苏州网站建设哪里好网站点击排名优化
  • 网站建设收费标准策划百度推广关键词越多越好吗
  • 网站怎么做更新吗如何建立网页
  • 国外建设工程招聘信息网站tool站长工具
  • 专业做相册书的网站电商网站建设制作
  • 银川网站开发公司电话东莞网
  • 环境保护局网站管理制度建设百度指数的主要功能有
  • 安装wordpress提示500错误关键词优化的策略有哪些
  • 企业网站建设公司排名深圳高端seo公司助力企业
  • 做网站套餐网站seo
  • 网站上的代码网页怎么做的下载百度软件
  • 网站功能模块建设搜狗推广
  • 网站做推广有用吗网站页面设计
  • 做简报的网站广州搜发网络科技有限公司
  • 南乐县住房和城乡建设局网站制作网站的步骤是什么
  • 金华做网站最专业的公司搜易网提供的技术服务
  • wordpress适合门户网站吗怎么营销自己的产品
  • 常用的网站类型有哪些seo优化专员编辑