本文是对上一篇文章做优化,CSDNhttps://mp.csdn.net/mp_blog/creation/editor/134987575
主要是通过多线程,以按钮形式开启录制,结束录制。主要在代码结构上做一些修改。
怎么建立多线程文件这里就不赘述了,主要是继承QThread类,重写run函数,注意while里的内容是多线程循环主体,并不是所有run函数里面的内容都会一直执行。
并且最好建立一个标志位来开启线程,结束线程,这样会省去很多复杂的麻烦事。多线程头文件如下
#ifndef CAPTURETHREAD_H
#define CAPTURETHREAD_H
#include <QThread>
#include <QDebug>
//引入C链接库
extern "C"
{
#include "libavdevice/avdevice.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/avcodec.h"
}
class CaptureThread : public QThread
{
Q_OBJECT
public:
CaptureThread();
~CaptureThread();
void thread_flag_start();
void thread_flag_stop();
protected:
void run();
bool flag_thread;
signals:
};
#endif // CAPTURETHREAD_H
多线程.cpp内容如下面所示
#include "capturethread.h"
CaptureThread::CaptureThread()
{
}
CaptureThread::~CaptureThread()
{
}
void CaptureThread::thread_flag_start()
{
flag_thread = true;
}
void CaptureThread::thread_flag_stop()
{
flag_thread = false;
}
void CaptureThread::run()
{
int ret;
AVFormatContext *fmt_ctx = NULL;
char *device_name = "audio=麦克风 (2- Realtek(R) Audio)";
AVInputFormat *in_fmt = NULL;
AVDictionary *options = NULL;
char str_error[1024];
AVPacket pkt;
av_init_packet(&pkt);
int num = 0;
avdevice_register_all();
in_fmt = av_find_input_format("dshow");
if(ret = avformat_open_input(&fmt_ctx,device_name,in_fmt,&options) < 0)
{
av_strerror(ret,str_error,1024);
qDebug()<<"打开设备失败"<<"失败参数:"<<ret;
}
char *file_name = "E:/class_2.pcm";
FILE *out_file = fopen(file_name,"wb+");
while((ret = av_read_frame(fmt_ctx,&pkt)) == 0 && flag_thread == true)
{
num++;
fwrite(pkt.data,pkt.size,1,out_file);
fflush(out_file);
qDebug()<<"pkt size is: "<<pkt.size;
qDebug()<<"pkt count is:"<<num;
av_packet_unref(&pkt);
msleep(100);
}
fclose(out_file);
qDebug()<<"hello world";
}
mainwindows.cpp开启录制,结束录制代码如下所示
void MainWindow::on_pushButton_clicked()
{
qDebug()<<"线程开始";
thread_A->thread_flag_start();
thread_A->start();
}
void MainWindow::on_pushButton_2_clicked()
{
qDebug()<<"线程结束";
thread_A->thread_flag_stop();
thread_A->quit();
thread_A->wait();
}