Qt上的UDP语音聊天

UDP voice chat on Qt

本文关键字:语音聊天 UDP 上的 Qt      更新时间:2023-10-16

首先,我试图通过本地主机上的UDP协议将音频数据从一个进程发送到另一个进程。

首先,程序从麦克风中读取语音,并通过UDP套接字发送:

#include <QApplication>
#include <QIODevice>
#include <QtMultimediaKit/QAudioOutput>
#include <QtMultimediaKit/QAudioInput>
#include <QtMultimediaKit/QAudioFormat>
#include <QUdpSocket>
int main(int argc, char** argv){
    QApplication app(argc, argv);
    QAudioFormat format;
    format.setSampleRate(128000);
    format.setChannelCount(1);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);
    QAudioInput* input = new QAudioInput(format);
    QUdpSocket* socket = new QUdpSocket();
    socket->connectToHost("127.0.0.1", 1002);
    input->start(socket);
    return app.exec();
}

我检查了Wireshark发送的数据,我认为数据已经发送。1002端口上每秒有这么多UDP包。

第二个程序应该读取UDP包并在输出设备中播放:

#include "UDPPlayer.h"
#include <QDebug>
UDPPlayer::UDPPlayer(){
    socket = new QUdpSocket();
    socket->bind(1002);
    QAudioFormat format;
    format.setSampleRate(128000);
    format.setChannelCount(1);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);
    output = new QAudioOutput(format);
    connect(socket, SIGNAL(readyRead()), this, SLOT(playData()));
}
void UDPPlayer::playData(){
    qDebug() << "data";
    output->start(socket);
}

问题如下:从未调用playData()(从未打印"数据")。这是否意味着套接字永远不是readyRead?但我看到了Wireshark的这些包裹。我做错了什么?

您需要确保输入和输出设备支持所使用的格式。

您还需要从输出设备创建一个QIODevice,以便向其写入数据,这样的数据将通过socket->readDatagram() 获得

你需要做这样的事情:

main.cpp:

#include <QApplication>
#include <QIODevice>
#include <QtMultimedia/QAudioOutput>
#include <QtMultimedia/QAudioInput>
#include <QtMultimedia/QAudioFormat>
#include <QUdpSocket>
#include "udpplayer.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    new UDPPlayer();
    QAudioFormat format;
    format.setSampleRate(128000);
    format.setChannelCount(1);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);
    //If format isn't supported find the nearest supported
    QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
    if (!info.isFormatSupported(format))
        format = info.nearestFormat(format);
    QAudioInput* input = new QAudioInput(format);
    QUdpSocket* socket = new QUdpSocket();
    socket->connectToHost("127.0.0.1", 1002);
    input->start(socket);
    return a.exec();
}

udpplayer.h:

#include <QObject>
#include <QtMultimedia/QAudioOutput>
#include <QtMultimedia/QAudioInput>
#include <QtMultimedia/QAudioFormat>
#include <QUdpSocket>
class UDPPlayer : public QObject
{
    Q_OBJECT
public:
    explicit UDPPlayer(QObject *parent = 0);
private slots:
    void playData();
private:
    QAudioOutput *output;
    QUdpSocket *socket;
    QIODevice *device;
};

udpplayer.cpp:

UDPPlayer::UDPPlayer(QObject *parent) : QObject(parent)
{
    socket = new QUdpSocket();
    socket->bind(1002);
    QAudioFormat format;
    format.setSampleRate(128000);
    format.setChannelCount(1);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);
    QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
    if (!info.isFormatSupported(format))
        format = info.nearestFormat(format);
    output = new QAudioOutput(format);
    device = output->start();
    connect(socket, SIGNAL(readyRead()), this, SLOT(playData()));
}
void UDPPlayer::playData()
{
    //You need to read datagrams from the udp socket
    while (socket->hasPendingDatagrams())
    {
        QByteArray data;
        data.resize(socket->pendingDatagramSize());
        socket->readDatagram(data.data(), data.size());
        device->write(data.data(), data.size());
    }
}