最新版ffmpeg 提取视频关键帧

2023-05-16

(如果有转载的请注明哈)

对于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);
}


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最新版ffmpeg 提取视频关键帧 的相关文章

  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • FFmpeg - 来自 NodeJS 的 RTMP 流,流比实时更快

    我的目标是在 Node 中渲染画布 并将该画布流式传输到 RTMP 服务器 最终是 Twitch 但现在我正在在本地 RTMP 服务器上测试 流式传输到 RTMP 的标准方式似乎是ffmpeg 所以我使用它 从 NodeJS 中作为子进程生
  • Bash 脚本:自动为 mpeg-dash 进行 ffmpeg 编码

    我正在编写一个 bash 文件来创建视频编码和串联 以供 dash 实时流媒体使用 基本上 它读取输入视频文件夹 将所有视频编码为三种分辨率格式 然后将它们连接起来创建三个适应集 DIAGRAM 该脚本检查 fps 一致性 如果输入不是 1
  • 两个图像之间的视频变形,FFMPEG/Minterpolate

    我正在尝试在 Ubuntu Linux 上的 bash 脚本中使用两个帧 png 图像 和 ffmpeg 的 minterpolate 过滤器制作一个快速且简单的变形视频 目的是稍后使用变形作为不同视频编辑器中相似视频之间的过渡 它适用于
  • Ffmpeg 无法正确转换为 ogg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在使用 ffmpeg 在我的网站上转换音频和视频 Ffmpeg 可以正确转换为其他格式 如 mp3 mp4 等 但无法正确转换为 ogg 虽然 f
  • 使用 Coldfusion 的 CFFILE 标签监控 FFMpeg 的进度日志

    我想学习如何使用 ColdFusion 中的 CFFILE 标签来读取文本文件的内容 就我而言 该文本文件是 FFMpeg 在对媒体文件进行转码时生成的进度日志 我想编写一个 ColdFusion 脚本 该脚本将定期轮询进度日志 直到日志表
  • 转换为 JPEG 时 HEIC 切片损坏

    我在将 HEIC 图像转换为 jpeg 时遇到问题 HEIC 文件是使用运行最新 iOS 公共测试版的 iPhone 拍摄的图像 我正在使用诺基亚提供的库 https github com nokiatech heif 要解析文件并从 HE
  • Node.js - 将数据缓冲到 Ffmpeg

    我使用 Node js 和 Ffmpeg 来创建动画 因为我试图避免第三方 avi mp4 解析器 所以我决定将动画输出为原始 rgb24 数据文件 然后使用一些程序将其转换为 mp4 文件 我发现 Ffmpeg 是免费且开源的 它完全可以
  • 将 ffmpeg 编译为独立二进制文件

    我正在尝试编译ffmpeg作为独立的二进制文件 因为我想在 AWS lambda 中使用它 我可以让事情在我正在编译的服务器上正常工作 但是如果我复制二进制文件并从另一台服务器运行它 我会得到 ffmpeg error while load
  • Xuggler 未转换 .webm 文件?

    我只是尝试使用 Xuggler 将 mov 文件转换为 webm 这应该可以工作 因为 FFMPEG 支持 webm 文件 这是我的代码 IMediaReader reader ToolFactory makeReader home use
  • 如何启用 FFMPEG 日志记录?

    我想调试 ffmpeg 我添加以下代码来打印日志 av log s AV LOG PANIC fmt or printf msg 但这行不通 没有任何调试信息 然后我启用调试构建选项 export COMMON FF CFG FLAGS C
  • ffmpeg计算视频比特率

    我想知道如何计算该视频的比特率 http jell yfish us media jellyfish 30 mbps hd hevc mkv http jell yfish us media jellyfish 30 mbps hd hev
  • FFMPEG 帧到 DirectX 表面

    给定一个指向 FFMPEG 的 AVFrame 的指针avcodec decode video 函数如何将图像复制到 DirectX 表面 假设我有一个指向适当大小的 DX X8R8G8B8 表面的指针 Thanks John 您可以使用
  • 以 Gif 形式在 Android 上以编程方式共享 WhatsApp 视频

    我如何将 mp4 视频文件转换为 WhatsApp gif 文件 在应用程序 UI 中简单显示为 gif 但内部是特定的 mp4 格式 以在 android 共享意图中使用 并被 Whatsapp 聊天应用程序识别为此类媒体 我搜索了很多
  • 有没有更有效的方法通过ffmpeg批量添加水印和加入视频?

    我有这个批处理文件 使用 ffmpeg 在我的视频中添加徽标 然后添加简介 但需要 10 小时到一天的时间 具体取决于我需要添加水印的数量 是否有更有效的方法来实现此目的 视频有时具有不同的分辨率 因此我无法删除到 1280 720 尺寸的
  • 如何在不指定像素格式的情况下从 AVFrame.data[] 和 AVFrame.linesize[] 获取原始帧数据?

    我的总体想法是frame data 根据视频的像素格式 RGB 或 YUV 进行解释 但是有没有通用的方法可以从帧中获取所有像素数据 我只想计算帧数据的哈希值 而不解释它来显示图像 根据 AVFrame h uint8 t AVFrame
  • 如何使用 FFmpeg 连接 MTS 视频并应用过滤器而不重新编码?

    我有一个包含许多 MTS 视频文件的 txt 文件 我想使用将它们全部合并在一起FFmpeg并获取一个大的 MTS 文件 但我想申请fade in and fade out到最后的视频 我可以在不重新编码的情况下做到这一点吗 因为重新编码需
  • 用于 Windows Phone 开发的 FFmpeg

    我在 ASP Net 基于 Web 的应用程序中使用了 FFmpeg 现在我想用它来进行Windows Phone开发 可以使用吗 如果是 那么如何 Windows Phone 7 根本不支持 FFmpeg 而且据我在网上找到的信息 Win
  • 使用 ImageMagick 有效地将线扫描图像拼接在一起

    我正在寻找线扫描相机的替代品 用于体育计时 或者更确切地说 用于需要确定位置的部分 我发现普通工业相机可以轻松与商业相机解决方案的速度相匹配 每秒 gt 1000 帧 对于我的需求来说 通常计时的准确性并不重要 重要的是运动员的相对位置 我
  • 使用 libavcodec 提取音频样本

    我对如何从 AVFrame 中的数据提取双值感到困惑 我正在尝试提取帧 我尝试检查用 CPython 编写的 av 模块背后的源代码 尤其是 AudioFrame 来尝试了解它从何处解码样本 https github com PyAV Or

随机推荐