运维开发网

我如何在Qt中通过以太网播放流音频?

运维开发网 https://www.qedev.com 2020-04-17 14:42 出处:网络 作者:运维开发网整理
我的目标是通过LAN网络传输* .wav文件,没有延迟或只有最小的. 我们也读取服务器mashin上的文件,部分320字节.在此之后,我们通过Udp发送数据包并在抖动缓冲区中写入接收.抖动缓冲区的大小为10. 我应该在计时器上设置什么延迟以获得清晰的声音. 这是发件人: void MainWindow::on_start_tx_triggered() { timer1 = new QTi
我的目标是通过LAN网络传输* .wav文件,没有延迟或只有最小的.

我们也读取服务器mashin上的文件,部分320字节.在此之后,我们通过Udp发送数据包并在抖动缓冲区中写入接收.抖动缓冲区的大小为10.

我应该在计时器上设置什么延迟以获得清晰的声音.

这是发件人:

void MainWindow::on_start_tx_triggered()
{
    timer1 =  new QTimer (this);
    udpSocketout = new QUdpSocket(this);
    qDebug()<<"Start";
    for (int i = 0; i < playlist.size(); ++i)
    {
        inputFile.setFileName(playlist.at(i));
        qDebug()<<inputFile.fileName();
        if (!inputFile.open(QIODevice::ReadOnly))
        {
            qDebug()<< "file not found;";
        }
    }
    connect(timer1, SIGNAL(timeout()),this, SLOT(writeDatagrams()));
    timer1->start(5);
}

void  MainWindow::writeDatagrams() 
{    
    if(!inputFile.atEnd()){
        payloadout = inputFile.read(320);
    }
    qDebug()<<payloadout;
    QDataStream out(&datagramout, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_7);
    out << qint64(0);
    out << payloadout;
    out.device()->seek(qint64(0));
    out << qint64(datagramout.size() - sizeof(qint64));
    qint64 writtenBytes = udpSocketout->writeDatagram(datagramout, remoteHOST, remotePORT);
    qDebug() << "Sent " << writtenBytes << " bytes.";
}

这里是接收器和播放器:

void MainWindow::on_start_rx_triggered()
{
    udpSocketin = new QUdpSocket(this);
    udpSocketin->bind(localHOST, localPORT);
    connect(udpSocketin, SIGNAL(readyRead()),
            this, SLOT(readDatagrams()));
    QDataStream out(&datagramout, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_7);
    timer2 =  new QTimer (this);
    connect(timer2, SIGNAL(timeout()),this, SLOT(playbuff()));
    timer2->start(50);
    audioout = new QAudioOutput(format, this);
}

void  MainWindow::readDatagrams()
{
    datagramin.resize(udpSocketin->pendingDatagramSize());
    qint64 receiveBytes = udpSocketin->readDatagram(datagramin.data(),datagramin.size());
    qDebug() << "Receive " << receiveBytes << " bytes.";
    QDataStream in(&datagramin, QIODevice::ReadOnly);
    in.setVersion(QDataStream::Qt_4_7);
    quint64 size = 0;
    if(in.device()->size() > sizeof(quint64))
    {
        in >> size;
    }
    else return;
    if(in.device()->size() < size) return;
    in >> payloadin;
    qDebug()<<payloadin.size();
    emit jitterbuff();
}

void MainWindow::jitterbuff() 
{
    if (buff_pos < SIZE_OF_BUF)
    {
        QDataStream out(&buffered, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_7);
        out << payloadin;
        buff_pos++;
    }
    else buff_pos=0;
}

void MainWindow::playbuff()
{
    qDebug()<<"YES!!!";
    buffer = new QBuffer(&buffered);
    buffer->open(QIODevice::ReadOnly);
    audioout->start(buffer);
    QEventLoop loop;
    QTimer::singleShot(50,&loop,SLOT(quit()));
    loop.exec();
    buffer->close();
}
这个问题解决了. QAdioOutput有两种模式,分别是“推”和“拉”.我在QIODevice上给出指针,并在此直接写入数据.解:

读取UDP套接字:

void MainWindow::on_start_rx_triggered()
{
    udpSocketin = new QUdpSocket(this);
    udpSocketin->bind(localPORT);
    connect(udpSocketin, SIGNAL(readyRead()),this, SLOT(readDatagrams()));
    QDataStream out(&datagramout, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_7);
    timer2 =  new QTimer (this);
    connect(timer2, SIGNAL(timeout()),this, SLOT(playbuff()));
    timer2->setInterval(15*9);
    audioout = new QAudioOutput(format, this);
    input = audioout->start();
    } 
void  MainWindow::readDatagrams()
    {
        if (udpSocketin->hasPendingDatagrams()){
        datagramin.resize(udpSocketin->pendingDatagramSize());
        qint64 receiveBytes = udpSocketin->readDatagram(datagramin.data(),datagramin.size());
        if (receiveBytes<=0)
        {
            msg.warning(this,"File ERROR","The end!",QMessageBox::Ok);
            emit on_stop_rx_triggered();
        }
        QDataStream in(&datagramin, QIODevice::ReadOnly);
        in.setVersion(QDataStream::Qt_4_7);
        quint64 size = 0;
        if(in.device()->size() > sizeof(quint64))
        {
            in >> size;
        }
        else return;
        in >> rxfilename;
        in >> name;
        in >> payloadin;
    emit jitterbuff();
    }
    void MainWindow::jitterbuff()
        {
            if (buff_pos < SIZE_OF_BUF)
            {
                buffered.append(payloadin);
                buff_pos++;
            }
            else
            {
                timer2->start();
                buffered.clear();
                buff_pos=0;
            }
        }

        void MainWindow::playbuff()
        {
            if (!buffered.isEmpty())
            {
                buffer = new QBuffer(&buffered);
                buffer->open(QIODevice::ReadOnly);
                input->write(buffered);
                buffer->close();
            }
        }

写入UDP套接字:

void MainWindow::on_start_tx_triggered()
{
    timer1 =  new QTimer (this);
    udpSocketout = new QUdpSocket(this);
    inputFile.setFileName(playlist.at(playIDfile));
        if (!inputFile.open(QIODevice::ReadOnly))
        {
            msg.warning(this,"File ERROR","File not found!",QMessageBox::Ok);
            return;
        }
    fileinfo = new QFileInfo (inputFile);
    txfilename = fileinfo->fileName();
    ui->playedFile->setText("Now played: " + txfilename);
    connect(timer1, SIGNAL(timeout()),this, SLOT(writeDatagrams()));
    timer1->start(15);
}
void  MainWindow::writeDatagrams()
{

    if(!inputFile.atEnd()){
        payloadout = inputFile.read(SIZE_OF_SOUND);
        QDataStream out(&datagramout, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_7);
        out << qint64(0);
        out << txfilename;
        out << name;
        out << payloadout;
        out.device()->seek(qint64(0));
        out << qint64(datagramout.size() - sizeof(qint64));
        qint64 writtenBytes = udpSocketout->writeDatagram(datagramout, remoteHOST, remotePORT);
    }
}

如果有人似乎有问题,我会尽力帮助他.

0

精彩评论

暂无评论...
验证码 换一张
取 消