最新版ffmpeg 提取视频关键帧
(如果有转载的请注明哈)
对于ffmpeg的配置请看我的上篇博客:http://blog.csdn.net/kuaile123/article/details/11367309
所用视频为 flv格式的,用的vs2010,电脑为64位,下面的也是64位,别下错了。
因为ffmpeg的函数和版本有关系,这里记录下我所用的整合的版本,是昨天下的最新版的,需要请下载
http://download.csdn.net/detail/kuaile123/6232827(因为博主没有积分可用了,所以需要积分)
32位的请去官网下载。
从网上找到的都是旧版本的函数,函数的讲解可用直接自己看里面include中的.h文件,自己根据新版的文件自己弄出来的。
需要用到libavformat 用来处理解析视频文件并将包含在其中的流分离出来, 而libavcodec 则处理原始音频和视频流的解码
还是上代码:
完整的代码下载:http://download.csdn.net/detail/kuaile123/6232905
//注册库中含有的所有可用的文件格式和编码器,这样当打开一个文件时,它们才能够自动选择相应的文件格式和编码器。
av_register_all();
int ret;
// 打开视频文件
if((ret=avformat_open_input(&pInputFormatContext, sourceFile, NULL, NULL))!=0){
cout<<" can't open file "<<endl;
return -1;
}
// 取出文件流信息
if(avformat_find_stream_info(pInputFormatContext,NULL)<0){
cout<<" can't find suitable codec parameters"<<endl;
return -1;
}
//用于诊断 //产品中不可用
//dump_format(pInputFormatContext, 0, sourceFile, false);
//仅仅处理视频流
//只简单处理我们发现的第一个视频流
// 寻找第一个视频流
int videoIndex = -1;
for(int i=0; i<pInputFormatContext->nb_streams; i++) {
if(pInputFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
videoIndex = i;
break;
}
}
if(-1 == videoIndex){
cout<<" can't find video stream !"<<endl;
return -1;
}
// 得到视频流编码上下文的指针
pInputCodecContext = pInputFormatContext->streams[videoIndex]->codec;
// 寻找视频流的解码器
pInputCodec = avcodec_find_decoder(pInputCodecContext->codec_id);
if(NULL == pInputCodec){
cout<<"can't decode "<<endl;
return -1;
}
// 通知解码器我们能够处理截断的bit流,bit流帧边界可以在包中
//视频流中的数据是被分割放入包中的。因为每个视频帧的数据的大小是可变的,
//那么两帧之间的边界就不一定刚好是包的边界。这里,我们告知解码器我们可以处理bit流。
if(pInputCodec->capabilities & CODEC_CAP_TRUNCATED){
pInputCodecContext->flags|=CODEC_FLAG_TRUNCATED;
}
//打开解码器
if(avcodec_open2(pInputCodecContext, pInputCodec,NULL) != 0) {
cout<<"decode error"<<endl;
return -1;
}
int videoHeight;
int videoWidth;
videoWidth = pInputCodecContext->width;
videoHeight = pInputCodecContext->height;
AVPacket InPack;
int len = 0;
AVFrame OutFrame;
int nComplete=0;
int nFrame = 0;
AVRational avRation = pInputCodecContext->time_base;
float frameRate = (float)avRation.den/avRation.num;
//av_seek_frame(pInputFormatContext,0);
while((av_read_frame(pInputFormatContext, &InPack) >= 0)){
len = avcodec_decode_video2(pInputCodecContext, &OutFrame, &nComplete, &InPack);
//判断是否是关键帧
if(nComplete > 0 && OutFrame.key_frame){
//解码一帧成功
SaveBmp(pInputCodecContext, &OutFrame, videoWidth, videoHeight,nFrame);
nFrame++;
}
}
cout<<" save frame number: "<<nFrame<<endl;
avcodec_close(pInputCodecContext);
av_free(pInputFormatContext);
保存为bmp格式,保存函数如下:
void SaveBmp(AVCodecContext *CodecContex, AVFrame *Picture, int width, int height,int num)
{
AVPicture pPictureRGB;//RGB图片
static struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(width, height, CodecContex->pix_fmt, width, height,\
PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
// 确认所需缓冲区大小并且分配缓冲区空间
avpicture_alloc(&pPictureRGB, PIX_FMT_RGB24, width, height);
sws_scale(img_convert_ctx, Picture->data, Picture->linesize,\
0, height, pPictureRGB.data, pPictureRGB.linesize);
int lineBytes = pPictureRGB.linesize[0], i=0;
char fileName[1024]={0};
char * bmpSavePath = "%d.bmp";
//time_t ltime;
//time(<ime);
//sprintf(fileName,bmpSavePath , ltime);???????????????????????????
sprintf(fileName,bmpSavePath , num);
FILE *pDestFile = fopen(fileName, "wb");
BITMAPFILEHEADER btfileHeader;
btfileHeader.bfType = MAKEWORD(66, 77);
btfileHeader.bfSize = lineBytes*height;
btfileHeader.bfReserved1 = 0;
btfileHeader.bfReserved2 = 0;
btfileHeader.bfOffBits = 54;
BITMAPINFOHEADER bitmapinfoheader;
bitmapinfoheader.biSize = 40;
bitmapinfoheader.biWidth = width;
bitmapinfoheader.biHeight = height;
bitmapinfoheader.biPlanes = 1;
bitmapinfoheader.biBitCount = 24;
bitmapinfoheader.biCompression = BI_RGB;
bitmapinfoheader.biSizeImage = lineBytes*height;
bitmapinfoheader.biXPelsPerMeter = 0;
bitmapinfoheader.biYPelsPerMeter = 0;
bitmapinfoheader.biClrUsed = 0;
bitmapinfoheader.biClrImportant = 0;
fwrite(&btfileHeader, 14, 1, pDestFile);
fwrite(&bitmapinfoheader, 40, 1, pDestFile);
for(i=height-1; i>=0; i--)
{
fwrite(pPictureRGB.data[0]+i*lineBytes, lineBytes, 1, pDestFile);
}
fclose(pDestFile);
avpicture_free(&pPictureRGB);
}
最新版ffmpeg 提取视频关键帧相关推荐
- 使用ffmpeg 提取视频关键帧
关键帧是视频中最清晰的帧,在视频中有关键帧和过渡帧的区别.以下程序可以按你设置的数量在一定的时间间隔中把关键帧提取出来. 可以设置每分钟的关键帧提取数量.如果需要更多信息,可以适当加大数量再进行后处理 ...
- 提取视频关键帧和关键帧的时间点信息
这篇文章的原文地址是:http://www.videoproductionslondon.com/blog/scene-change-detection-during-encoding-key-fra ...
- Python:使用PyAV提取视频关键帧
Python:使用PyAV提取视频关键帧 1.软件环境⚙️ 2.问题描述
- FFmpeg提取视频(mp4)中的音频(m4a)
目的 方法 1. 下载 FFmpeg 下载地址 下载后解压缩,我解压缩到的位置是:D:\Program Files 并将文件夹名称改为ffmpeg 自己可以根据情况,随便解压缩到什么位置都可以 2. ...
- ffmpeg 提取 视频,音频,字幕 方法
ffmpeg 提取 视频,音频,字幕 方法 (How to Extract Video, Audio, Subtitle from Original Video?) 1. 提取视频 (Extra ...
- 使用ffmeg提取视频关键帧
一. 什么是关键帧 参考维基百科Key frame的解释: 关键帧,是指动画中一个绘图,定义任何的起点和终点平滑过渡.一系列关键帧定义了观看者将看到的运动,而关键帧在电影,视频或动画上的位置定义了运动 ...
- ffmpeg提取视频所有帧
可以使用 ffmpeg 命令行工具提取视频中的所有帧.命令格式如下: ffmpeg -i input.mp4 -vf fps=1/60 frames/frame%d.jpg 其中,-i 后面是输入视频 ...
- FFmpeg提取视频中的音频
提取完整音频 ffmpeg -i input.mp4 -q:a 0 -map a output.mp3 提取指定时间段的音频 ffmpeg -i input.mp4 -ss 00:03:05 -t 0 ...
- FFmpeg提取视频音乐
先下载安装包 把bin目录下exe文件放在新建的ffmpeg文件夹下,音频视频都放在此目录下. 命令行切到f盘符的ffmpeg文件夹下: 提取视频音频:ffmpeg.exe -i xx.mp4 -vn ...
最新文章
- 图像滤波常用算法实现及原理解析
- 如何提升计算机内存,怎么提高电脑物理内存
- Norse Attack Map网络攻击实时监测地图
- linux下安装mysql数据库
- Linux执行shell脚本提示文件找不到问题解决办法
- adb 安卓模拟器 进程端口_Frida初体验安卓CTF逆向
- SEO实战密码阅读笔记
- JavaScript快速入门-基础
- php poedit怎么debug,php – 使用Poedit与XAMPP
- 西门子博图怎么导入库文件_【傻瓜教程】博途中库的建立与使用方法(工控公开课 今晚8点 老地方 不见不散!)...
- 个人 OKR 案例,帮助你变得更好
- 高数_第5章常微分方程__一阶微分方程之齐次方程
- 2022.10.13(四)[仿写《百草园到三味书屋》第二段]
- CMP SUB 区别
- 超级实用的软著申请源代码材料格式文档生成辅助工具——软著源代码工具
- 电脑回收站清空了能恢复吗?
- 含protobuf程序运行时与libqgtk3.0.so冲突
- hadoop2.7.2下载
- Java实现蓝桥杯VIP算法训练 二元函数
- aix kill java_AIX环境Java进程cpu瓶颈分析(转)
热门文章
- Android安卓开发-eclipse正确添加第三方jar包
- 数据挖掘导论读书笔记3--分类
- linux 文件与进程
- 源代码解读Cas实现单点登出(single sign out)功能实现原理--转
- 机器学习中用来防止过拟合的方法有哪些?
- 机器之心 Synced 08月12日 20:59
- 开源是互联网发展的核动力
- 关于yum安装后提示There are no enabled repos Run yum repolist all..的问题解决
- java 单例模式 泛型_设计模式之架构设计实例(工厂模式、单例模式、反射、泛型等)...
- Android Studio使用外部jar包