ffmpeg 从视频流中抓取图片
从视频中不断抓取图片的基本流程:打开视频流地址->获取视频流packt->解码成图片帧->输出图片
一.初始化Ffmpeg
void ffmpegInit()
{
av_register_all();
avformat_network_init();
av_log_set_level(AV_LOG_ERROR);
}
如果你不想输出log,设置log级别为AV_LOG_PANIC。
二.打开视频。
int Open(char* url)
{
context = avformat_alloc_context();
context->interrupt_callback.opaque = this; //C++
context->interrupt_callback.callback = interruptCallback;//设置回调函数,否则有可能ffmpeg一直被挂住。
context->start_time_realtime = av_gettime();
AVDictionary* options = nullptr;
av_dict_set(&options, "rtsp_transport", "udp", ); //以udp方式打开,如果以tcp方式打开将udp替换为tcp
av_dict_set(&options, "stimeout", "", ); //设置超时断开连接时间
int ret = avformat_open_input(&context, url, nullptr, &options); //avformat_open_input 返回0表示open成功,小于0表示open失败
if(ret < 0) return ret;
ret = avformat_find_stream_info(context, options); ///avformat_find_stream_info 返回0表示查抄stream info成功 小于0表示失败。
if(options!= nullptr)
{
av_dict_free(options);
}
return ret;
}
int interrupt_cb(void *ctx)
{
if((av_gettime() - ffmpeg->lastFrameRealtime) > * * ) //10s超时退出
{
return AVERROR_EOF;
}
return 0;
}
三 .读取视频包:
shared_ptr<AVPacket> ReadPacket()
{
shared_ptr<AVPacket> packet((AVPacket*)av_malloc(sizeof(AVPacket)), [&](AVPacket *p){av_free_packet(p);av_freep(&p);});
av_init_packet(packet.get());
lastFrameRealtime = av_gettime();
int ret = av_read_frame(context, packet.get());
if(ret >= )
{
return packet;
}
else
{
return nullptr;
}
}
说明一下:不一定要用智能指针。我确定这样写不会有内存泄露,所以就不改了,随手写的代码会有bug。
四. 解码
1. 初始化解码器
InitDecoderCodec
{
int ret = -1;
for(int i = 0; i < context->nb_streams; ++i)
{
AVCodecContext *codecContext = context->streams[i]->codec;
if(codecContext->codec_type == AVMEDIA_TYPE_VIDEO)
{
//返回小于0,打开解码器失败
ret = avcodec_open2(codecContext, avcodec_find_decoder(codecContext->codec_id), &options);
}
}
return ret;
}
2. 解码视频包
AVFrame* DecodeVideoPacket(AVCodecContext* codecContext)
{
AVFrame* videoFrame = av_frame_alloc();
auto hr = avcodec_decode_video2(codecContext, frame, &gotFrame, packet);
if(hr >= && gotFrame != )
{
return videoFrame;
}
else
{
avcodec_free_frame(&videoFrame);
return nullptr
}
}
输出图片:
uint8_t *GetPictureData(int width,int height, int *bufferSize)
{
pFrameYUV= av_frame_alloc();
uint8_t *out_buffer;
out_buffer = new uint8_t[avpicture_get_size(PIX_FMT_RGB32, width, height)];
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_RGB32, width, height);
sws_scale(sws, (const uint8_t* const*)frame->data, frame->linesize, , height, pFrameYUV->data, pFrameYUV->linesize);
*bufferSize = width * height * 4;
return pFrameYUV->data[0];
}
context是全局变量,如果有问题,加群流媒体/Ffmpeg/音视频 127903734或者766718184进行交流
视频下载地址:http://www.chungen90.com/?news_3/
Demo下载地址:http://www.chungen90.com/?news_2
ffmpeg 从视频流中抓取图片的更多相关文章
- Phantomjs+Nodejs+Mysql数据抓取(2.抓取图片)
概要 这篇博客是在上一篇博客Phantomjs+Nodejs+Mysql数据抓取(1.抓取数据) http://blog.csdn.net/jokerkon/article/details/50868 ...
- 基于jsmpeg库下使用ffmpeg创建视频流连接websocket中继器传输视频并播放
这个功能的基本工作是这样的: 1.使用node运行jsmpeg库下的websocket-relay.js文件,这个文件的作用是创建一个websocket视频传输中继器 2.运行ffmpeg,将输出发送 ...
- FFmpeg在JAVA中的使用以及Process.waitFor()引发的阻塞问题
此文已由作者叶海啸授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. FFmpeg是一个开源免费跨平台的视频和音频流方案,可以快速对音视频流进行多方面的处理,本文主要介绍FFmp ...
- HttpClient(三)-- 抓取图片
使用HttpClient抓取图片,先通过 entity.getContent() 获取输入流,然后 使用 common io 中的文件复制 方法 将图片专区到本地,代码如下: 1.需要依赖common ...
- ffmpeg architecture(中)
ffmpeg architecture(中) 艰苦学习FFmpeg libav 您是否不奇怪有时会发出声音和视觉? 由于FFmpeg作为命令行工具非常有用,可以对媒体文件执行基本任务,因此如何在程序中 ...
- java练习题(字符串类):显示4位验证码、输出年月日、从XML中抓取信息
1.显示4位验证码 注:大小写字母.数字混合 public static void main(String[] args) { String s="abcdefghijklmnopqrstu ...
- #在FLAT模式下,需要设置flat子网,VM的IP从这个设置的子网中抓取,这时flat_injected需要设置为True,系统才能自动获得IP,如果flat
#在FLAT模式下,需要设置flat子网,VM的IP从这个设置的子网中抓取,这时flat_injected需要设置为True,系统才能自动获得IP,如果flat子网和主机网络是同一网络,网络管理员要注 ...
- ListView与.FindControl()方法的简单练习 #2 -- ItemUpdting事件中抓取「修改后」的值
原文出處 http://www.dotblogs.com.tw/mis2000lab/archive/2013/06/24/listview_itemupdating_findcontrol_201 ...
- 调用opencv相关函数,从视频流中提取出图片序列&&&&jpg图片序列,转化成avi格式视频
/************************ @HJ 2017/3/30 参考http://blog.sina.com.cn/s/blog_4b0020f301010qcz.html修改的代码 ...
随机推荐
- 小知识点 LINQ中延时求值和主动求值的区别
先看个简单的例子: List<, , , , , , }; select c; select c).ToList<int>(); list.Add(); Console.WriteL ...
- redistribute_prefix
使用分发列表和前缀列表控制路由 拓扑如下 将基本环境(ip和路由协议)配置好,所得到的各个路由表如下 R1: R2: R3: EIGRP和OSPF间的双向重分发 1. 在R2上做重分发 2. ...
- Github 访问时出现Permission denied (public key)
一. 发现问题: 使用 git clone 命令时出现Permission denied (public key) . 二. 解决问题: 1.首先尝试重新添加以前生成的key,添加多次,仍然不起作用. ...
- throws与throw的对比
1.throws关键字通常被应用在声明方法时,用来指定可能抛出的异常.多个异常可以使用逗号隔开.当在主函数中调用该方法时,如果发生异常,就会将异常抛给指定异常对象.如下面例子所示:public cla ...
- Objective C中nil/Nil/NULL的区别
nil:指向oc中对象的空指针 Nil:指向oc中类的空指针 NULL:指向其他类型的空指针,如一个c类型的内存指针 NSNull:在集合对象中,表示空值的对象 若obj为nil:[obj messa ...
- Grunt 认识
基本工作流: JS合并.JS压缩.CSS压缩.CSS Sprite.图片优化.测试.静态资源缓存(版本更新)... 基于工作流产生的工具: JSHint(jshint.com).CSSLint(css ...
- String中重要方法与字段
下列这段代码已全部包含了我要写的String类中重要的字段: //StringMisc.java// This program demonstrates the length, charAt and ...
- Myeclipse安装svn插件(link方式)
Myeclipse安装svn插件(link方式) 优点:1.离线安装2.非侵入式 演示版本 myeclipse--myeclipse8.6 svn--subeclipse-site-1.6.5.zip ...
- ArcGIS 坐标系统文件
坐标是GIS数据的骨骼框架,能够将我们的数据定位到相应的位置,为地图中的每一点提供准确的坐标. ArcGIS自带了多种坐标系统,在${ArcGISHome}Coordinate Systems目录下可 ...
- 真正明白C语言二级指针(转载)
指针是C语言的灵魂,我想对于一级指针大家应该都很熟悉,也经常用到:比如说对于字符串的处理,函数参数的“值,结果传递”等,对于二级指针或者多级指针,我想理解起来也是比较容易的,比如二级指针就是指向指针的 ...