如何强制ffmpeg编码时输出一个关键帧
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何强制ffmpeg编码时输出一个关键帧相关的知识,希望对你有一定的参考价值。
如何强制ffmpeg编码时输出一个关键帧AVCodecContext *c //编码器环境句柄AVFrame* f //需要编码的一帧视频 在编码前设置
f->pict_type=FF_I_TYPE;
f->key_frame=1;
然后编码
*outsize = avcodec_encode_video(c, temp, outbuf_size, f);
则编码之后通过如下参数判断是否为关键帧:
key_frame=c->coded_frame->key_frame;
pict_type=c->coded_frame->pict_type; 参考技术A int main()
SwsContext *pSWSCtx;
AVFormatContext *pFormatCtx;
const char *filename="sample.mpg";
int i,videoStream,y_size;
AVCodecContext *pCodecCtx;
AVFrame *pFrame;
AVFrame *pFrameRGB;
int numBytes,frameFinished;
uint8_t *buffer;
static AVPacket packet;
av_register_all();
if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)
printf("error!\n");
if(av_find_stream_info(pFormatCtx)<0)
printf("error!\n");
dump_format(pFormatCtx, 0, filename, false);
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
videoStream=i;
break;
if(videoStream==-1)
printf("error!\n");// Didn't find a video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
AVCodec *pCodec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
printf("error!\n");
if(avcodec_open(pCodecCtx, pCodec)<0)
printf("error!\n");
pFrame=avcodec_alloc_frame();
pFrameRGB = avcodec_alloc_frame();
numBytes=avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width,pCodecCtx->height);
buffer=new uint8_t[numBytes];
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);
pSWSCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
i=0;
while(av_read_frame(pFormatCtx,&packet)>=0)
if(packet.stream_index==videoStream)
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);
if(frameFinished)
if(pFrame->key_frame==1)//这里取到关键帧数据
sws_scale(pSWSCtx, pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
i++;
av_free_packet(&packet);
av_free(pFrameRGB);
av_free(pFrame);
sws_freeContext(pSWSCtx);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);
return 0;
ffmpeg视频剪切时长不正确
参考技术A 在windows下使用ffmpeg以下命令剪切视频时,发现剪切后的时长都会比设置的时长长ffmpeg -ss 00:10 -t 30 -i 0.mp4 -c copy 2.mp4
以上的命令是从10s开始剪30s时长的视频,不过实际出来的时长32s左右
-c copy就是没有重新编码,直接裁剪视频,这样会出现一个问题:如果不重编码的分割视频,就需要对准视频的关键帧分割,比如视频的关键帧在8s处,而你是从10s开始分割,分割就会调整在8s处,这样剪切出来的视频就会比想要的长了
目前我的解决方法就是重新编码视频,去掉-c copy就行了,不过重新编码有点耗时间。有其他的解决方法欢迎指出。
以上是关于如何强制ffmpeg编码时输出一个关键帧的主要内容,如果未能解决你的问题,请参考以下文章
请问如何将这些 Blender 视频设置转换为 ffmpeg?
将 FFMPEG 编码为 MPEG-DASH - 或带有关键帧集群的 WebM - 用于 MediaSource API