首先致敬雷神提供的资源,使用雷神的代码实现视频剪切功能

雷神实现的ffmpeg代码文章

说明一下,这里转载首先是记录一下实现方法,其次就是解决代码无法正常运行问题(avformat_write_header返回-22)

本文介绍一个基于FFMPEG的封装格式转换器。所谓的封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间转换(对应.avi,.flv,.mkv,.mp4文件)。需要注意的是,本程序并不进行视音频的编码和解码工作。而是直接将视音频压缩码流从一种封装格式文件中获取出来然后打包成另外一种封装格式的文件。传统的转码程序工作原理如下图所示:

上图例举了一个举例:FLV(视频:H.264,音频:AAC)转码为AVI(视频:MPEG2,音频MP3)的例子。可见视频转码的过程通俗地讲相当于把视频和音频重新“录”了一遍。

本程序的工作原理如下图所示:

由图可见,本程序并不进行视频和音频的编解码工作,因此本程序和普通的转码软件相比,有以下两个特点:
处理速度极快。视音频编解码算法十分复杂,占据了转码的绝大部分时间。因为不需要进行视音频的编码和解码,所以节约了大量的时间。
视音频质量无损。因为不需要进行视音频的编码和解码,所以不会有视音频的压缩损伤。


#include <stdio.h>
extern "C"
{#include <FFmpeg\libavcodec\avcodec.h>
#include <FFmpeg\libavformat\avformat.h>
}
#pragma comment (lib, "avcodec.lib")
#pragma comment (lib, "avformat.lib")
#pragma comment (lib, "avutil.lib")int main(int argc, char* argv[])
{int startTime = 1;//起始时间  如果为0就不启用该变量int endTime = 4;//结束时间   如果为0就不启用该变量AVCodecContext* pCodecCtx = NULL;AVCodecContext *pAVCodecContext = NULL;AVOutputFormat *ofmt = NULL;AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;AVPacket pkt;const char *in_filename, *out_filename;int ret, i;in_filename = "e://Test.mp4";out_filename = "e://Temp.mp4";av_register_all();//输入(Input)if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {printf("Could not open input file.");goto end;}if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {printf("Failed to retrieve input stream information");goto end;}av_dump_format(ifmt_ctx, 0, in_filename, 0);//输出(Output)avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);if (!ofmt_ctx) {printf("Could not create output context\n");ret = AVERROR_UNKNOWN;goto end;}ofmt = ofmt_ctx->oformat;for (i = 0; i < ifmt_ctx->nb_streams; i++) {//根据输入流创建输出流(Create output AVStream according to input AVStream)AVStream *in_stream = ifmt_ctx->streams[i];AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);if (!out_stream) {printf("Failed allocating output stream\n");ret = AVERROR_UNKNOWN;goto end;}ret = avcodec_copy_context(out_stream->codec, in_stream->codec);if (ret < 0) {printf("Failed to copy context from input to output stream codec context\n");goto end;}out_stream->codec->codec_tag = 0;if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;//Param that must setpCodecCtx = out_stream->codec;/*//特殊处理 如果使用雷神的代码这里不增加特殊的处理,会在avformat_write_header函数执行的时候返回-22i=0: codec_id = AV_CODEC_ID_HEV //H265i=1:codec_id = AV_CODEC_ID_AACi=2:codec_id = AV_CODEC_ID_NONEi=3:codec_id = AV_CODEC_ID_NONEi=4:codec_id = AV_CODEC_ID_NONE*/pAVCodecContext = ifmt_ctx->streams[i]->codec;if (i < 2)pCodecCtx->codec_id = ifmt_ctx->streams[i]->codec->codec_id;elsepCodecCtx->codec_id = ifmt_ctx->streams[i%2]->codec->codec_id;#if 0//其他参数配置pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;pCodecCtx->width = 1920;pCodecCtx->height = 1080;pCodecCtx->bit_rate = pAVCodecContext->bit_rate;pCodecCtx->gop_size = 250;pCodecCtx->time_base.num = 1;pCodecCtx->time_base.den = 25;pCodecCtx->qmin = 10;pCodecCtx->qmax = 51;//Optional ParampCodecCtx->max_b_frames = 3;
#endif}pAVCodecContext = ifmt_ctx->streams[0]->codec;// 显示视频相关的参数信息(编码上下文)printf("比特率: = %lld\n", pAVCodecContext->bit_rate);printf("宽高: = %d\n" , pAVCodecContext->width );printf("格式: = %d\n" , pAVCodecContext->pix_fmt);  // AV_PIX_FMT_YUV420P 0printf("帧率: = %d\n",pAVCodecContext->time_base.den );printf("总时长: = %f s\n", (ifmt_ctx->duration) / AV_TIME_BASE );printf("总帧数: = %d\n", ifmt_ctx->streams[0]->nb_frames );int fps = ifmt_ctx->streams[0]->avg_frame_rate.num * 1.0f / ifmt_ctx->streams[0]->avg_frame_rate.den;int interval = 1 * 1000 / fps;printf("平均帧率: = %d\n", fps );printf("帧间隔: = %d ms\n", interval);//输出一下格式------------------av_dump_format(ofmt_ctx, 0, out_filename, 1);//打开输出文件(Open output file)if (!(ofmt->flags & AVFMT_NOFILE)) {ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);if (ret < 0) {printf("Could not open output file '%s'", out_filename);goto end;}}//写文件头(Write file header)ret = avformat_write_header(ofmt_ctx, NULL);if (ret < 0) {printf("Error occurred when opening output file\n");goto end;}//跳转到多少秒if(startTime <= 0){ret = av_seek_frame(ifmt_ctx, -1, startTime * AV_TIME_BASE, AVSEEK_FLAG_ANY);if (ret<0) {fprintf(stderr, "Error seek\n");}}int frame_index = 0;while (1) {AVStream *in_stream, *out_stream;//获取一个AVPacket(Get an AVPacket)ret = av_read_frame(ifmt_ctx, &pkt);if (ret < 0)break;in_stream = ifmt_ctx->streams[pkt.stream_index];out_stream = ofmt_ctx->streams[pkt.stream_index];//裁剪区域if (endTime > startTime){if (av_q2d(in_stream->time_base) * pkt.pts > (startTime + endTime)){av_packet_unref(&pkt);break;}}/* copy packet *///转换PTS/DTS(Convert PTS/DTS)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)ret = av_interleaved_write_frame(ofmt_ctx, &pkt);if (ret < 0) {printf("Error muxing packet\n");break;}printf("Write %8d frames to output file\n", frame_index);av_free_packet(&pkt);frame_index++;}//写文件尾(Write file trailer)av_write_trailer(ofmt_ctx);
end:avformat_close_input(&ifmt_ctx);/* close output */if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))avio_close(ofmt_ctx->pb);avformat_free_context(ofmt_ctx);if (ret < 0 && ret != AVERROR_EOF) {printf("Error occurred.\n");return -1;}return 0;
}

转:文章资源:https://blog.csdn.net/leixiaohua1020/article/details/84597944

完整工程下载地址(代码是一样的,就是包含了ffmpeg运行所需要的环境,能直接编译通过):
https://download.csdn.net/download/qq_36351159/85748703
工程项目VS2015 x64 Debug下载 (包括ffmpeg库,配置好的所需包含目录、库,可直接编译)

使用FFMpeg实现视频剪切功能相关推荐

  1. android端采用FFmpeg进行视频剪切、转码与添加水印

    前两篇文章介绍过FFmpeg进行音频处理.音视频处理:android端采用FFmpeg进行音频混合与拼接剪切, android端采用FFmpeg进行音视频合成与分离.关于FFmpeg涉及文件导入以及c ...

  2. 前端ffmpeg实现视频剪切

    利用ffmpeg实现纯前端视频剪切 注意:在新版本Chrome浏览器中由于安全性问题,只能在https或localhost当中才能正常使用 1. 下载ffmpeg npm install @ffmpe ...

  3. Java使用ffmpeg实现视频剪切、mp3剪切

    直接运行代码即可: import java.io.IOException;public class FfmpegDemo {// 剪切命令static String command = "$ ...

  4. iOS - 仿微信朋友圈视频剪切功能

    分析需求 我们先看一看微信的界面 微信效果图 1.页面下部拖动左边和右边的白色竖条控制剪切视频的开始和结束时间,预览界面跟随拖动位置跳到视频相应帧画面,控制视频长度最长15秒,最短5秒 2.拖动下部图 ...

  5. 超强视频剪切工具Boilsoft Video Splitter7.02.2中文免费绿色版

    它除了普通的视频剪切功能外,特别的是支持RMVB格式,剪切工具亲测可用,可以完美剪切RMVB/RM格式视频,如果你想从一段完整的视频中剪切指定的视频段落,需要选择[分割选择],设置好[开始时间]和[结 ...

  6. 超强视频剪切工具Boilsoft Video Splitter7.02.2中文免费绿色版_我是亲民_新浪博客...

    它除了普通的视频剪切功能外,特别的是支持RMVB格式,剪切工具亲测可用,可以完美剪切RMVB/RM格式视频,如果你想从一段完整的视频中剪切指定的视频段落,需要选择[分割选择],设置好[开始时间]和[结 ...

  7. FFmpeg优化 苏宁PP体育视频剪切效率提升技巧

    FFmpeg功能强大,社区活跃,在多媒体处理业务中扮演着不可或缺的角色.但没有优化过的FFmpeg在生产环境下有很多性能瓶颈,因此对其进行优化势在必行.苏宁旗下PP体育音视频技术负责人田钊撰文分享了团 ...

  8. ffmpeg视频剪切与拼接

    文章目录 ffmpeg工具进行视频剪切与合并 剪切视频 拼接视频 ts格式拼接 将ts格式文件转为mp4格式 mp4格式拼接 ffmpeg工具常用命令 ffmpeg的安装及基本使用可以看上一篇博客 F ...

  9. java ffmpeg 合并视频_android ffmpeg视频剪切与合并

    android-ffmpeg-java-demo 说明 以前一直希望可以做一个播放器,所以当时就接触了ffmpeg这个库,当时打算使用JNI的方式进行底层的调用,无奈整个逻辑比较麻烦,因此进度一再搁浅 ...

最新文章

  1. Tungsten Fabric SDN — Service Chain — 高级特性
  2. spring boot actuator工作原理之http服务暴露源码分析
  3. 编程之美-寻找最大的k个数
  4. java 鲜为人知的知识点_鲜为人知的Java 8功能:广义目标类型推断
  5. 铭飞MCMS内容管理系统完整开源版J2EE代码
  6. Executors 线程池的7个参数详解
  7. vim编辑器操作汇总
  8. 3D旋转(CSS3)
  9. 算法:判断对称树 101. Symmetric Tree
  10. matlab7.0工具箱,matlab6.5+gaot工具箱和matlab7.0自带工具箱的效果一样吗?
  11. css三大样式(行内样式)
  12. html 闪白光效果,css3实现图片划过一束光闪过成效
  13. Vue 源码学习过程 - Observer/Dep/Watcher三者实现数据双向绑定
  14. 【转载】测试报告模板
  15. bzoj2456瞎搞
  16. Verilog基础知识-——计数器设计以及任意分频设计与modelsim仿真
  17. 用canvas写 看你有多色 游戏
  18. 阳光与紫外线或是白内障致病主因
  19. DML和DDL的区别
  20. 内存卡数据删除了怎么恢复?sd卡数据恢复,3个步骤找回

热门文章

  1. 香港知名主持人梁继璋----给孩子的一封信
  2. 计算机学报和软件学报19~20年测试类相关论文
  3. Mac安装jdk和maven3.6配置环境
  4. 【matlab教程】09、函数已知y值求x,或已知x值求y
  5. 计算机开启远程服务与修改端口号教程
  6. python中round函数_round函数
  7. win10 ghost 安装
  8. 新学期,新FLAG | 从心出发
  9. 一起探索西工大图书馆数字资源
  10. R语言处理数据——删除文件某列中包含某元素的行