ffmpeg封装和解封装介绍-(7)截断视频关键代码解析

计算相关pts并移动到第10s处的pts:

    /// 截取10 ~ 20 秒之间的音频视频 取多不取少// 假定 9 11秒有关键帧 我们取第9秒double begin_sec = 10.0;    //截取开始时间double end_sec = 20.0;      //截取结束时间long long begin_pts = 0;long long begin_audio_pts = 0;  //音频的开始时间long long end_pts = 0;//换算成pts 换算成输入ic的pts,以视频流为准if (vs && vs->time_base.num > 0){//sec /timebase = pts// pts =  sec/(num/den) = sec* (den/num)  double t = (double)vs->time_base.den / (double)vs->time_base.num;//den分母/num分子begin_pts = begin_sec * t;end_pts = end_sec * t;}if (as && as->time_base.num > 0)begin_audio_pts = begin_sec * ((double)as->time_base.den / (double)as->time_base.num);//seek输入媒体 移动到第十秒的关键帧位置if (vs)re = av_seek_frame(ic, vs->index, begin_pts,AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD); //向后关键帧CERR(re);

 这段代码的目的是从一个媒体文件中截取10秒到20秒之间的音频和视频数据。具体来说,它将找到第10秒和第20秒的PTS(Presentation Timestamp)值,然后将媒体文件的读位置移动到第10秒附近的关键帧位置,以便从该位置开始读取数据。

首先,定义了一些变量来存储开始和结束的时间(秒)以及对应的PTS值。begin_ptsend_pts 用于视频的PTS值,而 begin_audio_pts 用于音频的开始PTS值。 

time_basenum(分子)大于0。time_base 是FFmpeg中用来表示时间基准的结构体。代码将开始和结束时间从秒转换为PTS值。转换公式为:PTS = 秒 * (time_base.den / time_base.num)

再通过seekframe函数将输入媒体文件(通过 ic 表示)的读取位置移动到第10秒附近的关键帧位置。

把10s处的帧通过计算偏移移动到输出文件的开头:

AVPacket pkt;for (;;){re = av_read_frame(ic, &pkt);if (re != 0){PrintErr(re);break;}AVStream* in_stream = ic->streams[pkt.stream_index];AVStream* out_stream = nullptr;long long offset_pts = 0; //偏移pts,用于截断的开头pts运算if (vs && pkt.stream_index == vs->index){cout << "视频:";//超过第20秒退出,只存10~20秒if (pkt.pts > end_pts){av_packet_unref(&pkt);break;}out_stream = ec->streams[0];offset_pts = begin_pts;}else if (as && pkt.stream_index == as->index){cout << "音频:";out_stream = ec->streams[1];offset_pts = begin_audio_pts;}cout << pkt.pts << " : " << pkt.dts << " :" << pkt.size << endl;//重新计算pts dts duration//`a * bq(输入basetime) / cq(输出basetime)`if (out_stream){pkt.pts = av_rescale_q_rnd(pkt.pts - offset_pts, in_stream->time_base,out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));pkt.dts = av_rescale_q_rnd(pkt.dts - offset_pts, in_stream->time_base,out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);}pkt.pos = -1;

无限循环,循环处理每一帧。

这段代码的主要功能是在截取指定时间段(10秒到20秒)的视频和音频后,将其重新编码或写入到输出文件中。它读取输入文件的每一帧数据,根据PTS值判断是否在截取范围内,并调整PTS、DTS和duration值以适应输出文件的时间基准。

使用 av_read_frame 从输入文件中读取每一帧数据,并存储在 pkt 中。如果读取失败(re != 0),打印错误信息并退出循环。

根据 pkt.stream_index 获取输入流指针 in_stream,初始化输出流指针 out_stream 和偏移PTS offset_pts

如果当前帧的PTS值超过20秒(pkt.pts > end_pts),释放 pkt 并退出循环。

设置输出流为第一个输出流(ec->streams[0]),并设置偏移PTS为 begin_pts

设置输出流为第二个输出流(ec->streams[1]),并设置偏移PTS为 begin_audio_pts

再对outstream输出流进行重新计算pts dts duration 等值。

重新计算中减去offset_pts的原因:

当我们截取视频时,我们选择了一个开始截取的时间点,比如从视频的第 10 秒开始截取。而在视频文件中,每一帧都有一个时间戳(PTS)来表示它在视频中的时间位置。

现在,假设视频的第 10 秒对应的时间戳(PTS)是 5000。如果我们不减去偏移值,那么视频的第 10 秒就会被映射到输出文件的第 10 秒,这是正确的。但是,我们希望视频的第 10 秒被映射到输出文件的第 0 秒,因为我们是从视频的第 10 秒开始截取的。

因此,我们需要减去一个偏移值,这个偏移值就是视频的第 10 秒对应的时间戳。这样,视频的第 10 秒就会被映射到输出文件的第 0 秒,而不是第 10 秒。这就是为什么要减去偏移值的原因。

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

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

相关文章

【深度学习】基于NNCLR模型的计算机视觉自监督学习过程

1.引言 1.1.自监督学习研究的背景 进行自监督学习的研究具有深远的意义&#xff1a; 首先&#xff0c;自监督学习能够有效减少对标注数据的依赖。在实际应用中&#xff0c;获取大量标注数据往往需要消耗大量的时间和人力资源&#xff0c;特别是在一些专业领域&#xff0c;如…

Spring中自定义注解进行类方法增强

说明 说到对类方法增强&#xff0c;第一时间想到自定义注解&#xff0c;通过aop切面进行实现。这是一种常用做法&#xff0c;但是在某些场景下&#xff0c;如开发公共组件&#xff0c;定义aop切面可能不是最优方案。以后通过原生aop方式&#xff0c;自定义注解&#xff0c;对类…

jpg图片下载后如何转换格式?方法揭秘(全)

在互联网浏览中&#xff0c;我们经常下载到各种各样的图片文件&#xff0c;而JPEG&#xff08;JPG&#xff09;是其中一种常见的格式。尽管JPEG在保持图像质量的同时能够有效地压缩文件大小&#xff0c;但有时我们可能需要将下载的JPEG图片转换为其他格式&#xff0c;以满足不同…

Python基于 Jupyter Notebook 的图形可视化工具库之ipysigma使用详解

概要 在数据科学和网络分析中,图(Graph)结构是一种常用的数据结构,用于表示实体及其关系。为了方便图数据的可视化和交互操作,ipysigma 提供了一个基于 Jupyter Notebook 的图形可视化工具。通过 ipysigma,用户可以在 Jupyter Notebook 中创建、编辑和展示图结构,方便进…

流体性能测试实验室建设需求参考

在第一次提需求的时候&#xff0c;很多人感到很迷茫&#xff0c;这里以某流体实验室建设为例&#xff0c;进行说明&#xff0c;希望抛砖引玉&#xff0c;能起到一点参考作用。 一、项目概述 学校拟建一座流体性能测试实验室&#xff0c;旨在兼顾教学和企业科研能力。实验室需…

WordPress后台地址被改导致无法登陆后台的简单解决方法

WordPress修改WordPress地址和站点地址之后无法打开网站和无法后台登录的解决方法&#xff1a; 使用ssh登录服务器 xshell、SecureCRT、finalShell等工具均可。登录MySQL数据库 使用如下指令后&#xff0c;输入密码&#xff0c;打开mysql数据库&#xff1a; mysql -u root -p…

开源大模型的新星:ChatGPT-Next-Web 项目解析与推荐

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

艾体宝干货 | 老牌科技企业也难幸免的域名劫持是什么?

域名不仅是一个网络上地址&#xff0c;一个企业的域名还代表着企业的品牌、声誉&#xff0c;甚至关系到企业的生存。随着域名重要性与价值的日益凸显&#xff0c;其也逐渐成为网络黑客的目标。域名劫持是一种严重的网络安全威胁&#xff0c;如果不及时加以应对&#xff0c;会带…

物业客服“逆袭”记:从被质疑到被点赞,只因用了这款小程序

作为物业服务企业来说&#xff0c;物业客服人员是物业公司的核心部门。客服人员不仅仅要进行各部门之间的工作协调沟通&#xff0c;而且也是物业与业主沟通的主要桥梁。但是&#xff0c;往往客服人员经常被传统的报修方式所困扰&#xff0c;导致业主对物业客服人员存在质疑与谩…

主流后端开发语言对比

软件开发领域&#xff0c;语言本身在各自领域都有适用场景&#xff0c;有许多流行的编程语言可供选择&#xff0c;每种语言都有其独特的特点和适用场景。 Java、C、C、Go 、Python、C#、Ruby、PHP 等主流编程语言&#xff0c;从底层实现、效率、原理、国内外市场占有率、社区活…

Linux 文件类型权限

drwxr-xr-x 2 root root 1024 Aug 4 10:56 zfmnt drwxrwxrwx 1 root root 4096 Jun 4 2024 zfmnt在你给出的两个目录条目中&#xff0c;zfmnt 的权限似乎有所不同。不过&#xff0c;在Unix和Linux系统中&#xff0c;目录条目的权限通常不会完全相同&#xf…

机器视觉:光源的类型以及主要参数

光源在机器视觉中起着决定性的作用&#xff0c;决定了视觉算法的复杂性&#xff0c;也决定了视觉系统的精度和稳定性。光源用于突出目标物体的特征&#xff0c;增加目标物体与背景的对比度&#xff0c;克服环境光线的干扰。光源的选择与打光方式在视觉系统的前期评估中非常重要…

蓝牙体脂秤智能化方案模组

蓝牙体脂秤原理跟普通电子体重秤的原理差不多&#xff0c;都是利用压力传感器及芯片设计完成功能的实现。蓝牙电子秤的外形和地面有四个接触点&#xff0c;四个接触点那里都放着一种压力传感器&#xff0c;压力传感器将人体的重量转换成电信号&#xff0c;后经过芯片设计完成处…

【网络编程开发】7.TCP可靠传输的原理

7.TCP可靠传输的原理 TCP实现可靠传输的原理主要基于序列号和确认应答、超时重传、滑动窗口、连接管理机制以及拥塞控制等多重机制。 TCP&#xff08;Transmission Control Protocol&#xff09;&#xff0c;即传输控制协议&#xff0c;是网络通信中的一种重要协议&#xff0…

油烟净化器高强度过滤油烟:为酒店餐饮带来持久清新

我最近分析了餐饮市场的油烟净化器等产品报告&#xff0c;解决了餐饮业厨房油腻的难题&#xff0c;更加方便了在餐饮业和商业场所有需求的小伙伴们。 在现代餐饮业&#xff0c;高效的油烟净化器是酒店和餐馆不可或缺的设备。通过高强度的过滤和净化&#xff0c;油烟净化器不仅…

数据结构和矩阵细节用法:double、cell和complex #matlab

矩阵建立 建立矩阵用[]&#xff1b; 矩阵的同一行内的元素用逗号或者空格隔开&#xff1b; 矩阵的不同行的元素用分号隔开 eg. 矩阵 A 1 2 3 4 5 6 7 8 9 在matlab中矩阵A表示为&#xff1a; clc;clear; A[1,2,3;4,5,6;7,8,9]; %或者A[1 2 3;4 5 …

C++的异常捕获

目录 C语言的异常处理方式 C的异常处理方式 异常的抛出与捕获 抛出与捕获原则 异常安全 C语言的异常处理方式 1、终止程序 常见形式&#xff1a;assert 缺陷&#xff1a;太过强硬&#xff0c;如果发生内存错误&#xff0c;或者除0语法错误等就会直接终止程序 2、返回错误码…

for 、while循环

练习1&#xff1a;输入一个数&#xff0c;判断是否是完美数 完美数&#xff1a;正序和逆序的结果一致 练习2&#xff1a; * ** *** **** 练习3&#xff1a; **** *** ** * 练习4&#xff1a;输入一个数&#xff0c;计算最大公约数&#xff0c;以及最小公倍数 练习5&#xff…

排序---归并排序(简单优化前后比较)

前言 个人小记 一、优化方案 将递归调用中的创建数组空间提出&#xff0c;减少数组空间创造次数&#xff0c;从而减少运行时间。 二、代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_ARR 100000…

Unity引擎在UI上渲染粒子播放

大家好&#xff0c;我是阿赵。   在UI上面显示粒子特效&#xff0c;如果把粒子系统直接拖到Canvas里面&#xff0c;会存在很多问题&#xff0c;比如层级问题、裁剪问题等。这里分享一种用MaskableGraphic和UIVertex来显示粒子特效的方法。 一、 MaskableGraphic和UIVertex简…