ffmpeg 基本概念

  • 多媒体文件其实是个容器(比如mp4是个包装盒,里面可以放mp3/aac, h264视频数据)
  • 在容器里有很多流(Stream/Track)
  • 每种流是由不同的编码器编码的
  • 从流中读取的是包,在一个包中包含着一个或多个帧

 

常用结构体

AVFormatContext 格式上下文

AVStream 流

AVPacket

 

 

打印音视频信息

  • avformat_open_input/avformat_close_input
  • av_find_input_format
  • av_dump_format

 

要想对一个文件进行分析我们首先要获取到AVFormatContext,通过avformat_open_input函数

int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options);

参数

ps ,AVFormatContext*的地址

url,要处理的文件\设备

AVInputFormat,如果为NULL,就会按照url的后缀自动匹配AVInputFormat

AVDictionary 命令行输入的参数,一般不使用,如果采集视频需要设置编码格式,分辨率,帧率

 

如何获取AVInputFormat呢?

可以通过av_find_input_format

/**

* Find AVInputFormat based on the short name of the input format.

*/

ff_const59 AVInputFormat *av_find_input_format(const char *short_name);

 

我们打开mac的麦克风与摄像头

char *devicename="0:0"; //冒号前面是摄像头,冒号后面是麦克风

AVDictionary *options = NULL;

avdevice_register_all();

AVInputFormat * iformat = av_find_input_format("avfoundation");

av_dict_set(&options, "video_size", "640x480", 0);

av_dict_set(&options, "framerate", "30", 0);

av_dict_set(&options, "pixel_format", "yuv420p", 0);

 

ret = avformat_open_input(&format_context, devicename, iformat, &options);

 

如果只采集音频 options可以不设置

av_find_input_format 传入的参数avfoundataion/dshow/alsa

avfoundataion mac

dshow  windows

alsa  linux

av_dump_format 打印输入文件的流信息

#include<stdio.h>
#include<libavutil/log.h>
#include<libavformat/avformat.h>
#include<libavdevice/avdevice.h>


void open_file(){
  AVFormatContext *fmt_ctx;
    int ret;
    char *url = "/Users/yuanxuzhen/study/mac/ffmpeg_demo/output/sync_714251_3900875.mp4";
    av_log(NULL, AV_LOG_ERROR, "open_file\n");
    ret = avformat_open_input(&fmt_ctx, url, NULL, NULL);
    if(ret < 0){
        av_log(NULL, AV_LOG_ERROR, "avformat_open_input %s", av_err2str(ret));
        goto  __ERROR;
    }
    av_dump_format(fmt_ctx, 0, url, 0);
 __ERROR:
    if(fmt_ctx) {
        avformat_close_input(&fmt_ctx);
    }
}


void open_audio(){
    av_log(NULL, AV_LOG_ERROR, "open_audio\n");
    AVFormatContext *fmt_ctx;
    int ret;
    char *url = ":0";
    AVInputFormat *input_format;
    avdevice_register_all(); //注册设备
    input_format = av_find_input_format("avfoundation");
    if(!input_format){
       av_log(NULL, AV_LOG_ERROR, "av_find_input_format error\n");
        return;
    }

    ret = avformat_open_input(&fmt_ctx, url, input_format, NULL);
    if(ret < 0){
        av_log(NULL, AV_LOG_ERROR, "avformat_open_input %s\n", av_err2str(ret));
        goto  __ERROR;
    }
    av_dump_format(fmt_ctx, 0, url, 0);
 __ERROR:
    if(fmt_ctx) {
        avformat_close_input(&fmt_ctx);
    }
}

void open_video(){
    av_log(NULL, AV_LOG_ERROR, "open_video\n");
    AVFormatContext *fmt_ctx;
    int ret;
    char *url = "0:";
    AVInputFormat *input_format;
    AVDictionary *options = NULL;
    avdevice_register_all(); //注册设备
    input_format = av_find_input_format("avfoundation");
    if(!input_format){
       av_log(NULL, AV_LOG_ERROR, "open_video av_find_input_format error\n");
       return;
    }
    av_dict_set(&options, "video_size", "640x480", 0);
    av_dict_set(&options, "framerate", "30", 0);
    av_dict_set(&options, "pixel_format", "nv12", 0);

    ret = avformat_open_input(&fmt_ctx, url, input_format, &options);
    if(ret < 0){
        av_log(NULL, AV_LOG_ERROR, "open_video avformat_open_input %s\n", av_err2str(ret));
        goto  __ERROR;
    }
    av_dump_format(fmt_ctx, 0, url, 0);
 __ERROR:
    if(fmt_ctx) {
        avformat_close_input(&fmt_ctx);
    }
}


void open_video_and_audio(){
    av_log(NULL, AV_LOG_ERROR, "open_video_and_audio\n");
    AVFormatContext *fmt_ctx;
    int ret;
    char *url = "0:0";
    AVInputFormat *input_format;
    AVDictionary *options = NULL;
    avdevice_register_all(); //注册设备
    input_format = av_find_input_format("avfoundation");
    if(!input_format){
       av_log(NULL, AV_LOG_ERROR, "open_video_and_audio av_find_input_format error\n");
       return;
    }
    av_dict_set(&options, "video_size", "640x480", 0);
    av_dict_set(&options, "framerate", "30", 0);
    av_dict_set(&options, "pixel_format", "nv12", 0);

    ret = avformat_open_input(&fmt_ctx, url, input_format, &options);
    if(ret < 0){
        av_log(NULL, AV_LOG_ERROR, "open_video_and_audio avformat_open_input %s\n", av_err2str(ret));
        goto  __ERROR;
    }
    av_dump_format(fmt_ctx, 0, url, 0);
 __ERROR:
    if(fmt_ctx) {
        avformat_close_input(&fmt_ctx);
    }
}


int main(int argc, char* argv[]){
    av_log_set_level(AV_LOG_INFO); 
    // open_file();
    // open_audio();
    open_video_and_audio();
    return 0;
}


从输出中我们可以看到多媒体的信息。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值