1、概述

本程序实现把一个视频切割为2个视频,不涉及编解码,最难理解的地方在于pts和dts的计算,要好好看看,不够完美的地方在于没有按照关键帧切割,所以会在切割点花屏,以后改善。

*注:只处理一个视频流和一个音频流,若流多了,估计会crash。

简单说下流程:

打开输入---->打开输出---->根据输入来创建流---->拷贝流设置---->循环读帧---->判断时间点是否到达切割点,并做设置---->设置pts和dts---->写入---->善后

2、代码

/*
*最简单的视频切割
*缪国凯 Mickel
*821486004@qq.com
*本程序实现把一个视频切割为2个视频,不涉及编解码,最难理解的地方在于pts和dts的计算,要好好看看
*不够完美的地方在于没有按照关键帧切割,所以会在切割点花屏,以后改善
*注:只处理一个视频流和一个音频流,若流多了,估计会crash
*2015-5-14
*/#include "stdafx.h"#ifdef __cplusplus
extern"C"
{
#endif
#include <libavformat/avformat.h>
#include "libavcodec/avcodec.h"
#include "libavfilter/avfiltergraph.h"
#include "libavfilter/buffersink.h"
#include "libavfilter/buffersrc.h"
#include "libavutil/avutil.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libswresample\swresample.h"
#include "libavutil\fifo.h"
#include "libavutil/audio_fifo.h"#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
//#pragma comment(lib, "avdevice.lib")
#pragma comment(lib, "avfilter.lib")
//#pragma comment(lib, "postproc.lib")
#pragma comment(lib, "swresample.lib")
//#pragma comment(lib, "swscale.lib")
#ifdef __cplusplus
};
#endifint _tmain(int argc, _TCHAR* argv[])
{if(argc < 3){printf("no input file!\n");return -1;}AVFormatContext *ifmt_ctx = NULL, *ofmt1_ctx = NULL, *ofmt2_ctx = NULL;AVStream *out1_vstream = NULL, *out1_astream = NULL;AVStream *out2_vstream = NULL, *out2_astream = NULL;char str_out1_filename[10];char str_out2_filename[10];sprintf(str_out1_filename, "test1.%s", argv[2]);sprintf(str_out2_filename, "test2.%s", argv[2]);int inVideo_StreamIndex = -1,inAudio_StreamIndex = -1;int ret;av_register_all();if ((ret = avformat_open_input(&ifmt_ctx, argv[1], NULL, NULL)) < 0){printf("can not open the in put file format context!\n");return -1;}if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0){printf("can not find the input stream info!\n");goto end;}avformat_alloc_output_context2(&ofmt1_ctx, NULL, NULL, str_out1_filename);if (!ofmt1_ctx){printf( "Could not create output1 context\n");ret = AVERROR_UNKNOWN;goto end;}avformat_alloc_output_context2(&ofmt2_ctx, NULL, NULL, str_out2_filename);if (!ofmt2_ctx){printf( "Could not create output2 context\n");ret = AVERROR_UNKNOWN;goto end;}for (int i = 0; i < ifmt_ctx->nb_streams; i++){if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){inVideo_StreamIndex = i;out1_vstream = avformat_new_stream(ofmt1_ctx, NULL);out2_vstream = avformat_new_stream(ofmt2_ctx, NULL);//open decoderif(0 > avcodec_open2(ifmt_ctx->streams[i]->codec, avcodec_find_decoder(ifmt_ctx->streams[i]->codec->codec_id), NULL)){printf("can not find or open video decoder!\n");goto end;}if (!out1_vstream){printf("Failed allocating output1 video stream\n");ret = AVERROR_UNKNOWN;goto end;}else{//copy the settings of AVCodecContext;if (avcodec_copy_context(out1_vstream->codec, ifmt_ctx->streams[i]->codec) < 0){printf( "Failed to copy context from input to output stream codec context\n");goto end;}out1_vstream->codec->codec_tag = 0;if(ofmt1_ctx->oformat->flags & AVFMT_GLOBALHEADER){out1_vstream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;}}if (!out2_vstream){printf("Failed allocating output1 video stream\n");ret = AVERROR_UNKNOWN;goto end;}else{//copy the settings of AVCodecContext;if (avcodec_copy_context(out2_vstream->codec, ifmt_ctx->streams[i]->codec) < 0){printf( "Failed to copy context from input to output stream codec context\n");goto end;}out2_vstream->codec->codec_tag = 0;if(ofmt2_ctx->oformat->flags & AVFMT_GLOBALHEADER){out2_vstream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;}}}else if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){inAudio_StreamIndex = i;out1_astream = avformat_new_stream(ofmt1_ctx, NULL);out2_astream = avformat_new_stream(ofmt2_ctx, NULL);if (!out1_astream){printf("Failed allocating output1 video stream\n");ret = AVERROR_UNKNOWN;goto end;}else{//copy the settings of AVCodecContext;if (avcodec_copy_context(out1_astream->codec, ifmt_ctx->streams[i]->codec) < 0){printf( "Failed to copy context from input to output stream codec context\n");goto end;}out1_astream->codec->codec_tag = 0;if(ofmt1_ctx->oformat->flags & AVFMT_GLOBALHEADER){out1_astream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;}}if (!out2_astream){printf("Failed allocating output1 video stream\n");ret = AVERROR_UNKNOWN;goto end;}else{//copy the settings of AVCodecContext;if (avcodec_copy_context(out2_astream->codec, ifmt_ctx->streams[i]->codec) < 0){printf( "Failed to copy context from input to output stream codec context\n");goto end;}out2_astream->codec->codec_tag = 0;if(ofmt2_ctx->oformat->flags & AVFMT_GLOBALHEADER){out2_astream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;}}}}//Dump Format------------------printf("\n==============Input Video=============\n");av_dump_format(ifmt_ctx, 0, argv[1], 0);printf("\n==============Output1============\n");av_dump_format(ofmt1_ctx, 0, str_out1_filename, 1);printf("\n==============Output2============\n");av_dump_format(ofmt2_ctx, 0, str_out1_filename, 1);printf("\n======================================\n");//open output1 fileif (!(ofmt1_ctx->oformat->flags & AVFMT_NOFILE)){if (avio_open(&ofmt1_ctx->pb, str_out1_filename, AVIO_FLAG_WRITE) < 0){printf( "Could not open output file '%s'", str_out1_filename);goto end;}}//open output2 fileif (!(ofmt2_ctx->oformat->flags & AVFMT_NOFILE)){if (avio_open(&ofmt2_ctx->pb, str_out2_filename, AVIO_FLAG_WRITE) < 0){printf( "Could not open output file '%s'", str_out2_filename);goto end;}}//write out 1 file headerif (avformat_write_header(ofmt1_ctx, NULL) < 0){printf( "Error occurred when opening video output file\n");goto end;}//write out 2 file headerif (avformat_write_header(ofmt2_ctx, NULL) < 0){printf( "Error occurred when opening video output file\n");goto end;}int splitPtsV = 0;//the real split video ptsint splitDtsV = 0;int splitPtsA = 0;//the real split audio ptsint splitDtsA = 0;int videoIndex = 0;//the real video indexint splitTime = 30;//the split time (sec)AVPacket pkt;while(1){AVFormatContext *ofmt_ctx;AVStream *in_stream, *out_stream;if (av_read_frame(ifmt_ctx, &pkt) < 0){break;}in_stream = ifmt_ctx->streams[pkt.stream_index];if (pkt.stream_index == inVideo_StreamIndex){videoIndex++;int time = pkt.pts * (((float)in_stream->time_base.num) / ((float)in_stream->time_base.den));if (time <= splitTime){splitPtsV = pkt.pts;splitDtsV = pkt.dts;              out_stream = ofmt1_ctx->streams[pkt.stream_index];ofmt_ctx = ofmt1_ctx;}else{pkt.pts = pkt.pts - splitPtsV;pkt.dts = pkt.dts - splitDtsV;out_stream = ofmt2_ctx->streams[pkt.stream_index];ofmt_ctx = ofmt2_ctx;}}else if (pkt.stream_index == inAudio_StreamIndex){int time = pkt.pts * (((float)in_stream->time_base.num) / ((float)in_stream->time_base.den));if (time <= splitTime){splitPtsA = pkt.pts;splitDtsA = pkt.dts;out_stream = ofmt1_ctx->streams[pkt.stream_index];ofmt_ctx = ofmt1_ctx;}else{   pkt.pts = pkt.pts - splitPtsA;pkt.dts = pkt.dts - splitDtsA;out_stream = ofmt2_ctx->streams[pkt.stream_index];ofmt_ctx = ofmt2_ctx;}}pkt.pts = av_rescale_q_rnd(pkt.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, 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;//write into fileif (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0){printf( "Error muxing packet\n");break;}av_free_packet(&pkt);}av_write_trailer(ofmt1_ctx);av_write_trailer(ofmt2_ctx);end:avformat_close_input(&ifmt_ctx);/* close output */if (ofmt1_ctx && !(ofmt1_ctx->oformat->flags & AVFMT_NOFILE))avio_close(ofmt1_ctx->pb);avformat_free_context(ofmt1_ctx);/* close output */if (ofmt2_ctx && !(ofmt2_ctx->oformat->flags & AVFMT_NOFILE))avio_close(ofmt2_ctx->pb);avformat_free_context(ofmt2_ctx);return 0;
}

3、下载地址

http://download.csdn.net/detail/dancing_night/8699109

ffmpeg实现视频切割相关推荐

  1. 【ffmpeg裁剪视频faster rcnn自动检测 via】全自动实现ffmpeg将视频切割为图片帧,再使用faster rcnn将图片中的人检测出来,最后将检测结果转化为via可识别的csv格式

    目录 前言 一,ffmpeg 自动裁剪 1.1 目录结构 1.2 cutVideoToImage.sh 1.2 myVideo 1.3 myVideo15mins 1.5 myFrames 1.6 运 ...

  2. java使用ffmpeg视频切割聚合截图

    环境信息: 操作系统:centos7 编程语言:java 安装ffmpeg # 安装epel扩展源 sudo yum install -y epel-release # 安装Nux Dextop Yu ...

  3. 使用ffmpeg从视频文件中提取音频文件、视频抽帧和切割视频

    目录 ffmpeg下载 使用ffmpeg从视频文件中提取音频文件 批量提取文件夹下多个视频文件的音频 使用ffmpeg从视频文件中提取视频帧 使用ffmpeg将按固定时长将视频切割成多个小片段 将分割 ...

  4. 【FFmpeg 之MP4】mp4视频切割

    视频切割 一.实现功能 二.源程序 一.实现功能 从mp4文件截取局部视频. splite_video(std::string in_filename, std::string out_filenam ...

  5. python使用ffmpeg去掉视频片头和片尾

    python使用ffmpeg去掉视频片头和片尾 需要自己得到视频的片头和片尾时长:并且设置好视频文件的名称. 关于ffmpeg的配置及操作可看ffmpeg配置环境和测试,ffmpeg的基本使用,pyt ...

  6. ffmpeg分割视频,制作gif图,加水印、去水印,视频拼接

    一.分割视频 进入ffmpeg的目录: (1)执行从0分钟开始,剪切5分钟: ./ffmpeg -ss 00:00:00 -i /111/Movies/a2009.mp4 -t 00:05:00 a2 ...

  7. ffmpeg解码视频存为BMP文件

    ffmpeg解码视频存为BMP文件 分类: ffmpeg2011-07-28 12:13 8人阅读 评论(0) 收藏 举报 view plain #include <windows.h> ...

  8. ffmpeg java linux水印,Linux环境用FFmpeg给视频加水印详细步骤

    FFmpeg给视频添加水印,根据官方文档的介绍可以知道FFmpeg在编译安装的时候还需要加 –enable-libfreetype.–enable-libfontconfig. --enable-li ...

  9. ffmpeg 压缩视频

    ffmpeg 压缩视频 代码 ffmpeg -i input.mp4 -r 30 -b:a 64k output.mp4 30: 帧数 64k: 表示音频的码率为64kb/s

  10. ffmpeg入门及java操作ffmpeg对视频进行处理

    一.ffmpeg 1.简介 FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非 ...

最新文章

  1. 大龄屌丝自学笔记--Java零基础到菜鸟--028
  2. UML学习总结(1)——UML学习入门
  3. Games101现代图形学入门Lecture 3: Transformation知识点总结
  4. Atlassian发布事故管理解决方案Jira Ops
  5. 统计学习方法-李航(1)
  6. android Intent的介绍
  7. js调用摄像头麦克风,截取摄像头图像 js调用摄像头录像保存本地
  8. 在知行EDI系统中实施SNIP验证
  9. win10下面安装MTK USB VCOM 驱动
  10. 考研计算机专业流程,计算机专业考研复试基本流程-文都教育.doc
  11. 移动mm 话费支付接入过程(ane)
  12. python怎么画圆螺旋线_使用Turtle画正螺旋线的方法
  13. python 语法错误 和异常_Python基础知识:新手学Python时常见的语法错误和异常
  14. 门店私域运营,突围线上冲击
  15. 03-行为型设计模式
  16. C语言学习笔记---查漏补缺
  17. python识别火车票二维码_Python3 实现查询火车票工具
  18. 字体下载大宝库:30款好看的免费英文字体
  19. 一座教学楼内的计算机网络系统属于,2006—2007学年第一学期期末考试(计算机网络技术试卷》A...
  20. 电子计算机维修工三级高级技能,国家职业技能鉴定考核指导:计算机(微机)维修工(高级)...

热门文章

  1. 云效研发效能度量体系,如何展示和解读交付效能数据
  2. matlab绘制图形中,常用函数调用(num2str,disp,gcf,hold on,plot,axis,subplot,line,stairs,grid,set,gca)
  3. 计算机英文电子书分享
  4. 打开ps显示计算机内存不足怎么办,ps显示内存不足怎么办,教你ps显示内存不足怎么办...
  5. HBase之一月速成:整合phoenix
  6. 6.0 Python 模块编写 导入 引用
  7. 如何将mp4视频格式转换成mov视频
  8. 1+X web证书(高级)的重要知识点的复习
  9. GitHub每月优秀热门项目推荐:2021年12月
  10. excel如何去重统计户数_Excel如何去重,然后统计数据?_excel提取数据并去重