1. 代碼錄製視頻的核心代碼以下:
#include "audiothread.h"
#include <QDebug>
#include <QFile>
extern "C" {
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include <libavcodec/avcodec.h>
}
#define FMT_NAME "avfoundation"
#define DEVICE_NAME "0"
#define FILENAME "/Users/carrot__lsp/Documents/current/FFMpeg/MyCode/AudioVideo/out.yuv"
#define ERROR_BUF(ret) \ char errbuf[1024]; \ av_strerror(ret, errbuf, sizeof (errbuf));
AudioThread::AudioThread(QObject *parent) : QThread(parent)
{
connect(this, &AudioThread::finished,
this, &AudioThread::deleteLater);
}
AudioThread::~AudioThread() {
disconnect();
requestInterruption();
quit();
wait();
qDebug() << this << "析構(內存被回收)";
}
void AudioThread::run() {
qDebug() << this << "開始執行----------";
AVInputFormat *fmt = av_find_input_format(FMT_NAME);
if(!fmt) {
qDebug() << "av_find_input_format error" << FMT_NAME;
return;
}
AVFormatContext *ctx = nullptr;
AVDictionary *options = nullptr;
av_dict_set(&options, "video_size", "640x480", 0);
av_dict_set(&options, "pixel_format", "yuyv422", 0);
av_dict_set(&options, "framerate", "30", 0);
int ret = avformat_open_input(&ctx, DEVICE_NAME, fmt, &options);
if (ret < 0) {
ERROR_BUF(ret);
qDebug() << "avformat_open_input error" << errbuf;
return;
}
QFile file(FILENAME);
if (!file.open(QFile::WriteOnly)) {
qDebug() << "file open error" << FILENAME;
avformat_close_input(&ctx);
return;
}
AVCodecParameters *params = ctx->streams[0]->codecpar;
AVPixelFormat pixFmt = (AVPixelFormat)params->format;
int imageSize = av_image_get_buffer_size(
pixFmt,
params->width,
params->height,
1);
AVPacket *pkt = av_packet_alloc();
while(!isInterruptionRequested()) {
ret = av_read_frame(ctx,pkt);
if(ret == 0) {
file.write((const char*)pkt->data, imageSize);
qDebug() << pkt->size;
av_packet_unref(pkt);
} else if (ret == AVERROR(EAGAIN)) {
continue;
} else {
ERROR_BUF(ret);
qDebug() << "av_read_frame error" << errbuf << ret;
break;
}
}
av_packet_free(&pkt);
file.close();
avformat_close_input(&ctx);
qDebug() << this << "正常結束-----";
}
複製代碼
2. 使用下面命令便可順利播放錄製的視頻
ffplay -video_size 640x480 -pixel_format yuyv422 -framerate 30 out.yuv