Qt上的UDP语音聊天

时间:2014-09-07 18:04:54

标签: c++ qt sockets udp

首先,我尝试通过localhost上的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()(&#34;数据&#34;永不打印)。这是否意味着套接字永远不会readyRead?但是我通过Wireshark看到了这些软件包。我做错了什么?

1 个答案:

答案 0 :(得分:2)

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

您还需要从输出设备创建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());
    }
}