1024programmer News [Seconds to understand audio and video development] 09_ audio recording 02_ programming

[Seconds to understand audio and video development] 09_ audio recording 02_ programming

Recording by programming

The main steps to develop the recording function are:

  • Register device
  • Get input format object
  • Open device
  • Collect data
  • Release resources

Technical Image

There are 3 FFmpeg libraries that need to be used.

extern "C" {
// Device related API
#include
// Format related API
#include
// tool related API (such as error handling)
#include
}

Register device

During the running of the entire program, you only need to execute the code for registering the device once.

// Initialize libavdevice and register all input and output devices
avdevice_register_all();

Get input format object

Macro definition

The format name and device name of Windows and Mac environments are both are different, so use conditional compilation to achieve cross-platform.

//The format name and device name are temporarily fixed by macro definitions
#ifdef Q_OS_WIN
//The format name
#define FMT_NAME "dshow"
// device name
#define DEVICE_NAME "audio=microphone array (Realtek(R) Audio)"
#else
#define FMT_NAME "avfoundation"
#define DEVICE_NAME " :0"
#endif

Core Code

Get the input format object according to the format name, you need to Open the device with an input format object.

AVInputFormat *fmt = av_find_input_format(FMT_NAME);
if (!fmt) {
// if the input format cannot be found
qDebug () <<"Input format not found" <<FMT_NAME;
return;
}

Open device

// format context (later operate device through format context)
AVFormatContext *ctx = nullptr;
// open device
int ret = avformat_open_input(&ctx, DEVICE_NAME, fmt, nullptr);
// If the device fails to open
if (ret <0) {
char errbuf[1024] = {0};
// According to the function The returned error code gets the error message
av_strerror(code, errbuf, sizeof (errbuf));
qDebug() <<"Failed to open the device" <<errbuf;
return;
}

Collect data

Macro definition

#ifdef Q_OS_WIN
// The file name of the PCM file
#define FILENAME "F:/out.pcm"
#else
#define FILENAME "/ Users/mj/Desktop/out.pcm"
#endif

core code

#include
// file
QFile file(FILENAME);
// WriteOnly: write-only mode. If the file does not exist, create the file; if the file exists, delete the file content
if (!file.open(QFile::WriteOnly)) {
qDebug() <<"Failed to open the file" <<FILENAME ;
// Close the device
avformat_close_input(&ctx);
return;
}
// Temporarily assume that only 50 data packets are collected
int count = 50;
/ / Data packet
AVPacket pkt;
// Collect data from the device
// The return value of av_read_frame is 0, which means the data collection is successful
while (count-- > 0 && av_read_frame(ctx, &pkt ) == 0) {
// write data
file.write((const char *) pkt.data, pkt.size);
}

Release resources

//Close the file
file.close();
//Close Device
avformat_close_input(&ctx);

To understand the specific role of each function, you can query: official API documentation.

Multithreading

Recording is a time-consuming operation. In order to avoid blocking the main thread, it is best to perform recording operations in sub-threads. A thread class inherited from QThread is created here. Once the thread starts (start), it will automatically call the run function.

.h

#include

class AudioThread : public QThread {
Q_OBJECT
private:
void run();

public:
explicit AudioThread(QObject *parent = nullptr);
~AudioThread();
};

.cpp

AudioThread::AudioThread(QObject * parent,
AVInputFormat *fmt,
const char *deviceName)
: QThread(parent), _fmt(fmt), _deviceName(deviceName) {
// Automatically reclaim the memory of the thread when the thread ends
connect(this, &AudioThread::finished,
this, &AudioThread::deleteLater);
}
AudioThread::~AudioThread() {
// When the memory of the thread object is recycled, End the thread normally
requestInterruption();
quit();
wait();
}
void AudioThread::run() {
// recording operation
/ / ...
}

Open Thread

AudioThread *audioThread = new AudioThread(this);
audioThread- >start();

end thread

//external Call the requestInterruption of the thread and request to end the thread
audioThread->requestInterruption();
//The logic inside the thread
void AudioThread::run() {
//You can judge whether to end by isInterruptionRequested Thread
// When the requestInterruption of the thread is called, the return value of isInterruptionRequested is true, otherwise it is false
while (!isInterruptionRequested()) {
// ...
}
}

[Second understand audio and video development] 09_ audio recording 02_ programming

This article is from the internet and does not represent1024programmerPosition, please indicate the source when reprinting:https://www.1024programmer.com/seconds-to-understand-audio-and-video-development-09_-audio-recording-02_-programming/

author: admin

Previous article
Next article

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact Us

Contact us

181-3619-1160

Online consultation: QQ交谈

E-mail: [email protected]

Working hours: Monday to Friday, 9:00-17:30, holidays off

Follow wechat
Scan wechat and follow us

Scan wechat and follow us

Follow Weibo
Back to top
首页
微信
电话
搜索