采集设备视频(实战)(待验证)

要修改的点

  • 修改设备名称
    之前音频的采集程序使用的设备名称是音频的名称,现在要改为视频的名称。
  • 增加参数
    确定采集视频的YUV格式、分辨率、帧率等
  • 修改文件名及文件数据的大小
    音频采集例程H文件
#ifndef testc_h
#define testc_h

#include 
#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 

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 
#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 

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;
}

你可能感兴趣的:(ffmpeg笔记)