• 基于QT和UDP实现一个实时RTP数据包的接收,并将数据包转化成文件


    简单介绍:代码写的比较详细,需要留意的地方看结尾介绍

    头文件

    1. #ifndef RTPRECEIVER_H
    2. #define RTPRECEIVER_H
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. class RTPReceiver : public QWidget
    10. {
    11. Q_OBJECT
    12. public:
    13. explicit RTPReceiver(QWidget *parent = nullptr);
    14. ~RTPReceiver();
    15. void start();
    16. void closeFile();
    17. void writeBufferToFile();
    18. void initSocket();
    19. void sendGetRequest();
    20. private slots:
    21. void readPendingDatagrams();
    22. private:
    23. QUdpSocket *udpSocket;
    24. QFile file;
    25. QByteArray buffer;
    26. int bufferSize = 1400;
    27. QString filePath;
    28. };
    29. #endif // RTPRECEIVER_H

    cpp文件

    1. #include "rtpreceiver.h"
    2. const int RTP_HEADER_LENGTH = 12;
    3. RTPReceiver::RTPReceiver(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. this->setVisible(false);
    7. }
    8. RTPReceiver::~RTPReceiver()
    9. {
    10. }
    11. void RTPReceiver::start()
    12. {
    13. initSocket();
    14. }
    15. void RTPReceiver::closeFile()
    16. {
    17. if (file.isOpen()) {
    18. file.close();
    19. }
    20. }
    21. void RTPReceiver::readPendingDatagrams()
    22. {
    23. qDebug()<<"readPendingDatagrams方法被执行";
    24. while (udpSocket->hasPendingDatagrams()) {
    25. QByteArray datagram;
    26. datagram.resize(udpSocket->pendingDatagramSize());
    27. udpSocket->readDatagram(datagram.data(), datagram.size());
    28. qDebug()<<"传过来的大小"<size();
    29. if (datagram.size() < RTP_HEADER_LENGTH) {
    30. qDebug() << "Invalid RTP packet";
    31. continue;
    32. }
    33. // QByteArray payload = datagram.mid(RTP_HEADER_LENGTH);
    34. // 将RTP数据包添加到缓冲区
    35. buffer.append(datagram.mid(12));
    36. qDebug()<<"缓存大小"<size();
    37. // 检查缓冲区是否达到一定大小,达到则写入文件
    38. if (buffer.size() >= bufferSize) {
    39. writeBufferToFile();
    40. continue;
    41. }
    42. //代表是最后一次请求
    43. if(buffer.size()<1666){
    44. writeBufferToFile();
    45. //关闭文件
    46. closeFile();
    47. udpSocket->close();
    48. //调用whisper去翻译当前音频
    49. RequestWhisper();
    50. //重新初始化服务
    51. initSocket();
    52. continue;
    53. }
    54. }
    55. }
    56. void RTPReceiver::writeBufferToFile()
    57. {
    58. qDebug()<<"每次写入大小"<size();
    59. if (!file.isOpen()) {
    60. QString outputFilePath = "F:\\output.wav";
    61. filePath=outputFilePath;
    62. file.setFileName(outputFilePath);
    63. file.open(QIODevice::WriteOnly);
    64. }
    65. file.write(buffer);
    66. file.flush();
    67. buffer.clear();
    68. }
    69. void RTPReceiver::initSocket()
    70. {
    71. qDebug()<<"RTP服务被初始化";
    72. udpSocket = new QUdpSocket(this);
    73. bool bindResult=udpSocket->bind(QHostAddress::AnyIPv4, 1234); // 替换成实际的RTP端口
    74. if(!bindResult)
    75. {
    76. qDebug()<<"绑定失败";
    77. return;
    78. }
    79. //绑定接收
    80. qDebug()<<"RTP服务监听中";
    81. connect(udpSocket, &QUdpSocket::readyRead, this, &RTPReceiver::readPendingDatagrams);
    82. }

    注意: 这里需要注意的地方是,如何判断数据包是否是最后一包,这里当时我花了一些时间,最后采取通过判断数据包大小来判断是否是最后一包,我定义的发送的RTP的数据包缓存大小是1400,然后如果小于这个大小,说明是最后一包,这样就可以执行文件关闭和一些其他命令了,还有其他的不同的方式,这里需要你们自己去了解RTP数据包

  • 相关阅读:
    山东三体系认证意义及申请认证流程
    在旭日X3派开发板上使用USB Wifi来提高网络速度
    k8s 读书笔记 - 初始化容器 Init Conatiner
    lesson4-C++内存管理
    【Java小项目】--- 飞机大战(源码+注释)
    卷积神经网络处理图像,卷积神经网络图像增强
    解题-->在线OJ(十八)
    20_ue4实现键盘控制物体自转(蓝图通讯2)
    高效数据传输:Java通过绑定快速将数据导出至Excel
    2.7 Time Series
  • 原文地址:https://blog.csdn.net/weixin_45533131/article/details/133211751