通过QT_TCP和百度AI接口实现的支持语音输入的多人聊天室

        本项目主要通过tcp实现的并发聊天室再加上百度ai的语音识别接口,实现的支持语音识别输入的并发聊天室。

1.服务器

        服务器设置的一个没有ui的界面的软件,实现聊天数据的中介

        

    2.客户端

                客户端通过qt写了相应的ui,并加入了语音识别的功能

            

 客户端上的按钮通过相应的槽函数,分别控制着不同的功能

name后的lineEdit-> 进入聊天室使用的昵称

connect -> 连接入聊天室,连接成功后connect变化为disconnect,点击即断开连接

中间的Text Browser ->信息交互界面

Text Browser下的Line Edit ->输入需要发送的消息支持手动输入和语音转化输入

pushbutton->按住说话,按下后进行录音,松开进行识别并将识别结果放入上边的LineEdit

pushbutton->发送,按下按钮将信息发送至聊天室

pushbutton->清楚,如果写入信息有误或者不想发送,按下可清空信息框内信息

3. 运行结果

         

   

4.代码

        1.tcpserver.cpp

#include "Server.h"

Server::Server(QObject *parent) : QObject(parent)
{

}

void Server::startServer()
{

    allClients = new QVector<QTcpSocket*>;

    chatServer = new QTcpServer();
    // 限制同时最大连接数为10
    chatServer->setMaxPendingConnections(10);

    connect(chatServer, SIGNAL(newConnection()), this, SLOT(newClientConnection()));
    // 监听端口8081
    if (chatServer->listen(QHostAddress::Any, 8001))
    {
        qDebug() << "Server has started. Listening to port 8001.";
    }
    else
    {
        qDebug() << "Server failed to start. Error: " + chatServer->errorString();
    }

}

void Server::sendMessageToClients(QString message)
{
    if (allClients->size() > 0)
    {

        for (int i = 0; i < allClients->size(); i++)
        {
            if (allClients->at(i)->isOpen() && allClients->at(i)->isWritable())
            {
                allClients->at(i)->write(message.toUtf8());
            }
        }
    }

}

void Server::newClientConnection()
{

    QTcpSocket* client = chatServer->nextPendingConnection();

    QString ipAddress = client->peerAddress().toString();
    int port = client->peerPort();

    connect(client, &QTcpSocket::disconnected, this, &Server::socketDisconnected);

    connect(client, &QTcpSocket::readyRead, this, &Server::socketReadyRead);

    connect(client, &QTcpSocket::stateChanged, this, &Server::socketStateChanged);

    allClients->push_back(client);
    qDebug() << "Socket connected from " + ipAddress + ":" + QString::number(port);
}


void Server::socketDisconnected()
{

    QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
    QString socketIpAddress = client->peerAddress().toString();
    int port = client->peerPort();
    qDebug() << "Socket disconnected from " + socketIpAddress + ":" + QString::number(port);
}


void Server::socketReadyRead()
{

    QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
    QString socketIpAddress = client->peerAddress().toString();
    int port = client->peerPort();
    QString data = QString(client->readAll());
    qDebug() << "Message: " + data + " (" + socketIpAddress + ":" + QString::number(port) + ")";

    sendMessageToClients(data);
}


void Server::socketStateChanged(QAbstractSocket::SocketState state)
{
    QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
    QString socketIpAddress = client->peerAddress().toString();
    int port = client->peerPort();
    QString desc;

    if (state == QAbstractSocket::UnconnectedState)
        desc = "The socket is not connected.";
    else if (state == QAbstractSocket::HostLookupState)
        desc = "The socket is performing a host name lookup.";
    else if (state == QAbstractSocket::ConnectingState)
        desc = "The socket has started establishing a connection.";
    else if (state == QAbstractSocket::ConnectedState)
        desc = "A connection is established.";
    else if (state == QAbstractSocket::BoundState)
        desc = "The socket is bound to an address and port.";
    else if (state == QAbstractSocket::ClosingState)
        desc = "The socket is about to close (data may still be waiting to be written).";
    else if (state == QAbstractSocket::ListeningState)
        desc = "For internal use only.";
    qDebug() << "Socket state changed (" + socketIpAddress + ":" + QString::number(port) + "): " + desc;
}

        tcpclient:

                语音识别处理:

#include "speech.h"
QString accessToken;
speech::speech(QObject *parent) : QObject(parent)
{

}

QString speech::speechIdentify(QString fileName)
{
//    获取access_token;
    //QNetworkRequest request(QUrl(QString("http://openapi.baidu.com/oauth/2.0/token?")));
    QString tokenUrl = "http://openapi.baidu.com/oauth/2.0/token?";
//    qDebug() << tokenUrl;
    QMap<QString, QString> header;
    header.insert(QString("content-Type"), QString("audio/pcm;rate=16000"));

    QByteArray requestData = QString("grant_type=client_credentials&client_id=%1&client_secret=%2&").arg(client_id).arg(client_secret).toLatin1();//发送的内容
    QByteArray replyData;
    Http m_http;
    bool result = m_http.post_sync(tokenUrl, header,requestData, replyData);
    if(result){
        QString key = "access_token";
        accessToken = getJsonValue(replyData, key);
        //qDebug() << "11111111111";

    }
    else{
        qDebug() << "access failed!!!!";
    }
    //识别语音
    QString speechUrl = QString(baiduspeechUrl).arg(QHostInfo::localHostName()).arg(accessToken);
    QFile file;
    requestData.clear();
    file.setFileName(fileName);
    file.open(QIODevice::ReadOnly);
    requestData = file.readAll();
    file.close();
    //再次发起请求
    replyData.clear();
    result = m_http.post_sync(speechUrl, header, 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(jsonDocument.isObject()){
        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();//数组
                    QJsonValue jv = arr.at(0);
                    return jv.toString();
                }
            }
        }
    }
    return "";

}

        client主体:

                

#include "widget.h"
#include "ui_widget.h"
#include "http.h"
#include <QObject>

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("松开识别");
    audio = new Audio;
    audio->startAudio("1.pcm");//
}

void Widget::on_pushButton_released()
{
//    停止录音
    audio->stopAudio();
//    修改按钮文字
    ui->pushButton->setText("开始识别");
//    开始识别
    speech m_speech;
    QString text = m_speech.speechIdentify("1.pcm");
    ui->lineEdit->setText(text);

    ui->pushButton->setText("按住说话");
}

void Widget::on_pushButton_2_clicked()
{
    ui->lineEdit->clear();

}
void Widget::on_connectButton_clicked()
{
    if (!connectedToHost)
    {
        // create a QTcpSocket object called socket and make it connect to a host at 127.0.0.1 on port 8801.
        socket = new QTcpSocket();
        
        connect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
        connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
        connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));

        socket->connectToHost("127.0.0.1", 8001);
    }
    else
    {
        QString name = ui->nameInput->text();
        socket->write("<font color=\"Orange\">" + name.toUtf8() + " has left the chat room.</font>");
        socket->disconnectFromHost();
    }

}

void Widget::socketConnected()
{
    qDebug() << "Connected to server.";
    printMessage("<font color=\"Green\">Connected to server.</font>");
    QString name = ui->nameInput->text();
    socket->write("<font color=\"Purple\">" + name.toUtf8() + " has joined the chat room.</font>");
    ui->connectButton->setText("Disconnect");
    connectedToHost = true;
}

void Widget::socketDisconnected()
{
    qDebug() << "Disconnected from server.";
    printMessage("<font color=\"Red\">Disconnected from server.</font>");
    ui->connectButton->setText("Connect");
    connectedToHost = false;
}

void Widget::socketReadyRead()
{
    ui->chatDisplay->append(socket->readAll());
}

void Widget::printMessage(QString message)
{
    ui->chatDisplay->append(message);
}


void Widget::on_sendButton_clicked()
{
    QString name = ui->nameInput->text();
    QString message = ui->lineEdit->text();
    socket->write("<font color=\"Blue\">" + name.toUtf8() + "</font>: " + message.toUtf8());
    ui->lineEdit->clear();
}


相关源码:

        聊天室1.0 · mihuiyu-YunYang/通过QT_TCP和百度AI接口实现的支持语音输入的多人聊天室 - 码云 - 开源中国 (gitee.com)

注:该项目仅做学习使用,如有侵权联系删除,

邮箱2217258154@qq.com

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值