1. 打开视频设备
- 设置url,"0"表示使用摄像头,”1“表示录制桌面;
- 需要设置分辨率、帧率、采样格式,每个设备支持的参数可能都不一样;
2. 将数据写入文件
- 在从包里面取数据时候,要自己根据采样的格式计算正确的size,如yuv420 = 分辨率宽 x 分辨率高 x 1.5;
3. 实战代码
static AVFormatContext* open_device() {
avdevice_register_all();
AVFormatContext *ctx = NULL;
AVDictionary *options = NULL;
AVInputFormat *fmt = av_find_input_format("avfoundation");
// 0 表示摄像头 1 表示录制桌面
char *device_name = "0";
// 设置分辨率
av_dict_set(&options, "video_size", "640*480", 0);
// 设置帧率
av_dict_set(&options, "framerate", "29.97", 0);
// 设置采样格式
av_dict_set(&options, "pixel_format", "nv12", 0);
int result = avformat_open_input(&ctx, device_name, fmt, &options);
if (result < 0 ) {
char error[1024];
av_make_error_string(error, 1024, result);
printf("打开设备失败:%s", error);
return NULL;
}
isRecording = 1;
return ctx;
}
void start_video_recorder(void) {
AVFormatContext *fmt_ctx = NULL;
fmt_ctx = open_device();
if (!fmt_ctx) {
goto __ERROR;
}
AVPacket *packet = NULL;
packet = av_packet_alloc();
if (!packet) {
goto __ERROR;
}
char *path = "/Users/cunw/Desktop/learning/音视频学习/音视频文件/video_recoder.yuv";
FILE *file = fopen(path, "wb+");
int rst = 0;
while (isRecording) {
rst = av_read_frame(fmt_ctx, packet);
if (rst == 0 && packet->size > 0) {
printf("packet size is %d\n", packet->size);
// 因为采样格式420 所以size = 640 * 480 * 1.5
fwrite(packet->data, 640 * 480 * 1.5, 1, file);
av_packet_unref(packet);
} else if (rst == -EAGAIN) {
av_usleep(1);
}
}
__ERROR:
isRecording = 0;
fflush(file);
fclose(file);
av_packet_free(&packet);
avformat_close_input(&fmt_ctx);
}
- 使用命令工具ffplay播放:ffplay -pixel_format nv12 -video_size 640x480 video_recoder.yuv
网友评论