2012-05-21 20 views
7

मेरा लक्ष्य बिना किसी देरी के या लैन नेटवर्क पर * .wav फ़ाइल को प्रेषित करना है।मैं क्यूटी में ईथरनेट पर स्ट्रीमिंग ऑडियो कैसे चला सकता हूं?

इसके अलावा हम सर्वर मैशिन पर फ़ाइल 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(); 
} 
+0

मैंने आपके कोड को नहीं देखा क्योंकि मैं क्यूटी से परिचित नहीं हूं, लेकिन लैन पर ऑडियो भेजने के बारे में कुछ सामान्य टिप्पणियां: 1. हालांकि पैकेट नुकसान कम है, फिर भी आपको कभी-कभी पैकेट नुकसान के लिए तैयार रहना चाहिए। 2. मेरे पास लांस के साथ बहुत अधिक अनुभव नहीं है, लेकिन मुझे लगता है कि आप विलंबता या उससे कम 100 एमएस प्राप्त कर सकते हैं। –

+0

100 एमएस ऑडियो स्ट्रीमिंग के लिए यह बहुत अधिक विलंबता है ... हां, मैं पैकेट नुकसान के लिए तैयार हूं, क्योंकि मैं यूडीपी का उपयोग करता हूं। लेकिन मैं आउटपुट पर स्पष्ट ध्वनि प्राप्त करना चाहता हूं। मैं बफरिंग डेटा का उपयोग करता हूं (उदाहरण के लिए last.fm पर यह उदाहरण) – HoBBiT

+0

इसके अलावा, मैं कैसे समझता हूं कि मैं उपयोग करता हूं: sampleRate = 8000 kHz नमूना आकार = 8 बिट और 320bytes द्वारा फ़ाइल से पढ़ें, तो मेरे पास डेटा में 5 मिमी ध्वनि है उदाहरण के लिए जिटर बफर का आकार 10 कोशिकाएं है, तो मेरे पास पैकेटिज़ेशन पर जिटर बफर + 5 एमएस के लिए 5 * 10 एमएस देरी है। नतीजतन मैं 55 एमएमएस कुल देरी होगी। यही है ना? मुझे बताएं कि यह गलत है या नहीं। – HoBBiT

उत्तर

6

यह समस्या हल किया गया था

यहाँ

इस है। 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

हाय, मुझे पता है कि यह 3 साल पहले से अधिक है, लेकिन क्या आपके पास अभी भी पूर्ण प्रोजेक्ट कोड है? क्या आप कृपया मेरे साथ कोड साझा कर सकते हैं? धन्यवाद। –