FFmpeg学习记录(二)—— ffmpeg多媒体文件处理

1.日志系统

常用的日志级别:

  • AV_LOG_ERROR
  • AV_LOG_WARNING
  • AV_LOG_INFO
  • AV_LOG_DEBUG
#include <stdio.h>
#include <libavutil/log.h>int main(int argc, char *argv[])
{av_log_set_level(AV_LOG_DEBUG);av_log(NULL, AV_LOG_DEBUG, "hello world!\n");return 0;
}

2.文件的删除与重命名

文件删除与重命名的API:

  • avpriv_io_delete()
  • avpriv_io_move()
	int ret;// 重命名ret = avpriv_io_move("111.txt", "222.txt");if(ret < 0) {av_log(NULL, AV_LOG_ERROR, "Failed to rename\n");return -1;}av_log(NULL, AV_LOG_INFO, "Success to renmae\n");// 删除ret = avpriv_io_delete("./test.txt");if(ret < 0) {av_log(NULL, AV_LOG_ERROR, "Failed to delete\n");return -1;}av_log(NULL, AV_LOG_INFO, "Success to delete\n");

3.目录操作

操作目录重要函数:

  • avio_open_dir()
  • avio_read_dir()
  • avio_close_dir()

操作目录重要结构体:

  • AVIODirContext
  • AVIODirEntry
    avdevice_register_all();int ret;AVIODirContext *ctx = NULL;AVIODirEntry *entry = NULL;av_log_set_level(AV_LOG_INFO);ret = avio_open_dir(&ctx, "./", NULL);if(ret < 0){av_log(NULL, AV_LOG_ERROR, "Can't open dir: %s\n", av_err2str(ret));return -1;}while(1) {avio_read_dir(ctx, &entry);if(ret < 0){av_log(NULL, AV_LOG_ERROR, "Can't read dir: %s\n", av_err2str(ret));goto __fail;}if(!entry) {break;}av_log(NULL, AV_LOG_INFO,"%-9s %12"PRId64"  %s\n", entry->size, entry->name);avio_free_directory_entry(&entry);}__fail:avio_close_dir(&ctx);

4.抽取音频数据

  • 1.处理一些参数
  • 2.打开多媒体文件
  • 3.从多媒体文件中找到音频流
  • 4.打开目的文件的上下文
  • 5.为目的文件,创建一个新的音频流
  • 6.设置输出音频参数
  • 7.写多媒体文件头到目的文件
  • 8…从源多媒体文件中读音频数据到目的文件中
  • 9.写多媒体文件尾到文件中
  • 10.将申请的资源释放掉

步骤比较多,一点一点来实现:

 // 1.处理一些参数if(argc < 3) {av_log(NULL, AV_LOG_INFO, "argument must be 3");exit(-1);}src = argv[1];dst = argv[2];// 2.打开多媒体文件ret = avformat_open_input(&pFmtCtx, src, NULL, NULL);if(ret < 0) {av_log(NULL, AV_LOG_ERROR, "%s\n", av_err2str(ret));exit(-1);}
// 3.从多媒体文件中找到音频流idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);if(idx < 0) {av_log(pFmtCtx, AV_LOG_ERROR, "Does not include audio\n");goto _ERROR;}// 4.打开目的文件的上下文oFmtCtx = avformat_alloc_context();if(!oFmtCtx) {av_log(NULL, AV_LOG_ERROR, "No Memory\n");goto _ERROR;}outFmt = av_guess_format(NULL, dst, NULL);oFmtCtx->oformat = outFmt;// 5.为目的文件,创建一个新的音频流outStream = av_format_new_stream(oFmtCtx, NULL);// 6.设置输出音频参数inStream = pFmtCtx->stream[idx];avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);outStream->codecpar->codec_tag = 0;
    // 7.写多媒体文件头到目的文件ret = avformat_write_header(oFmtCtx, NULL);if(ret < 0) {av_log(NULL, AV_LOG_ERROR, "%s\n", av_err2str(ret));goto _ERROR;}// 8.聪源多媒体文件中读到音频数据到目的文件中while(av_read_frame(pFmtCtx, &pkt) >= 0) {if(pkt.stream_index == idx) {pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);pkt.dts = pkt.dts;pkt.duration = av_rescale_q(pkt.duration, inStream->time_base, outStream->time_base);pkt.stream_index = 0;pkt.pos = -1;av_interleaved_write_frame(oFmtCtx, &pkt);av_packet_unref(&pkt);}}// 9.写多媒体文件尾到文件中av_write_trailer(oFmtCtx);// 10.将申请的资源释放掉
_ERROR:if(pFmtCtx) {avformat_close_input(&pFmtCtx);pFmtCtx = NULL;}if(oFmtCtx->pb) {avio_close(oFmtCtx->pb);}if(oFmtCtx) {avformat_free_context(oFmtCtx);oFmtCtx = NULL;}

6.抽取视频数据

与处理音频流程相同,简单修改即可

 // 3.从多媒体文件中找到视频流idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);if(idx < 0) {av_log(pFmtCtx, AV_LOG_ERROR, "Does not include VIDEO\n");goto _ERROR;}... ...// 8.从源多媒体文件中读到视频数据到目的文件中while(av_read_frame(pFmtCtx, &pkt) >= 0) {if(pkt.stream_index == idx) {pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);pkt.dts = av_rescale_q_rnd(pkt.dts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);// pkt.dts = pkt.dts;pkt.duration = av_rescale_q(pkt.duration, inStream->time_base, outStream->time_base);pkt.stream_index = 0;pkt.pos = -1;av_interleaved_write_frame(oFmtCtx, &pkt);av_packet_unref(&pkt);}}

6.多媒体格式转封装

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

7.视频裁剪

在这里插入图片描述

程序是在上面的程序基础上修改的,这里就把核心修改地方贴出来。

有两个注意点:(对应下面的修改2和修改3)

第一个是音视频时间的问题。

针对音频:从第5秒钟截取,那他就是第5秒。针对视频:因为有IPB 帧,如果刚好第5秒是P帧或者B帧,没有了I帧,那么就不能解码成功,播放的时候就会花屏。

解决:告诉ffmpeg如果不是I帧,就要向前或者向后找最近的I帧

第二个是时间的问题。

由于是裁剪,所以需要计算相对时间。 使用后面的时间减去第一个时间基的时间,这样子才能保证时间的正确性。音频的dts和pts是相同的,而视频可能是不同的,所以这里需要多加一步判断。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/6467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【软考高项】三十一、成本管理4个过程

一、规划成本管理 1、定义、作用 定义&#xff1a;确定如何估算、预算、管理、监督和控制项目成本的过程作用&#xff1a;在整个项目期间为如何管理项目成本提供指南和方向 应该在项目规划阶段的早期就对成本管理工作进行规划&#xff0c;建立各成本管理过程的基本框架&…

RKNN Toolkit2 工具的使用

RKNN Toolkit2 是由瑞芯微电子 (Rockchip) 开发的一套用于深度学习模型优化和推理的工具。它主要面向在瑞芯微SoC上进行AI应用开发&#xff0c;但也可以用于PC平台进行模型的转换、量化、推理等操作。它支持将多种深度学习框架的模型&#xff08;如Caffe, TensorFlow, PyTorch等…

单例、工厂、策略、装饰器设计模式

1. 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a; 单例模式是一种常用的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点。这种模式的特点是类自己负责保存其唯一的实例&#xff0c;并控制其实例化过程。单例模式广泛应用…

【hackmyvm】vivifytech靶机

渗透思路 信息收集端口扫描端口服务信息目录扫描爆破hydra--sshgit提权 信息收集 ┌──(kali㉿kali)-[~] └─$ fping -ag 192.168.9.0/24 2>/dev/null 192.168.9.119 --主机 192.168.9.164 --靶机个人习惯&#xff0c;也方便后续操作&#xff0c;将IP地址赋值给一个变…

【R语言数据分析】卡方检验

目录 交叉卡方检验 配对卡方检验 趋势卡方检验 交叉卡方检验 交叉卡方表用于比较组间“率”的差异。适用于分类型变量&#xff0c;被检验的分类变量应该是无序分类变量&#xff0c;分组变量可以是有序分组也可以是无序分组。比如比较两种药物治疗某个疾病的效率&#xff0c;…

Jhipster8禁用liquibase

开发环境添加dev,no-liquibase&#xff1b;

Stable Diffusion AI绘画

我们今天来了解一下最近很火的SD模型 ✨在人工智能领域&#xff0c;生成模型一直是研究的热点之一。随着深度学习技术的飞速发展&#xff0c;一种名为Stable Diffusion的新型生成模型引起了广泛关注。Stable Diffusion是一种基于概率的生成模型&#xff0c;它可以学习数据的潜…

INVS 对时钟二分频器(reg-clkgen)的理解和处理

在时钟树的设计中&#xff0c;有很多方式处理分频时钟&#xff0c;常见的无外乎两种模式&#xff1a; 时钟二分频器&#xff08;reg-clkgen&#xff09;门控时钟 二者在功能上略有不同&#xff0c;比较的大差异是前者可以简单的实现50%占空比&#xff0c;后者却对功耗友好同时…

找不到msvcp120D.dll无法继续执行代码的7个有效解决方法分享

在探讨msvcp120D.dll之前&#xff0c;首先需要明确的是&#xff0c;这个特定的动态链接库&#xff08;DLL&#xff09;文件属于Microsoft Visual C 2013的调试版本&#xff08;标记为"D"&#xff0c;代表Debug&#xff09;。这意味着它主要用于开发环境中的调试目的&…

【Linux】进程的隔离和控制:namespace 隔离、cgroup 控制

文章目录 五、namespace 隔离dd -- 读取、转换并输出数据mkfs -- 格式化文件系统df -- 显示文件系统磁盘使用情况mount -- 加载文件系统到指定的加载点unshare -- 创建子进程&#xff0c;同时与父程序不共享namespace一个 demo 六、cgroup(Control Group) 相关命令pidstat -- 监…

腾讯云IM即时通信引入(React Web端组件式)

开发环境要求 React ≥ v18.0 &#xff08;17.x 版本不支持&#xff09; TypeScript node&#xff08;12.13.0 ≤ node 版本 ≤ 17.0.0, 推荐使用 Node.js 官方 LTS 版本 16.17.0&#xff09; npm&#xff08;版本请与 node 版本匹配&#xff09; chat-uikit-react 集成 …

链表(基于C语言单向链表)

链表的实现的思想 链表表示一种是基于链接结构的线性表&#xff0c;链表实现的思想如下&#xff1a; 1、将表中的元素分别储存在一批独立的储存块里面。 2、表结构中的结点都能找到与之相关的下一个结点。 3、在前一个结点里用链表的方式显示的记录与下个结点之间的关联。 链…

STM32标准库编译流程

导入库函数 在ST官方固件库中找到STM32F10x_StdPeriph_Lib_V3.5.0.zip文件&#xff0c;解压&#xff0c;打开Libraries,接着打开STM32F10x_StdPeriph_Driver文件夹&#xff0c;继续点击src&#xff0c;看到库函数源文件&#xff1a; 将其复制到keil建立的工程的文件中&#xf…

SNR: Signal to Noise Ratio

https://www.xx.com/watch?vmyrZ_R6xIZA Fang, Y., Armin, A., Meredith, P. et al. Accurate characterization of next-generation thin-film photodetectors. Nature Photon 13, 1–4 (2019). https://doi.org/10.1038/s41566-018-0288-z Wang, F., Zhang, T., Xie, R. e…

抖音直播植物大战僵尸杂交版v1.2安装包—可用于抖音直播

植物大战僵尸杂交版是由玩家自制的一款改版游戏。在这个版本中&#xff0c;各种类型的植物都被融合成了全新的形态。比如&#xff0c;向日葵和阳光菇可以产出更多的阳光&#xff0c;坚果墙和火炬树桩合体成为能抗能辅的超级植物等等。这些融合植物种类繁多&#xff0c;各具特色…

从不平凡Image文件夹,自定义读取img和label,构造dataset

问题描述 torchvision.datasets.ImageFolder 假定&#xff1a;子文件名子文件夹的图像的标签 但在KDEF文件夹中&#xff0c;子文件夹下有所有的类&#xff0c;不宜用ImageFolder读取path来得到dataset My 实现&#xff1a; # how to build dataset? from torch.utils import …

AI-数学-高中-47导数与几何意义

原作者视频&#xff1a;【导数】【考点精华】7导数与几何意义考点解析&#xff08;基础&#xff09;_哔哩哔哩_bilibili 该点处切点的斜率 该点处导函数的值 示例1&#xff1a; 导数问题解决最常用方法&#xff1a;参数分离&#xff0c;在左边函数有解的值域范围内。 示例2&…

Netty 网络编程深入学习【一】:ByteBuffer 源码解析

ByteBuffer源码阅读 ByteBuffer是一个用于处理字节数据的缓冲区类。它是Java NIO 包的一部分&#xff0c;提供了一种高效的方式来处理原始字节数据。 ByteBuffer 可以用来读取、写入、修改和操作字节数据&#xff0c;它是一种直接操作字节的方式&#xff0c;比起传统的 InputSt…

基于Spring Boot的在线BLOG网设计与实现

基于Spring Boot的在线BLOG网设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台首页管理界面&#xff0c;用户经过登录前台首页查看通…