QT有一个音频信号处理的库,非常强大,可以实现音频采集,设定采集的参数等。本文的程序是在一台电脑中实现采集即时音频信号(电脑连接耳机并且说话),将这个音频信号采集后发送至另一台电脑上,在这一台电脑中连接耳机就可以清晰地听清这个即时语音信号。全程实现的是类似音频通话的功能。
话不多说,上代码。
在.pro文件中首先加入下面两个库,否则会造成编译错误:
- QT += network
- QT += multimedia
首先是发送端,实现的是语音的采集,以及音频信号的发送:
头文件:
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include <QtNetwork/QUdpSocket>
- #include <QAudio>//一下这五个是QT处理音频的库
- #include <QAudioFormat>
- #include <QAudioInput>
- #include <QAudioOutput>
- #include <QIODevice>
- using namespace std;
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
- private:
- Ui::MainWindow *ui;
- QUdpSocket *udpSocket;//用于音频信号的发送
- QAudioInput *input;
- QIODevice *inputDevice;
- struct video{
- char audiodata[1024];
- int lens;
- };
- private slots:
- void onReadyRead();//
- };
- #endif // MAINWINDOW_H
发送端.cpp文件如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork/QUdpSocket>
#include <QDebug>
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
udpSocket= new QUdpSocket(this);
udpSocket->bind(QHostAddress::Any,10004);//绑定10004端口,不绑定也行,因为是发送端不涉及到接收
input = new QAudioInput(format,this);
inputDevice = input->start();//input开始读入输入的音频信号,写入QIODevice,这里是inputDevice
connect(inputDevice,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
//槽函数,当inputDevice收到input写入的音频数据之后,调用onReadyRead函数,发送数据到目标主机上
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onReadyRead(){
qDebug()<<"It's sending audio!"<<endl;
video vp;
memset(&vp,0,sizeof(vp));
//读取音频
vp.lens = inputDevice->read(vp.data,1024);//读取音频
QHostAddress destaddr;
destaddr.setAddress("192.168.1.104");
udpSocket->writeDatagram((const char*)&vp,sizeof(vp),destaddr,10004);//将此结构体发送给目标主机,端口是10004,IP是192.168.1.104
}
至此发送端的程序就结束了,只要有音频信号输入就可以调用writedatagram函数发送至目标主机。
接收端的任务是手写接收网络上发送给他的音频数据包,之后发送给QIODevice进行播放。程序如下:
头文件:
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include <QtNetwork/QUdpSocket>
- #include <QAudio>
- #include <QAudioInput>
- #include <QAudioOutput>
- #include <QAudioFormat>
- #include <QIODevice>
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
- private:
- Ui::MainWindow *ui;
- QUdpSocket *udpsocket;
- struct video{
- char data[1024];
- int lens;
- };
- QAudioOutput *output;
- QIODevice *outputDevice;
- private slots:
- void readyReadSlot();
- };
- #endif // MAINWINDOW_H
接收.cpp文件如下:
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QHostAddress>
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- udpsocket = new QUdpSocket(this);
- udpsocket->bind(QHostAddress::Any,10004);
- connect(udpsocket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));//收到网络数据报就开始往outputDevice写入,进行播放
- QAudioFormat format;
- format.setSampleRate(8000);
- format.setChannelCount(1);
- format.setSampleSize(16);
- format.setCodec("audio/pcm");
- format.setSampleType(QAudioFormat::SignedInt);
- format.setByteOrder(QAudioFormat::LittleEndian);
- output = new QAudioOutput(format,this);
- outputDevice = output->start();//开始播放
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::readyReadSlot(){
- while(udpsocket->hasPendingDatagrams()){
- QHostAddress senderip;
- quint16 senderport;
- qDebug()<<"audio is being received..."<<endl;
- video vp;
- memset(&vp,0,sizeof(vp));
- udpsocket->readDatagram((char*)&vp,sizeof(vp),&senderip,&senderport);
- outputDevice->write(vp.data,vp.lens);
- }
- }
别忘了往.pro文件加上那两行QT库。
怎么样?运行程序,你在发送端的电脑上面说话,接收端就能听到,延迟不到半秒。这样你就自己实现了语音电话的功能。是不是很酷炫呢?
https://blog.csdn.net/hanzhen7541/article/details/98794555 这是更新版,更有借鉴价值。
联系客服