FFmpeg常用API与示例(一)—— 工具库篇(av_log、AVDictionary、avio)

2024-05-11 09:36

本文主要是介绍FFmpeg常用API与示例(一)—— 工具库篇(av_log、AVDictionary、avio),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

工具层

1.av_log

可以设置日志的级别,这个看看名字就明白了,也不用过多的解释。

  • AV_LOG_PANIC
  • AV_LOG_FATAL
  • AV_LOG_ERROR
  • AV_LOG_WARNING
  • AV_LOG_INFO
  • AV_LOG_VERBOSE
  • AV_LOG_DEBUG
void test_log()
{/ av_register_all();AVFormatContext *pAVFmtCtx = NULL;pAVFmtCtx = avformat_alloc_context();printf("====================================\n");av_log(pAVFmtCtx, AV_LOG_PANIC, "Panic: Something went really wrong and we will crash now.\n");av_log(pAVFmtCtx, AV_LOG_FATAL, "Fatal: Something went wrong and recovery is not possible.\n");av_log(pAVFmtCtx, AV_LOG_ERROR, "Error: Something went wrong and cannot losslessly be recovered.\n");av_log(pAVFmtCtx, AV_LOG_WARNING, "Warning: This may or may not lead to problems.\n");av_log(pAVFmtCtx, AV_LOG_INFO, "Info: Standard information.\n");av_log(pAVFmtCtx, AV_LOG_VERBOSE, "Verbose: Detailed information.\n");av_log(pAVFmtCtx, AV_LOG_DEBUG, "Debug: Stuff which is only useful for libav* developers.\n");printf("====================================\n");avformat_free_context(pAVFmtCtx);
}
2.AVDictionary
  • AVDictionary
  • AVDictionaryEntry
  • av_dict_set
  • av_dict_count
  • av_dict_get
  • av_dict_free
void test_avdictionary()
{AVDictionary *d = NULL;AVDictionaryEntry *t = NULL;av_dict_set(&d, "name", "zhangsan", 0);av_dict_set(&d, "age", "22", 0);av_dict_set(&d, "gender", "man", 0);av_dict_set(&d, "email", "www@www.com", 0);// av_strdup()char *k = av_strdup("location");char *v = av_strdup("Beijing-China");av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);printf("====================================\n");int dict_cnt = av_dict_count(d);printf("dict_count:%d\n", dict_cnt);printf("dict_element:\n");while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)){printf("key:%10s  |  value:%s\n", t->key, t->value);}t = av_dict_get(d, "email", t, AV_DICT_IGNORE_SUFFIX);printf("email is %s\n", t->value);printf("====================================\n");av_dict_free(&d);
}
3.AVParseUtil
  • av_parse_video_size
  • av_parse_video_rate
  • av_parse_time
  • av_parse_color
  • av_parse_ratio
void test_parseutil()
{char input_str[100] = {0};printf("========= Parse Video Size =========\n");int output_w = 0;int output_h = 0;strcpy(input_str, "1920x1080");av_parse_video_size(&output_w, &output_h, input_str);printf("w:%4d | h:%4d\n", output_w, output_h);// strcpy(input_str,"vga");//640x480(4:3)// strcpy(input_str,"hd1080");//high definitionstrcpy(input_str, "pal"); // ntsc(N制720x480), pal(啪制720x576)av_parse_video_size(&output_w, &output_h, input_str);printf("w:%4d | h:%4d\n", output_w, output_h);printf("========= Parse Frame Rate =========\n");AVRational output_rational = {0, 0};strcpy(input_str, "15/1");av_parse_video_rate(&output_rational, input_str);printf("framerate:%d/%d\n", output_rational.num, output_rational.den);strcpy(input_str, "pal"); // fps:25/1av_parse_video_rate(&output_rational, input_str);printf("framerate:%d/%d\n", output_rational.num, output_rational.den);printf("=========== Parse Time =============\n");int64_t output_timeval; // 单位:微妙, 1S=1000MilliSeconds, 1MilliS=1000MacroSecondsstrcpy(input_str, "00:01:01");av_parse_time(&output_timeval, input_str, 1);printf("microseconds:%lld\n", output_timeval);printf("====================================\n");
}

协议层

协议操作:三大数据结构

  • AVIOContext
  • **URLContext **
  • URLProtocol

协议(文件)操作的顶层结构是 AVIOContext,这个对象实现了带缓冲的读写操作;FFMPEG的输入对象 AVFormat 的 pb 字段指向一个 AVIOContext。

AVIOContext 的 opaque 实际指向一个 URLContext 对象,这个对象封装了协议对象及协议操作对象,其中 prot 指向具体的协议操作对象,priv_data 指向具体的协议对象。

URLProtocol 为协议操作对象,针对每种协议,会有一个这样的对象,每个协议操作对象和一个协议对象关联,比如,文件操作对象为 ff_file_protocol,它关联的结构体是FileContext。

1.avio 实战:打开本地文件或网络直播流
  • avformat_network_init
  • avformat_alloc_context
  • avformat_open_input
  • avformat_find_stream_info
int main_222929s(int argc, char *argv[]){/av_register_all();avformat_network_init();printf("hello,ffmpeg\n");AVFormatContext* pFormatCtx = NULL;AVInputFormat *piFmt = NULL;printf("hello,avformat_alloc_context\n");// Allocate the AVFormatContext:pFormatCtx = avformat_alloc_context();printf("hello,avformat_open_input\n");//打开本地文件或网络直播流//rtsp://127.0.0.1:8554/rtsp1//ande_10s.mp4if (avformat_open_input(&pFormatCtx, "rtsp://127.0.0.1:8554/rtsp1", piFmt, NULL) < 0) {printf("avformat open failed.\n");goto quit;}else {printf("open stream success!\n");}if (avformat_find_stream_info(pFormatCtx, NULL)<0){printf("av_find_stream_info error \n");goto quit;}else {printf("av_find_stream_info success \n");printf("******nb_streams=%d\n",pFormatCtx->nb_streams);}quit:avformat_free_context(pFormatCtx);avformat_close_input(&pFormatCtx);avformat_network_deinit();return 0;
}
2.avio 实战:自定义 AVIO
int read_func(void* ptr, uint8_t* buf, int buf_size)
{FILE* fp = (FILE*)ptr;size_t size = fread(buf, 1, buf_size, fp);int ret = size;printf("Read Bytes:%d\n", size);return ret;}int64_t seek_func(void *opaque, int64_t offset, int whence)
{int64_t ret;FILE *fp = (FILE*)opaque;if (whence == AVSEEK_SIZE) {return -1;}fseek(fp, offset, whence);return ftell(fp);}int main(int argc, char *argv[]){///av_register_all();printf("hello,ffmpeg\n");int ret = 0;FILE* fp = fopen("ande_10s.flv", "rb");int nBufferSize = 1024;unsigned char* pBuffer = (unsigned char*)malloc(nBufferSize);AVFormatContext* pFormatCtx = NULL;AVInputFormat *piFmt = NULL;printf("hello,avio_alloc_context\n");// Allocate the AVIOContext://请同学们自己揣摩AVIOContext* pIOCtx = avio_alloc_context(pBuffer, nBufferSize,0,fp,read_func,0,seek_func);printf("hello,avformat_alloc_context\n");// Allocate the AVFormatContext:pFormatCtx = avformat_alloc_context();// Set the IOContext:pFormatCtx->pb = pIOCtx;//关联,绑定pFormatCtx->flags = AVFMT_FLAG_CUSTOM_IO;printf("hello,avformat_open_input\n");//打开流if (avformat_open_input(&pFormatCtx, "", piFmt, NULL) < 0) {printf("avformat open failed.\n");goto quit;}else {printf("open stream success!\n");}if (avformat_find_stream_info(pFormatCtx, NULL)<0){printf("av_find_stream_info error \n");goto quit;}else {printf("av_find_stream_info success \n");printf("******nb_streams=%d\n",pFormatCtx->nb_streams);}quit:avformat_free_context(pFormatCtx);avformat_close_input(&pFormatCtx);free(pBuffer);return 0;
}
3.avio 实战:自定义数据来源
  • av_file_map
  • avformat_alloc_context
  • av_malloc
  • avio_alloc_context
  • avformat_open_input
  • avformat_find_stream_info
//自定义缓冲区
struct buffer_data {uint8_t *ptr;size_t size; ///< size left in the buffer
};//读取数据(回调函数)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
{struct buffer_data *bd = (struct buffer_data *)opaque;buf_size = FFMIN(buf_size, bd->size);if (!buf_size)return AVERROR_EOF;printf("ptr:%p size:%d\n", bd->ptr, bd->size);/* copy internal buffer data to buf *//// 灵活应用[内存buf]:读取的是内存,比如:加密播放器,这里解密memcpy(buf, bd->ptr, buf_size);bd->ptr  += buf_size;bd->size -= buf_size;return buf_size;
}int main(int argc, char *argv[])
{AVFormatContext *fmt_ctx = NULL;AVIOContext *avio_ctx = NULL;uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;size_t buffer_size, avio_ctx_buffer_size = 4096;char *input_filename = NULL;int ret = 0;struct buffer_data bd = { 0 };printf("Hello,ffmpeg\n");if (argc != 2) {fprintf(stderr, "usage: %s input_file\n""API example program to show how to read from a custom buffer ""accessed through AVIOContext.\n", argv[0]);return 1;}input_filename = argv[1];/* slurp file content into buffer *////内存映射文件ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);if (ret < 0)goto end;printf("av_file_map,ok\n");/* fill opaque structure used by the AVIOContext read callback */bd.ptr  = buffer;bd.size = buffer_size;/// 创建对象:AVFormatContextif (!(fmt_ctx = avformat_alloc_context())) {ret = AVERROR(ENOMEM);goto end;}printf("avformat_alloc_context,ok\n");/// 分配内存avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);if (!avio_ctx_buffer) {ret = AVERROR(ENOMEM);goto end;}/// 创建对象:AVIOContext,注意参数avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,0,&bd,&read_packet,NULL,NULL);if (!avio_ctx) {ret = AVERROR(ENOMEM);goto end;}fmt_ctx->pb = avio_ctx;printf("avio_alloc_context,ok\n");/// 打开输入流ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);if (ret < 0) {fprintf(stderr, "Could not open input\n");goto end;}printf("avformat_open_input,ok\n");/// 查找流信息ret = avformat_find_stream_info(fmt_ctx, NULL);if (ret < 0) {fprintf(stderr, "Could not find stream information\n");goto end;}printf("avformat_find_stream_info,ok\n");printf("******nb_streams=%d\n",fmt_ctx->nb_streams);av_dump_format(fmt_ctx, 0, input_filename, 0);end:avformat_close_input(&fmt_ctx);/* note: the internal buffer could have changed, and be != avio_ctx_buffer */if (avio_ctx)av_freep(&avio_ctx->buffer);avio_context_free(&avio_ctx);/// 内存映射文件:解绑定av_file_unmap(buffer, buffer_size);if (ret < 0) {fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));return 1;}return 0;
}

这篇关于FFmpeg常用API与示例(一)—— 工具库篇(av_log、AVDictionary、avio)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/979164

相关文章

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

MySQL 定时新增分区的实现示例

《MySQL定时新增分区的实现示例》本文主要介绍了通过存储过程和定时任务实现MySQL分区的自动创建,解决大数据量下手动维护的繁琐问题,具有一定的参考价值,感兴趣的可以了解一下... mysql创建好分区之后,有时候会需要自动创建分区。比如,一些表数据量非常大,有些数据是热点数据,按照日期分区MululbU

golang中reflect包的常用方法

《golang中reflect包的常用方法》Go反射reflect包提供类型和值方法,用于获取类型信息、访问字段、调用方法等,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录reflect包方法总结类型 (Type) 方法值 (Value) 方法reflect包方法总结