最新版ffmpeg 提取视频关键帧
来源:互联网 发布:windows ping端口命令 编辑:程序博客网 时间:2024/04/29 18:24
对于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);}
</pre><pre class="html" name="code" style="border: 1px solid rgb(255, 255, 204); font-family: 'Courier New'; overflow: auto; font-size: 16px; line-height: 24px; background-color: rgb(255, 255, 252);">http://m.blog.csdn.net/blog/dragonkuaile123/11378925
0 0
- 最新版ffmpeg 提取视频关键帧
- 最新版ffmpeg 提取视频关键帧
- 最新版ffmpeg 提取视频关键帧
- ffmpeg 提取关键帧
- 关于ffmpeg如何提取视频的关键帧的问题
- 关于ffmpeg如何提取视频的关键帧的问题
- ffmpeg视频关键帧提取保存为图片
- 视频关键帧提取
- ffmpeg 提取视频文件关键帧
- ffmpeg 提取视频文件关键帧
- FFMpeg提取视频帧
- ffmpeg 获取视频关键帧
- ffmpeg 获取视频关键帧
- ffmpeg 获取视频关键帧
- ffmpeg 获取视频关键帧
- ffmpeg 获取视频关键帧
- ffmpeg 获取视频关键帧
- ffmpeg 获取视频关键帧
- NodeJS 中模块module查找过程
- Android 如何快速浏览本地 API文档
- android系统设置里的字体大小导致的布局混乱问题
- OC学习日记Day1:程序怎么执行、类和对象
- LeetCode *** 54. Spiral Matrix
- 最新版ffmpeg 提取视频关键帧
- Lua数据类型转换
- 拍照怎么搜题?(下)
- 两个栈实现一个队列
- 学习总结:局部搜索
- Dubbo高级篇_06_Dubbo分布式服务子系统的划分
- 配置禅道可以通过计算机名称访问
- Notification、KVO实现代码
- ffmpeg 获取视频关键帧