Streaming audio

0

Cześć, przymierzam się do prostej aplikacji, której zadaniem będzie streamowanie dźwięku z klienta na komputer z uruchomionym serwerem (a poźniej może na jakiś serwer streamingowy w sieci). Na razie jestem na etapie nagrywania dźwięku do pliku za pomocą klasy QMediaRecorder. Z jakiej biblioteki najlepiej skorzystać do tego celu (w celu streamingu audio)? QTcpSocket to ogarnie? I pytanie odnośnie sieci... Aby przesłać cokolwiek przez sieć z jednego komputera na drugi muszę znać adres IP odbiorcy. Muszę mieć otwarty port danej usługi. Wiadomo, że większość komputerów to komputery w sieci lokalnej. Więc kiedy dane są przesyłane na dany port, a znany jest adres sieci, przekierowuje dane z tego portu na routerze na konkretny adres w sieci lokalnej. Nie ma prostszego sposobu?

0

Jak już wybrałeś Qt to obejrzyj dokładnie przykłady które są domyślnie zainstalowane w QtCreator
Potem obejrzyj projekty podobnego do tego co chcesz zrobić https://github.com/topics/audio-streaming?l=c%2B%2B
Potem do roboty ;)

Drzewiej QTcpSocket dawał rady , to teraz też to ogranie :D

0
Adamek Adam napisał(a):

Jak już wybrałeś Qt to obejrzyj dokładnie przykłady które są domyślnie zainstalowane w QtCreator
Potem obejrzyj projekty podobnego do tego co chcesz zrobić https://github.com/topics/audio-streaming?l=c%2B%2B
Potem do roboty ;)

Drzewiej QTcpSocket dawał rady , to teraz też to ogranie :D

Na tym etapie chciałbym to zrobić jak najprostszym sposobem bez zagłębiania się w bardziej zaawansowane projekty złożone z kilkunastu/kilkudziesięciu plików.
Na ten moment wiem jak przesłać Stringa za pomocą QTcpSocket, jak nagrać dźwięk na dysku i jak go odtworzyć.
Opieram się na przykładzie zaczerpniętym z książki, który służy do przesyłania wiadomości tekstowych.

SERVER
// server.h

#ifndef SERVER_H
#define SERVER_H

#include <QObject>
#include <QTcpServer>
#include <QDebug>

#include <QAudioOutput>
#include <QAudioFormat>

class server : public QObject
{
private:
    QTcpServer *audioServer;
    QAudioOutput *audioOutput;

public:
    explicit server(QObject *parent = nullptr);
    void startServer();
    QAudioFormat setFormat();

public slots:
    void newClientConnection();
    void socketDisconnected();
    void socketReadyRead();
};

#endif // SERVER_H
// server.cpp

#include "server.h"
#include <QTcpSocket>

server::server(QObject *parent)
    : QObject{parent}
{

}

void server::startServer()
{
    audioServer = new QTcpServer();
    audioServer->setMaxPendingConnections(10);
    connect(audioServer, &QTcpServer::newConnection, this, &server::newClientConnection);

    if (audioServer->listen(QHostAddress::Any, 1234))
    {
        qDebug() << "Server has started. Listening to port 1234.";

    }
    else
    {
        qDebug() << "Server failed to start. Error: " + audioServer->errorString();
    }
}

void server::newClientConnection()
{
    QTcpSocket *client = audioServer->nextPendingConnection();
    QString ipAddress = client->peerAddress().toString();
    int port = client->peerPort();

    connect(client, &QTcpSocket::disconnected, this, &server::socketDisconnected);
    connect(client, &QTcpSocket::readyRead, this, &server::socketReadyRead);

    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());
    QAudioOutput *audioOutput = new QAudioOutput(setFormat(), this);
    audioOutput->start(client);
}

QAudioFormat server::setFormat()
{
    QAudioFormat format;
    format.setChannelCount(1);
    format.setSampleRate(8000);
    format.setSampleSize(8);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);

    return format;
}
// CLIENT
mainwindow.h

#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QTcpSocket>

#include <QAudioInput>
#include <QAudioFormat>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    QAudioFormat setFormat();

private slots:
    void on_connectButton_clicked();
    void socketConnected();
    void socketDisconnected();
    void socketReadyRead();

    void on_sendButton_clicked();

private:
    Ui::MainWindow *ui;
    bool connectedToHost;
    QTcpSocket *socket;
    QAudioInput *audioInput;

};
#endif // MAINWINDOW_H

// mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connectedToHost = false;


}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_connectButton_clicked()
{
    if (!connectedToHost)
    {
        socket = new QTcpSocket();

        connect(socket, &QTcpSocket::connected, this, &MainWindow::socketConnected);
        connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socketDisconnected);
        connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socketReadyRead);

        socket->connectToHost("127.0.0.1", 1234);
    }
    else
    {
        socket->disconnectFromHost();
        ui->sendButton->setEnabled(false);
    }
}

void MainWindow::socketConnected()
{
    ui->sendButton->setEnabled(true);
    qDebug() << "Connected to server.";

    ui->connectButton->setText("Disconnect");
    connectedToHost = true;
}

void MainWindow::socketDisconnected()
{
    qDebug() << "Disconnected form server.";

    ui->connectButton->setText("Connect");
    connectedToHost = false;
}

void MainWindow::socketReadyRead()
{
    socket->readAll();
}

void MainWindow::on_sendButton_clicked()
{
    audioInput = new QAudioInput(setFormat(), this);

    // TUTAJ CZEGOŚ BRAKUJE
    
    audioInput->start(socket);


}

QAudioFormat MainWindow::setFormat()
{
    QAudioFormat format;
    format.setChannelCount(1);
    format.setSampleRate(8000);
    format.setSampleSize(8);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);

    return format;
}

Domyślam się, że do wysłania strumienia audio nie wystarczy samo audioInput->start(socket);
Trzeba stworzyć jakiś buffer, który będzie wysyłał porcję pakietów? Czy w serwerze też taki musi się znaleźć?

1 użytkowników online, w tym zalogowanych: 0, gości: 1