简单介绍:代码写的比较详细,需要留意的地方看结尾介绍
头文件
#ifndef RTPRECEIVER_H
#define RTPRECEIVER_H
#include <QDialog>
#include <QUdpSocket>
#include <QFile>
#include <QTextStream>
#include <httpclient.h>
#include <QEventLoop>
class RTPReceiver : public QWidget
{
Q_OBJECT
public:
explicit RTPReceiver(QWidget *parent = nullptr);
~RTPReceiver();
void start();
void closeFile();
void writeBufferToFile();
void initSocket();
void sendGetRequest();
private slots:
void readPendingDatagrams();
private:
QUdpSocket *udpSocket;
QFile file;
QByteArray buffer;
int bufferSize = 1400;
QString filePath;
};
#endif // RTPRECEIVER_H
cpp文件
#include "rtpreceiver.h"
const int RTP_HEADER_LENGTH = 12;
RTPReceiver::RTPReceiver(QWidget *parent)
: QWidget(parent)
{
this->setVisible(false);
}
RTPReceiver::~RTPReceiver()
{
}
void RTPReceiver::start()
{
initSocket();
}
void RTPReceiver::closeFile()
{
if (file.isOpen()) {
file.close();
}
}
void RTPReceiver::readPendingDatagrams()
{
qDebug()<<"readPendingDatagrams方法被执行";
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(), datagram.size());
qDebug()<<"传过来的大小"<<datagram.size();
if (datagram.size() < RTP_HEADER_LENGTH) {
qDebug() << "Invalid RTP packet";
continue;
}
// QByteArray payload = datagram.mid(RTP_HEADER_LENGTH);
// 将RTP数据包添加到缓冲区
buffer.append(datagram.mid(12));
qDebug()<<"缓存大小"<<buffer.size();
// 检查缓冲区是否达到一定大小,达到则写入文件
if (buffer.size() >= bufferSize) {
writeBufferToFile();
continue;
}
//代表是最后一次请求
if(buffer.size()<1666){
writeBufferToFile();
//关闭文件
closeFile();
udpSocket->close();
//调用whisper去翻译当前音频
RequestWhisper();
//重新初始化服务
initSocket();
continue;
}
}
}
void RTPReceiver::writeBufferToFile()
{
qDebug()<<"每次写入大小"<<buffer.size();
if (!file.isOpen()) {
QString outputFilePath = "F:\\output.wav";
filePath=outputFilePath;
file.setFileName(outputFilePath);
file.open(QIODevice::WriteOnly);
}
file.write(buffer);
file.flush();
buffer.clear();
}
void RTPReceiver::initSocket()
{
qDebug()<<"RTP服务被初始化";
udpSocket = new QUdpSocket(this);
bool bindResult=udpSocket->bind(QHostAddress::AnyIPv4, 1234); // 替换成实际的RTP端口
if(!bindResult)
{
qDebug()<<"绑定失败";
return;
}
//绑定接收
qDebug()<<"RTP服务监听中";
connect(udpSocket, &QUdpSocket::readyRead, this, &RTPReceiver::readPendingDatagrams);
}
注意: 这里需要注意的地方是,如何判断数据包是否是最后一包,这里当时我花了一些时间,最后采取通过判断数据包大小来判断是否是最后一包,我定义的发送的RTP的数据包缓存大小是1400,然后如果小于这个大小,说明是最后一包,这样就可以执行文件关闭和一些其他命令了,还有其他的不同的方式,这里需要你们自己去了解RTP数据包