,转载)ffmpe—实现将视频存储为图片jpg

技术,转载)ffmpe—实现将视频存储为图片jpg (转载)ffmpe—实现将视频存储为图片jpg原文出自:https://images1.tqwba.com/20211201/xuqcjtf4

(转载)ffmpe -实现将视频存储为图片使用联合图象专家组文件交换格式存储的编码图像文件扩展名

原文出自:https://images 1 . tqwba.com/20211201/xuqcjtf 4 ewe ‘,’ e :/QT/test _ ffmpegSavePic/ffmpeg/output/’,索引);

sprintf_s(out_file),sizeof(out_file),’ %s%d.jpg ‘,’./output/’,index);

//分配AVFormatContext对象

AVFormatContext * pfformactx=avformat _ alloc _ context();

//设置输出文件格式

pfformactx-oformat=av _ guess _ format(‘ mjpeg ‘,NULL,NULL);

//创建并初始化一个和该全球资源定位器(统一资源定位符)相关的AVIOContext

if(AVIO _ open(pfformactx-Pb,out_file,AVIO_FLAG_READ_WRITE) 0)

{

printf(‘无法打开输出文件’);

返回-1;

}

//构建一个新溪流

AVStream * PavStream=avformat _ new _ stream(pfformactx,0);

if (pAVStream==空)

{

返回-1;

}

//设置该溪流的信息

AVCodecContext * pcodectx=Pavlastream-codec;

pcodectx-codec _ id=pfformactx-oformat-video _ codec;

pcodectx-codec _ TYPE=AVMEDIA _ TYPE _ VIDEO;

pcodectx-PIX _ fmt=AV _ PIX _ FMT _ yuvj 420 p;

pcodectx-width=width;

pcodectx-高度=高度;

pcodectx-时基。num=1;

pcodectx-时基。den=25

//打印输出相关信息

av _ dump _ format(pfformactx,0,out_file,1);

//==================================查找编码器==================================//

AVCodec * pCodec=AVCodec _ find _ encoder(pcodectx-codec _ id);

if(!pCodec)

{

printf(‘找不到编解码器’);

返回-1;

}

//设置pCodecCtx的解码器为pCodec

if(av codec _ open 2(pcodectx,pCodec,NULL) 0)

{

printf(‘无法打开编解码器’);

返回-1;

}

//=====================================写入标头=====================================//

avformat _ write _ header(pfformactx,NULL);

int y _ size=pcodectx-宽度* pcodectx-高度;

//====================================编码==================================//

//给AVPacket分配足够大的空间

AVPacket pkt

av_new_packet(pkt,y _ size * 3);

int get _ picture=0;

int ret=avcodec _ encode _ video 2(pcodectx,pkt,pFrame,got _ picture);

if (ret 0)

{

printf(‘编码错误\\ n ‘);

返回-1;

}

if(get _ picture==1)

{

PKT。stream _ index=PavStream-index;

ret=av _ write _ frame(pfformactx,PKT);

}

av _ free _ packet(PKT);

//写预告片

av_write_trailer(pF

ormatCtx);
//if (pFrame){
// av_frame_unref(pFrame);
//}
if (pAVStream)
{
avcodec_close(pAVStream-codec);
}
avio_close(pFormatCtx-pb);
avformat_free_context(pFormatCtx);
return 0;
}
//没有完全源代码,自己修改过的
void FFmpegDemo::on_pictureBtn2_clicked()
{
//1.FFMPEG初始化操作
av_register_all(); //初始化FFMPEG 调用了这个才能正常适用编码器和解码器
//=========================== 创建AVFormatContext结构体 ===============================//
//分配一个AVFormatContext,FFMPEG所有的操作都要通过这个AVFormatContext来进行
AVFormatContext *pFormatCtx = avformat_alloc_context();
//==================================== 打开文件 ======================================//
char *file_path = “./2.mp4”;//这里必须使用左斜杠
int ret = avformat_open_input(pFormatCtx, file_path, NULL, NULL);
if (ret != 0)
{
cout “open error!” endl;
return ;
}
//循环查找视频中包含的流信息,直到找到视频类型的流
//便将其记录下来 保存到videoStream变量中
int i;
int videoStream;
//=================================== 获取视频流信息 ===================================//
if (avformat_find_stream_info(pFormatCtx, NULL) 0)
{
cout “Could’t find stream infomation.” endl;
return ;
}
videoStream = -1;
for (i = 0; i pFormatCtx-nb_streams; i++)
{
if (pFormatCtx-streams[i]-codec-codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
}
}
//如果videoStream为-1 说明没有找到视频流
if (videoStream == -1)
{
cout “Didn’t find a video stream.” endl;
return ;
}
//================================= 查找解码器 ===================================//
AVCodecContext* pCodecCtx = pFormatCtx-streams[videoStream]-codec;
AVCodec* pCodec = avcodec_find_decoder(pCodecCtx-codec_id);
if (pCodec == NULL)
{
cout “Codec not found.” endl;
return ;
}
//================================ 打开解码器 ===================================//
if (avcodec_open2(pCodecCtx, pCodec, NULL) 0)// 具体采用什么解码器ffmpeg经过封装 我们无须知道
{
cout “Could not open codec.” endl;
return ;
}
//================================ 设置数据转换参数 ================================//
SwsContext * img_convert_ctx;
img_convert_ctx = sws_getContext(pCodecCtx-width, pCodecCtx-height, pCodecCtx-pix_fmt, //源地址长宽以及数据格式
pCodecCtx-width, pCodecCtx-height, AV_PIX_FMT_YUVJ420P, //目的地址长宽以及数据格式
SWS_BICUBIC, NULL, NULL, NULL);//算法类型 AV_PIX_FMT_YUVJ420P AV_PIX_FMT_BGR24
//==================================== 分配空间 ==================================//
//一帧图像数据大小
int numBytes = avpicture_get_size(AV_PIX_FMT_YUVJ420P, pCodecCtx-width, pCodecCtx-height);
unsigned char *out_buffer;
out_buffer = (unsigned char *)av_malloc(numBytes * sizeof(unsigned char));
AVFrame * pFrame;
pFrame = av_frame_alloc();
AVFrame * pFrameRGB;
pFrameRGB = av_frame_alloc();
avpicture_fill((AVPicture *)pFrameRGB, out_buffer, AV_PIX_FMT_YUVJ420P, pCodecCtx-width, pCodecCtx-height);
//会将pFrameRGB的数据按RGB格式自动”关联”到buffer 即pFrameRGB中的数据改变了 out_buffer中的数据也会相应的改变
//=========================== 分配AVPacket结构体 ===============================//
int y_size = pCodecCtx-width * pCodecCtx-height;
AVPacket *packet = (AVPacket *)malloc(sizeof(AVPacket)); //分配一个packet
av_new_packet(packet, y_size); //分配packet的数据
//2.循环采集视频流数据 将其转换为图片
//=========================== 读取视频信息 ===============================//
int index = 0;
//读取的是一帧视频 数据存入一个AVPacket的结构中
while (av_read_frame(pFormatCtx, packet) = 0)
{
//此时数据存储在packet中
if (packet packet-stream_index == videoStream)
{
//视频解码函数 解码之后的数据存储在 pFrame中
int got_picture = 0;
ret = avcodec_decode_video2(pCodecCtx, pFrame, got_picture, packet);
if (ret 0)
{
cout “decode error.” endl;
return;
}
//转换一帧图像
sws_scale(img_convert_ctx, pFrame-data, pFrame-linesize, 0,
pCodecCtx-height, //源
pFrameRGB-data, pFrameRGB-linesize); //目的
SaveAsJPEG(pFrameRGB, pCodecCtx-width, pCodecCtx-height, index++); //保存图片
}
}
free(packet);
av_frame_free(pFrameRGB);
av_frame_free(pFrame);
avcodec_close(pCodecCtx);
avformat_free_context(pFormatCtx);
}

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/128328.html

(0)

相关推荐

  • 12.16 Java继承

    技术12.16 Java继承 12.16 Java继承首先 :继承,指一个对象直接使用另一对象的属性和方法。继承的格式:public class 子类名 entends 父类名{} /* 表示前面的

    礼包 2021年12月17日
  • 赞美春天的句子,有没有对春天赞美的好句子

    技术赞美春天的句子,有没有对春天赞美的好句子)春天来了!你看,融化的冰水把小溪弄醒了。“丁冬赞美春天的句子、丁冬”,它就像大自然的神奇歌手,唱着清脆悦耳的歌,向前奔流……
    2)柳树舒展开了黄绿嫩叶的枝条,在微微的春风

    生活 2021年10月23日
  • 数据之POD数据类型

    技术数据之POD数据类型 数据之POD数据类型1.POD数据类型的起源
    在C语言时代,只有基本数据类型char、int、float和复合数据类型数组、指针、结构体等。但是在C++时代,出现了抽象数据结构

    礼包 2021年12月9日
  • q函数,数学Q

    技术q函数,数学Qlog表示对数。如果a^n = b(a>0,且a≠1),那么数n叫做以a为底b的对数,记做n=log(a)b,【a是下标】其中,a叫做“底数”,b叫做“真数”。一般地,函数y=logax(a>0,且a≠

    生活 2021年10月29日
  • Python语法技巧有哪些

    技术Python语法技巧有哪些这篇文章主要讲解了“Python语法技巧有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python语法技巧有哪些”吧!1. for –

    攻略 2021年11月20日
  • 青团子,青团常温下放了5天,还能吃吗

    技术青团子,青团常温下放了5天,还能吃吗你好青团子,很高兴回答你的问题我的建议是不要吃了,因为五天的时间确实比较久了。通常两三天内吃掉最佳。下面介绍一下保存的方法:
    青团可以放冰箱保存,因为青团不允许添加防腐剂,保质期往

    生活 2021年10月28日