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

2023-11-21

我的目标是通过 LAN 网络无延迟或最少延迟地传输 *.wav 文件。

我们还按部分读取服务器计算机上的文件,均为 320 字节。之后我们通过 UDP 发送数据包并将接收写入 jitter-buffer 中。抖动缓冲区的大小为 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();
}

这个问题就解决了。 QAudioOutput 有两种模式;有“推”和“拉”。我给出一个指向 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);
    }
}

如果有人遇到问题,我会尽力帮助他/她。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Qt 中通过以太网播放流媒体音频? 的相关文章

  • Qt 布局,在小部件大小更改后调整到最小大小

    基本上我有一个QGridLayout里面有一些小部件 最重要的是 2 个标签 我用它们将图像绘制到屏幕上 好吧 如果用户愿意 他可以更改传入图像的分辨率 从而强制标签调整大小 我们假设标签的初始大小是320x240 用户将 VideoMod
  • PyQt5:如何使QThread返回数据到主线程

    I am a PyQt 5 4 1 1初学者 我的Python是3 4 3 这是我尝试遵循的many https mayaposch wordpress com 2011 11 01 how to really truly use qthr
  • 使用 Android 播放任意音调

    有没有办法让Android发出任意频率的声音 意思是 我不想预先录制声音文件 我环顾四周 音调发生器 http developer android com reference android media ToneGenerator html
  • 从 Qt4 中的文本文件中逐字读取

    我想在 Qt4 中逐字读取一个文本文件 说实话我对它很陌生 我想在另一个文件中每行一个字写入 我可以在 C 中做到这一点 没有任何问题 但是当我尝试在 Qt4 中使用 ifstream 和 ofstream 时 我遇到了错误 这是我的 Qt
  • 如何在 QtQuick 2 中对 QML TableView 进行排序?

    我想使用 Qt 5 1 实现具有自定义角色的可排序 TableView 但我不知道当用户单击标题时该怎么做才能对其进行排序 在我的 Qt pro 文件中 我添加了 android ios blackberry qtHaveModule wi
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • Qt 5.3 无法使 QCompass (QSensor) 在 Windows 8.1 上工作

    我无法让传感器在我的 Asus Transformer T100 上工作 磁力计和指南针无法启动 并且我从加速度计获得假值 始终 x 0 y 9 8 z 0 即使使用我的笔记本电脑 我总是得到相同的结果 第一段文字编辑 Initialisa
  • 如何将 zlib 添加到现有的 qt 安装中

    如何将 zlib 添加到 Qt 的现有安装中 我对此很陌生 所以请给我详细的描述 提前感谢您的帮助 zlib 包含在 Qt 核心库中 如果你想在 Qt 程序中使用 zlib 函数 你只需要包含 src 3rdparty zlib 中的 zl
  • 静态变量中的 qt tr()

    我在 qt 中的翻译方面遇到问题 我的项目中的所有翻译都工作正常 但有一个翻译位于类的静态变量中 相应部分代码如下 头文件类似于这样 typedef struct int type QString problematicString inf
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 是否可以在 Qt Creator 中将 Qt 样式表与升级的小部件一起使用?

    我正在尝试使用 Qt 样式表对标准小部件进行一些重大的重新设计 因此 在为不同的小部件手动完成大部分工作之后 objectName选择器 我决定以某种方式对类似的小部件进行分组 例如我有多个QFrames其作用类似于内部表单中的标题 我希望
  • Qt 安装程序框架 - 如何在卸载时仅删除某些文件和文件夹

    我使用 Qt 安装程序框架 如何确保在卸载时仅删除某些文件或文件夹 而不是像当前那样删除安装文件夹中的所有文件 先感谢您 您可以覆盖默认行为component createOperations对于卸载程序 然后使用手动指定每个卸载路径com
  • 为什么 QGraphicsWidget 的选择边框在 QGraphicsScene 中不可见?

    我已经通过一个小部件添加到图形场景 QGraphicSscene QGraphicsProxyWidget 问题是 当我选择该项目时 它被选中 但选择边框不可见 这是代码 QDial dial new QDial Widget dial g
  • 如何访问Loader的sourceComponent中的QML对象?

    我可能需要读取或写入的一些属性Loader s sourceComponent来自一些外部函数 访问该房产的方式是什么x里面的对象的Loader s sourceComponent import QtQuick 2 0 Item width
  • Java - 无缝改变循环剪辑的音量?

    我有一个循环剪辑 我像这样改变音量 clip stop clip flush FloatControl fc FloatControl clip getControl FloatControl Type MASTER GAIN fc set
  • 更改 Android 中的媒体音量?

    我可以更改媒体音量吗 如何 到目前为止我用过这个 setVolumeControlStream AudioManager STREAM MUSIC 但有一个搜索栏并且想要更改媒体音量 而不是铃声音量 那么有人可以告诉我如何更改媒体音量onC
  • 如何以编程方式播放 16 位 pcm 数组 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有一个包含 16 位 pcm 值的短 数组 我希望能够在不添加任何标题 也不将任何文件保存到内存的情况下播放它 我知道我可能需要一个提供
  • Android 上 WebRTC 的自定义视频源

    Overview 我想使用自定义视频源通过 WebRTC Android 实现来直播视频 如果我理解正确的话 现有的实现仅支持 Android 手机上的前置和后置摄像头 以下类与此场景相关 Camera1Enumerator java ht
  • 使用 PyQt 和 matplotlib 在可滚动小部件中显示多个绘图

    由于我没有得到答案this https stackoverflow com questions 12179893 creating a scrollable multiplot with pythons pylab我尝试用 PyQt 解决这
  • 捕获当前正在播放的声音

    是否可以捕获计算机上当前播放的声音 如果能够将其保存为 mp3 就好了 但我认为这样做会存在一些法律问题 所以 wav 也可以 我环顾四周 有人建议使用虚拟音频线之类的东西 在 C 中捕获声音输出 https stackoverflow c

随机推荐

  • 使用 MVVM 上下文菜单项命令绑定 WPF

    我知道这个问题已经在许多网站和 StackOverFlow 中以不同的方式被问过很多次 但我找到的所有答案都没有帮助我 准确地说 我无法理解它们并在我的应用程序中实现 所以我想从我的应用程序中添加一些代码 以便你们可以更好地帮助我 问题陈述
  • python 中 Burrows-Wheeler 的性能问题

    我试图实施布罗斯 惠勒在Python中进行转换 这是在线课程的作业之一 但我希望我已经做了一些工作才有资格寻求帮助 该算法的工作原理如下 获取一个以特殊字符 在我的例子中为 结尾的字符串 并从该字符串创建所有循环字符串 按字母顺序对所有这些
  • 为什么inline-block会导致这个div有高度呢?

    jsFiddle Demo 我似乎无法弄清楚为什么使用display inline block会导致这个 div 当包含元素被隐藏时 元素以某种方式获得高度 这不会发生在display block html div style displa
  • 在 hadoop 中并行运行作业

    我是 hadoop 新手 我已经设置了一个 2 节点集群 如何在 hadoop 中并行运行 2 个作业 当我提交作业时 它们按照 FIFO 顺序一项一项地运行 我必须并行运行这些作业 如何实现这一目标 谢谢 MRK Hadoop 可以配置多
  • 为什么 WaitForMultipleObjects 在使用多个线程句柄时会失败?

    在下面的测试程序中 每个测试线程将其句柄添加到全局TThreadList当它开始执行时 并在执行即将结束时从同一列表中删除其句柄 此外 出于测试目的 每个线程确保在主线程锁定列表之前添加其句柄 以复制其句柄并开始等待它们完成 这些线程还确保
  • 使用 find 和 sed 将文件名添加到文件开头

    使用以下内容 我将文件名添加到每行的前面 并将输出发送到单个文件 ls while read file do sed e s file g file gt out done 我想执行同样的操作sed替换但使用find and exec or
  • Xcode 4.2 iOS 5:来自 UITableView 的多个 Segues

    我现在开始使用适用于 iOS5 的 Xcode 4 2 有一些更改 我现在遇到一个问题 我无法找到解决方法 我正在使用 UITablwView 做一个示例 该视图以编程方式填充了 2 个部分 第 1 部分仅包含 1 行 第 2 部分包含 3
  • 访问Linux /dev/USB作为标准文件与USB设备通信

    我正在研究在 Linux 中与 USB 设备通信的方法 并且不想编写 Linux 内核驱动程序 我知道 libusb 存在并且是一个可以工作的用户空间库 但是我们的嵌入式设备不支持 usbfs 并且更改内核以添加支持确实很痛苦 所以我的问题
  • iOS13 模拟器上的 UIDocumentBrowserViewController 错误“无法为 url 创建 urlWrapper”

    我有一个非常奇怪的问题UIDocumentBrowserViewController在 iOS 13 上测试时 importHandler newDocumentURL move 似乎没有任何原因崩溃 DocumentManager Can
  • 为什么Lucene在索引大文件时会导致OOM?

    我正在使用 Lucene 2 4 0 和 JVM JDK 1 6 0 07 我不断收到OutOfMemoryError Java heap space 当尝试索引大型文本文件时 示例 1 对 5 MB 文本文件建立索引会导致内存不足 最大容
  • 模拟文本输入字段上的退格键

    有人可以提供一个很好的例子来模拟退格键 on a
  • 更改java控制台输出的颜色

    我想知道是否有什么办法可以设置我在 Java 中输出到控制台的文本的颜色 是否特定于系统并不重要 因为该程序只能在我的 Windows 7 x64 笔记本电脑上运行 这个问题 在 java eclipse 控制台中更改颜色几周前被问到 并且
  • 写入Main Bundle 目录。允许吗?

    我非常确定在 iOS 中不可能在主 Bundle 中写入 例如如下操作 NSString path NSBundle mainBundle pathForResource Data ofType plist something xmlDat
  • Three.js 截图

    我需要制作网站的屏幕截图 我尝试使用 html2canvas 和所有它的工作 但问题是我正在使用 THREE WebGLRenderer 和 THREE CSS3DRenderer 用于 webgl 中的 html 所以当我制作屏幕截图时
  • 如何为相同大小分区的 Spark RDD 定义自定义分区器,其中每个分区具有相同数量的元素?

    我是 Spark 新手 我有一个大型元素数据集 RDD 我想将其划分为两个大小完全相同的分区 以保持元素的顺序 我尝试使用RangePartitioner like var data partitionedFile partitionBy
  • 序列化有时是数组的 Json 属性[重复]

    这个问题在这里已经有答案了 有没有什么方法可以在一次操作中序列化从十进制到十进制 的 Json 对象属性 在我的 Json 产品提要中 特价商品表示为数组 正常价格 促销价格 普通商品只是价格 就像这样 product umbrella p
  • C++ 未处理的异常

    如果发生未处理的异常 C 是否提供了一种 显示 可视化内容的方法 我想做的是做一些像assert unhandled exception msg 如果它确实发生 如下面的示例所示 include
  • Android 未解决的主机异常

    我尝试使用以下方法从 Android 应用程序调用 RESTful Web 服务 HttpHost target new HttpHost http ServiceWrapper SERVER HOST ServiceWrapper SER
  • Git 哈希值是如何计算的?

    我试图了解 Git 如何计算 refs 的哈希值 git ls remote https github com git git 29932f3915935d773dc8d52c292cadd81c81071d refs tags v2 4
  • 如何在 Qt 中通过以太网播放流媒体音频?

    我的目标是通过 LAN 网络无延迟或最少延迟地传输 wav 文件 我们还按部分读取服务器计算机上的文件 均为 320 字节 之后我们通过 UDP 发送数据包并将接收写入 jitter buffer 中 抖动缓冲区的大小为 10 为了获得清晰