如何在Qt的线程中通过tcp发送音频流?

时间:2016-08-12 13:29:49

标签: c++ multithreading qt audio tcp

我试图通过TCP在主线程以外的线程中发送来自麦克风的音频流。因此,我设置了一台服务器,我正在监听传入的连接。一旦客户端连接,我想发送它的音频流。我已经阅读了有关QTcpServer,多线程和QtMultimedia的Qt文档。我还查看了this网站上有关Qt中多线程和TCP服务器的示例代码。问题是我在运行时得到的这条消息:

QObject:无法为位于其他线程中的父级创建子级。 (Parent是QNativeSocketEngine(0xae802a78),父线程是MyThread1(0x1856d28),当前线程是QThread(0x1838aa0)

这是我的代码:

在文件myserver.h中

#ifndef MYSERVER_H
#define MYSERVER_H

#include <QtNetwork>
#include <QTcpServer>
#include <mythread.h>
#include <QtMultimediaKit/QAudioFormat>
#include <QtMultimediaKit/QAudioInput>
#include <QtMultimediaKit/QAudioDeviceInfo>


class MyServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit MyServer(QObject *parent = 0);
    void startServer();

signals:

public slots:

protected:
    void incomingConnection(int socketDescriptor);

private:
    QAudioInput *audioInput;
};

#endif // MYSERVER_H

在文件myserver.cpp

#include "myserver.h"

MyServer::MyServer(QObject *parent) :
    QTcpServer(parent)
{
}

void MyServer::startServer()
{
    int port = 12345;

    QString ipAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();

    for (int i = 0; i < ipAddressesList.size(); ++i)
    {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&  ipAddressesList.at(i).toIPv4Address())
        {
            ipAddress = ipAddressesList.at(i).toString();
            break;
        } 
    }

    if(!this->listen( QHostAddress(ipAddress),port ) )
    {
        qDebug() << "Could not start server";
    }
    else
    {
        qDebug() << "The server is running on\n\nIP: "<< ipAddress;
        qDebug() << "\nport: " << this->serverPort() << "\n\n";
    }
}

void MyServer::incomingConnection(int socketDescriptor)
{
    qDebug() << socketDescriptor << " Connecting...";

    QAudioFormat format;

    format.setSampleRate(44100);
    format.setChannelCount(1);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);

    QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
    if (!info.isFormatSupported(format))
    {
        qWarning()<<"default format not supported try to use nearest";
        format = info.nearestFormat(format);
    }

    audioInput = new QAudioInput(format, this);

    MyThread1 *thread = new MyThread1(socketDescriptor,audioInput, this);

    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

    thread->start();
}
文件mythread.h中的

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QTcpSocket>
#include <QDebug>
#include <QtMultimediaKit/QAudioInput>

class MyThread1 : public QThread
{
    Q_OBJECT
public:
    explicit MyThread1( int ID, QAudioInput *spk, QObject *parent = 0);
    void run();

signals:
    void error(QTcpSocket::SocketError socketerror);

public slots:
    void sendData();
    void disconnected();

private:
    QTcpSocket *socket;
    int socketDescriptor;
    QAudioInput *speaker;
};
#endif // MYTHREAD_H
文件mythread.cpp中的

#include "mythread.h"

MyThread1::MyThread1( int ID, QAudioInput *spk, QObject *parent) :
    QThread(parent)
{
    this->socketDescriptor = ID;
    this->speaker = spk;
}

void MyThread1::run()
{
    qDebug() << " Thread started";

    socket = new QTcpSocket();

    if(!socket->setSocketDescriptor(this->socketDescriptor))
    {
        emit error(socket->error());
        return;
    }

    connect( speaker->start(), SIGNAL( readyRead() ), this, SLOT( sendData() ) , Qt::DirectConnection);
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));

    qDebug() << socketDescriptor << " Microphone connected";

    exec();
}

void MyThread1::sendData()
{
    QByteArray Data = speaker->start()->readAll();
    QDataStream l_vStream(&Data, QIODevice::WriteOnly);

    l_vStream.setByteOrder(QDataStream::LittleEndian);

    socket->write(Data, Data.length());
    socket->waitForBytesWritten();
}

void MyThread1::disconnected( )
{
    qDebug() << socketDescriptor << "Mic Disconnected";

    speaker->stop();
    delete speaker;

    socket->deleteLater();
    exit(0);
}

在main.cpp文件中

#include <QCoreApplication>
#include <myserver.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyServer server;
    server.startServer();

    return a.exec();
}

真的很感激任何帮助。感谢。

0 个答案:

没有答案