要修改的点
- 修改设备名称
之前音频的采集程序使用的设备名称是音频的名称,现在要改为视频的名称。 - 增加参数
确定采集视频的YUV格式、分辨率、帧率等 - 修改文件名及文件数据的大小
音频采集例程H文件
#ifndef testc_h
#define testc_h
#include <stdio.h>
#include "libavutil/avutil.h"
#include "libavdevice/vadevice.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswresample/swresample.h"
void set_status(int status);
void rec_audio(void);
#endif /* testc_h */
音频采集例程c文件
// 音频采集例程
#include "testc.h"
#include <string.h>
static int rec_status = 0;
void set_status(int status){
rec_status = status;
}
// @brief
//return
static AVFormatContext* open_dev(){
int ret = 0;
char errors[1024] = {0};
// ctx
AVFormatContext *fmt_ctx = NULL;
AVDictionary *options = NULL;
// [[video device]:[audio device]]
char *devicename = "hw:0";
// register audio device
avdevice_register_all();
// get format
AVInputFormat *iformat = av_find_input_format("avfoundation");
// open device
if((ret = avformat_open_input(&fmt_ctx, devicename, iformat, &options)) < 0 ){
av_strerror(ret, errors, 1024);
fprintf(stderr, "Failed to open audio device, [%d]%s\n, ret errors");
return NULL;
}
return fmt_ctx;
}
void rec_audio(){
int ret = 0;
AVFormatContext *fmt_ctx = NULL;
// pakcet
AVPacket pkt;
// set log level
av_log_set_level(AV_LOG_DEBUG);
// start record
rec_status = 1;
// create file
char *out = "/home/king/workspace/file/my_yuv.yuv";
FILE *outfile = fopen(out, "wb+");
// 打开设备
fmt_ctx = open_dev();
//read data from device
while((ret = av_read_frame(fmt_ctx, &pkt)) == 0 && rec_status){
av_log(NULL, AV_LOG_INFO, "packet size is %d(%p)\n", pkt.size, pkt.data);
//encode
fwrite(pkt.data, 1, pkt.size, outfile);
fflush(outfile);
// release pkt
av_packet_unref(&pkt);
}
__ERROR:
if(outfile){
// close file
fclose(outfile);
}
// close device and release ctx
if(fmt_ctx){
avformat_close_input(&fmt_ctx);
}
av_log(NULL, AV_LOG_DEBUG, "finish!\n");
return;
}
视频采集例程H文件
#ifndef testc_h
#define testc_h
#include <stdio.h>
#include "libavutil/avutil.h"
#include "libavdevice/vadevice.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswresample/swresample.h"
void set_status(int status);
void rec_vedio(void);
#endif /* testc_h */
视频采集例程c文件
// 视频采集例程
#include "testc.h"
#include <string.h>
static int rec_status = 0;
void set_status(int status){
rec_status = status;
}
// @brief
//return
static AVFormatContext* open_dev(){
int ret = 0;
char errors[1024] = {0};
// ctx
AVFormatContext *fmt_ctx = NULL;
AVDictionary *options = NULL;
// [[video device]:[audio device]]
//mac 0->机器摄像头, 1->桌面
char *devicename = "hw0";// 使用众多摄像头设备中的第0号(即第一个视频设备)
// register audio device
avdevice_register_all();
// get format
// mac -> avfoundation
// linux -> alsa
AVInputFormat *iformat = av_find_input_format("alsa");
/*
* AVDictionary **pm
* const char *key
* const char *value
* int flags
*/
av_dict_set(&options, "video_size", "640x480", 0);// 设置分辨率
av_dict_set(&options, "framerate", "30", 0);// 设置帧率
// open device
if((ret = avformat_open_input(&fmt_ctx, devicename, iformat, &options)) < 0 ){
av_strerror(ret, errors, 1024);
fprintf(stderr, "Failed to open vedio device, [%d]%s\n, ret errors");
return NULL;
}
return fmt_ctx;
}
void rec_vedio(){
int ret = 0;
AVFormatContext *fmt_ctx = NULL;
// pakcet
AVPacket pkt;
// set log level
av_log_set_level(AV_LOG_DEBUG);
// start record
rec_status = 1;
// create file
char *out = "/home/king/workspace/file/vedio.yuv";
FILE *outfile = fopen(out, "wb+");
// 打开设备
fmt_ctx = open_dev();
//read data from device
while((ret = av_read_frame(fmt_ctx, &pkt)) == 0 && rec_status){
av_log(NULL, AV_LOG_INFO, "packet size is %d(%p)\n", pkt.size, pkt.data);
//encode
//fwrite(pkt.data, 1, pkt.size, outfile);
fwrite(pkt.data, 1, 614400, outfile);
fflush(outfile);
// release pkt
av_packet_unref(&pkt);
}
__ERROR:
if(outfile){
// close file
fclose(outfile);
}
// close device and release ctx
if(fmt_ctx){
avformat_close_input(&fmt_ctx);
}
av_log(NULL, AV_LOG_DEBUG, "finish!\n");
return;
}