我的目标是通过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); } }
如果有人似乎有问题,我会尽力帮助他.
精彩评论