一年多以前曾经写过一篇用QT audio语音库实现音频的采集和播放的博文:https://blog.youkuaiyun.com/hanzhen7541/article/details/80152381
上面那个是初级版,实现的是从inputdevice音频采集,发送到目的地址端口;目的主机收到音频收到了信号,直接写入音频的设备进行播放。这几天又用到了QT的语音库,所以做了改进,因为网络环境不稳定,所以做了优化:接受端接收到音频流之后,并不直接写在输出的outputdevice进行播放,而是定义了一个缓冲区m_PCMDataBuffer,接受端sicket接收到音频流数据,调用函数addAudioBuffer向缓冲区里面写; 同时,重载了QThread的run函数,调用run()函数,每当缓冲区超过960字节(我社定的8000采样率,16比特采样,960字节对应60ms数据)就从缓冲区读取数据,写入QOutputDevice从而听到声音。
这样当网络不稳定的时候,每一包语音流有不同的延迟,在接受端也能听到较为流畅的声音。
话不多说,现在来看具体代码:
首先是发送线程,这个和之前博文里面的没用太多区别,在主函数中包含头文件之后初始化对象,调用mystart()函数就可以实现发送,调用mystop()函数就可以停止。发送端的头文件:
#ifndef AUDIOSENDTHREAD_H
#define AUDIOSENDTHREAD_H
//这是发送线程
#include <QObject>
#include <QThread>
#include <QDebug>
#include <QAudio>
#include <QAudioFormat>
#include <QAudioInput>
#include <QAudioOutput>
#include <QIODevice>
#include <QtNetwork/QUdpSocket>
#include <QHostAddress>
class audiosendthread : public QThread
{
Q_OBJECT
public:
explicit audiosendthread(QObject *parent = nullptr);
~audiosendthread();
QUdpSocket *udpSocket;
QHostAddress destaddr;
QAudioInput *input;
QIODevice *inputDevice;
QAudioFormat format;
struct video{
int lens;
char data[960];
};
void setaudioformat(int samplerate, int channelcount, int samplesize);
void mystart();
void mystop();
public slots:
void onReadyRead();
};
#endif // AUDIOSENDTHREAD_H
发送的.cpp
#include "audiosendthread.h"
audiosendthread::audiosendt