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修改的代码 ...
随机推荐
- Java中的堆和栈的区别
当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先 ...
- Jquery 格式化时间
我们常常会通过datetime得到时间,但是网页前台往往会显示不同的时间 如:2013-12-15 2013年12月23日 2013 12 15 等多种显示效果,这就需要我们把时间格式化一下. 下面是 ...
- 两种获取connectionString的方式
两种获取connectionString的方式 1. public static string connectionString = ConfigurationManager.ConnectionSt ...
- DCL,DDL,DML,DQL
DCL(Data Control Language)是数据库控制语言. 是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句. 在默认状态下,只有sysadmi ...
- UI2_UITableViewDelete
// AppDelegate.m // UI2_UITableViewDelete // // Created by zhangxueming on 15/7/14. // Copyright (c) ...
- 生成器generator
生成器generator 定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器 代码: def cash_out(a ...
- error at ::0 can't find referenced pointcut performance
严重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support. ...
- 怎样把function中的arguments变成普通数组
当我们在写一个具有处理可变长度参数的函数时,需要对arguments做一些操作.但是arguments它并不是一个数组,没有数组的各种操作,而且,JS的严格模式中不允许更改它的值. 这时我们需要将它的 ...
- 解析json数据总结
json格式的数据一般就是两种类型的,一种是数组类型的,一种是对象类型的. 数组类型:[{"id":"a001","name":" ...
- linux install mpi4py
Downloading The MPI for Python package is available for download at the project website generously h ...