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?
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
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źć?