#include <iostream>
#include <fstream>
#include <thread>extern "C"{#include <libavformat/avformat.h>
}
//预处理指令导入库
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avcodec.lib")#define CERR(err) do{if(err!=0)\{printErr(err); return -1;}\}while(0)void printErr(int err)
{char buf[1024] = { 0 };av_strerror(err, buf, sizeof(buf) - 1);cerr << buf << endl;
}int main(int argc, char* argv[])
{/**********解封装初始化************/
//打开媒体文件const char* url = "v1080.mp4";
//1, 生成解封装输入上下文, ic需要释放空间AVFormatContext* ic = nullptr;int re = avformat_open_input(&ic, url, NULL, //解封装格式,自动探测,以后缀名,或者文件头NULL);//参数设置, rtsp需要设置CERR(re);//2, 获取媒体信息 无头部格式的re = avformat_find_stream_info(ic, NULL);CERR(re);//打印封装信息av_dump_format(ic, 0, url, 0);//提取音视频流, 后面直接使用as, vsAVStream* as = nullptr;AVStream* vs = nullptr;for (int i = 0; i < ic->nb_streams; ++i) {if (ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {as = ic->streams[i];cout << "===音频===" << endl;cout << "sample_rate:" << as->codecpar->sample_rate << endl;}else if (ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {vs = ic->streams[i];cout << "===视频===" << endl;cout << "width:" << vs->codecpar->width << endl;cout << "height" << vs->codecpar->height << endl;}}/***************************//**********封装初始化************///1, 封装上下文  ec需要释放空间AVFormatContext* ec = nullptr;re = avformat_alloc_output_context2(&ec, NULL, NULL, out_url);CERR(re);
//2, 添加视频流, 音频流AVStream* mvs = avformat_new_stream(ec, NULL); //在后面通过上下文设置编码器指针AVStream* mas = avformat_new_stream(ec, NULL);//3, 打开输出IO 需要关闭re = avio_open(&ec->pb, out_url, AVIO_FLAG_WRITE);CERR(re);//如果需要重编码, 下面4,5步骤的这些参数的设置就要重新计算//4, 设置编码音视频流参数mvs->time_base = vs->time_base; //时间基数与原视频一致mas->time_base = as->time_base;mvs->codecpar->codec_tag = 0;mas->codecpar->codec_tag = 0;//5, 从解封装复制参数avcodec_parameters_copy(mvs->codecpar, vs->codecpar);avcodec_parameters_copy(mas->codecpar, as->codecpar);//6, 写入文件头re = avformat_write_header(ec, NULL);CERR(re);//打印输出上下文av_dump_format(ec, 0, out_url, 1);   /***************************//**********截取视频seek 10-20s************///取多不取少  假定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,  以视频流为准, 到第20s的pts就结束封装//换算公式 播放时间time = pts * timebase//令 vs->pts * vs->timebase = timeif (vs && vs->time_base.num > 0) { //除以分数就要判断分数的分子不为零double t = (double)vs->time_base.den / (double)vs->time_base.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输入媒体文件 移动到第十秒的关键帧位置re = av_seek_frame(ic, vs->index, begin_pts,AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME);//向后关键帧CERR(re);/****************************************/AVPacket pkt;while (1){re = av_read_frame(ic, &pkt); //从封装中读一包,有可能是视频包也有可能是音频包if (re != 0) CERR(re);AVStream* out_stream = nullptr;long long offset_pts = 0;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;}if (as && pkt.stream_index == as->index) {//读到的是音频包cout << "音频";out_stream = ec->streams[1];offset_pts = begin_audio_pts;}AVStream* in_stream = nullptr;if(pkt.stream_index <= 1){in_stream = ic->streams[pkt.stream_index];//可能是视频,也可能是音频//重新计算pts dts duration//a * bq (输入basetime)/ cq(输出basetime)   basetime存在AVStream中//因为进行了seek操作, 所以要输入的pts减去前面跳过的ptspkt.pts = av_rescale_q_rnd(pkt.pts - offset_pts, in_stream->time_base, out_stream->time_base,(AVRounding)(AV_ROUND_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_INF | AV_ROUND_PASS_MINMAX));pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);pkt.pos = -1;}//写入音视频帧av_interleaved_write_frame(ec, &pkt);av_packet_unref(&pkt);}//写入结尾re = av_write_trailer(ec);CERR(re);avformat_close_input(&ic);avio_closep(&ec->pb);avformat_free_context(ec);ec = nullptr;return 0;
}

ffmpeg之mp4文件解封装截取一段视频并重封装相关推荐

  1. 解决ffmpeg生成mp4文件不能正常预览的问题

    框架的使用极大的提高了开发效率,让我们能够有更多的精力去关注系统的整体架构和业务需求,而不需要过多的关注一些具体的实现细节,但任何事情都有两面性,如果某个细节出了问题,由于对具体的实现不了解,那么会给 ...

  2. ffmpeg截取一段视频中一段视频

    ffmpeg截取一段视频中一段视频 ffmpeg  -i ./plutopr.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 ./cut ...

  3. 如何基于ffmpeg截取一段视频中的多个片段,并合并在一起,且不改变原来的效果?

    ffmpeg截取一段视频中一段视频 ffmpeg  -i ./plutopr.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 ./cut ...

  4. matlab截取一段视频和裁剪一小块视频区域

    截取一段视频的400帧~600帧 function [vidFile,samplingRate] = Get_Vedio()addpath(genpath('.')); global inFile;% ...

  5. windows使用ffmpeg将mp4文件转变成h264视频文件

    我是直接使用ffmpeg的安装包,win10下 首先下载ffmpeg http://www.ffmpeg.org/download.htmlhttp://www.ffmpeg.org/download ...

  6. 使用ffmpeg从mp4文件中提取视频流到h264文件中

    注释: -i 2018.mp4:  是输入的MP4文件 -codec copy: 从mp4中拷贝 -bsf: h264_mp4toannexb: 从mp4拷贝到annexB封装 -f h264: 采用 ...

  7. FFMpeg写MP4文件例子分析

    这段时间看了FFMpeg提供的例子muxing.c,我略微修改了下源代码,使其生成一个MP4文件,音频使用AAC编码,视频使用H.264编码.代码很简单,我就不做说明了,代码如下.以后我们继续写如何将 ...

  8. ffmpeg截取一段视频

    ffmpeg  -i ./plutopr.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 ./cutout1.mp4 -y -ss ti ...

  9. ffmpeg 截取一段视频命令

    ffmpeg  -i ./plutopr.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 ./cutout1.mp4 -y -ss ti ...

最新文章

  1. Ubuntu下makefile及gcc生成静态库动态库的简单使用举例
  2. jquery总结和注意事项
  3. AAAI 2020 | MaskGEC:通过动态掩蔽改善语法纠错
  4. webgl值得重视的基础构建
  5. r.java自动删除变量_比较变量并删除一个最低值R [关闭]
  6. Linux开发_最全在Ubnutu环境下为你的程序设置快捷启动项和启动时管理员权限
  7. 常见数据结构总结,持续更新...
  8. 【基础知识】.Net基础加强 第四天
  9. Java 学习笔记·十二 —— Java 案例·网上商城系统
  10. SWF也能修改!硕思闪客精灵专业Flash反编译工具
  11. 妙计叠出,谋而后动——融云以“锦囊”之策,守护客户全生命周期
  12. xlsx的python处理
  13. adb devices offline_android adb devices offline的解决办法
  14. 关于H.264 profile-level-id
  15. php实现word文档在线浏览功能,配置安装手记
  16. 纷享销客高燕:回归第一性原理,B2B企业如何向精益化要增长
  17. 精彩回顾 | 一文盘点2021年中小企业数字化转型最新趋势
  18. 跨考计算机复试自我介绍,复试之自我介绍_跨考网
  19. c语言二重指针做参数,C语言二重指针的运用
  20. [caffe学习笔记]用自己的数据进行训练和测试

热门文章

  1. mapbox 绘制路线并展示路线长度
  2. 追剧人的福利来了,这几款APP让你痛快追剧
  3. 安卓版企业微信下载的文件保存目录
  4. 长时间从事电脑操作者,知道怎样保护你的眼睛吗?
  5. 统计学上数据的处理和图标的展示原则
  6. springboot 与rabbitmq集成+生产者投递确认+消费者手动确认+TTL+死信队列+延时队列
  7. c语言中handle的用法,handle什么意思_handle的用法和短语例句
  8. Android课程设计倒计时app,999倒计时计时器课程设计.docx
  9. ZZNUOJ_C语言1134:字符串转换(附完整源码)
  10. 为Debian解决Mercury MW150US无线网卡驱动