参考博客
step 1
http://baijiahao.baidu.com/s?id=1651732133043095764&wfr=spider&for=pc&isFailFlag=1
安装ffmpeg
step 2
http://www.qmwxb.com/article/1252981.html
代码如下
t.c
#include <stdio.h> #include <assert.h> #include "libavcodec/avcodec.h" #include <libavformat/avformat.h> #include <libswscale/swscale.h> void save_frame(AVFrame *pframe, int width, int height, int iframe){ char filename[32]; int y; sprintf(filename, "frame%d.ppm", iframe); FILE *fp = fopen(filename, "w+"); assert(fp!=NULL); fprintf(fp, "P6 %d %d 255 ", width, height); // header for (y=0; y<height;y++) fwrite(pframe->data[0]+y*pframe->linesize[0], 1, width*3, fp); fclose(fp); } int main(int argc, char *argv[]){ if(argc<2){ printf("usage: %s filename ",argv[0]); } av_register_all(); AVFormatContext *pctx = NULL; if (avformat_open_input(&pctx, argv[1], NULL, NULL)!=0) { return -1; } assert(avformat_find_stream_info(pctx, NULL)>=0); av_dump_format(pctx, 0, argv[1], 0); int i, video_stream = -1; for (i=0; i<pctx->nb_streams; i++) { // 查找第一个视频流 if (pctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { video_stream =i; break; } } if (-1==video_stream) { printf("no video stream detected "); return -1; } // pcodec_ctx 指向第一个视频流 AVCodecContext *pcodec_ctx = pctx->streams[video_stream]->codec; AVCodec *pcodec = NULL; // 查找视频流对应的解码器 pcodec = avcodec_find_decoder(pcodec_ctx->codec_id); if (NULL == pcodec) { printf("unsupported codec. "); return -1; } // 拷贝上下文 AVCodecContext *pcodec_ctx_orig = avcodec_alloc_context3(pcodec); if (avcodec_copy_context(pcodec_ctx_orig, pcodec_ctx) != 0) { printf("couldn't copy codec context "); return -1; } // 打开编解码器 if (avcodec_open2(pcodec_ctx, pcodec, NULL)){ printf("couldn't open codec "); return -1; } AVFrame *pframe = av_frame_alloc(); AVFrame *pframe_rgb = av_frame_alloc(); assert(pframe && pframe_rgb); int num_bytes = avpicture_get_size(AV_PIX_FMT_RGB24,pcodec_ctx->width, pcodec_ctx->height); uint8_t *buffer = av_malloc(num_bytes * sizeof(uint8_t)); avpicture_fill((AVPicture *)pframe_rgb,buffer,AV_PIX_FMT_RGB24,pcodec_ctx->width,pcodec_ctx->height); //读取 int frame_finished; AVPacket pkt; // 初始化 sws 上下文,用于转换数据格式 struct SwsContext *sws_ctx = sws_getContext( pcodec_ctx->width, pcodec_ctx->height, pcodec_ctx->pix_fmt, pcodec_ctx->width, pcodec_ctx->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL ); i = 0; // 作为实例,只保存前 5 帧 while (av_read_frame(pctx, &pkt) >= 0) { if (pkt.stream_index != video_stream) { continue; } avcodec_decode_video2(pcodec_ctx, pframe, &frame_finished, &pkt); if (!frame_finished) continue; sws_scale(sws_ctx, pframe->data, pframe->linesize,0, pcodec_ctx->height, pframe_rgb->data, pframe_rgb->linesize); if (++i<=5){ save_frame(pframe_rgb, pcodec_ctx->width, pcodec_ctx->height,i); } } av_free_packet(&pkt); // 释放内存 av_free(buffer); av_free(pframe_rgb); av_free(pframe); // 关闭 codec avcodec_close(pcodec_ctx); avcodec_close(pcodec_ctx_orig); // 关闭打开的文件 avformat_close_input(&pctx); }
安装以下两个命令
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
编译文件 t.c
gcc t.c -I /include/ -L /lib/ -lavutil -lavformat -lavcodec -lavutil -lm -g -lswscale
运行
./a.out ./test.avi(任意视频格式都可以)
会生成帧图片