还是给自己 学习啊 大部分是 命令 或是android的~~ 这边得用原生的 我也是刚学 到底什么区别也不太知道~~ 还请大神指点一二
1、fmpeg对将像素数据写入到JPG图片中也封装到了avformat_xxx系列接口中,它的使用流程和封装视频数据到mp4文件一模一样,只不过一个JPG文件中只包含了一帧视频数据而已;
2、ffmpeg对JPG文件的封装支持模式匹配,即如果想要将多张图片写入到多张jpg中只需要文件名包含百分号即可,例如 name%3d.jpg,那么在每一次调用av_write_frame()函数写入视频数据到jpg图片时都会生成一张jpg图片。这样做的好处是不需要每一张要写入的jpg文件都创建一个AVFormatContext与之对应。其它流程和写入一张jpg一样。
流程为:
1、先从MP4中提取指定时刻AVPacket解码成AVFrame
2、然后将步骤1得到的AVFrame进行从素格式YUV420P到JPG需要的YUVJ420P像素格式的转换
3、再重新编码,然后再封装到jpg中
#视频中提取照片流程图

#照片合成视频:

tips:要对jpg进行封装和解封装,编译ffmpeg时要添加如下封装器和解封装
封装器(及对应的编码器)
--enable-muxer=image2
--enable-encoder=mjpeg
接封装器(及对应的解码器)
--enable-demuxer=image2
--enable-decoder=mjpeg
还要IOS的框架,不过本人用不到就不贴了...
有时会碰到这样的需求场景,对一个视频中的某一段感兴趣,想要精确的截取这一段视频以及对应的音频。例如,有一个25fps的MP4的文件,时长20秒,我想要截取从5秒开始到15秒结束的视频以及对应的音频,这里有两点需要说明:
1、对于视频:开始时间5秒,结束时间15秒。只能做到尽量接近,因为源文件25fps,即每一帧的显示间隔为0.04秒,可能5秒附近的视频帧刚好在5.012秒,最大误差一帧时间差就是1/25==0.04秒,所以4.96-5.04秒范围内都可以。
2、对于音频:比如采样率44100,每一个AVPacket包含1024个采样,那么每一帧的显示时间间隔为1/43≈0.025秒,音频再5秒处的最大误差为0.025秒,所以4.975-5.025秒范围内都可以。
这里以MP4文件为例,假设视频的编码方式为H264,音频为aac,其它格式类似。
实现思路
1、在ffmpeg解封装之后得到的AVPacket代表着压缩的音/视频数据,该结构体内有一个字段pts,表示了该音/视频的时间,即前面说的5秒就是要参考这个时间。
2、对于音频来说,只需要依次取出5秒(或者最接近5秒)到15秒处的AVPacket,然后调用ffmpeg封装接口依次写入新的MP4文件即可
3、对于视频来说,写入MP4的第一个AVPacket一定要是I帧(对于H264等有IPB帧改变的编码方式来说,其它编码方式则跟音频一样处理),所以视频的处理分两种情况:
流程图

关键函数
调用av_read_frame()函数时,其内部会有一个文件指针(默认情况下指向文件中的首个AVPacket),所以默认时读取的第一个AVPacket就是文件中的首个AVPacket,调用结束后指针再指向下一个AVPacket。此函数的作用就相当于将指针指向指定的key_frame的AVPacket,那么首次调用av_read_frame()函数时将获取的是满足要求的AVPacket,而非文件的第一个AVPacket。
1、stream_index:代表音视频流的索引,如果为-1,那么将对文件的默认流索引进行操作
2、timestamp:移动到指定的时间戳(单位为AVStream.time_base )。如果stream_index为-1,单位为(AV_TIME_BASE)
3、flag:移动参考的方式,取值如下:
#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes
#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes
#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number
AVSEEK_FLAG_BACKWARD
基于前面指定的时间戳参数查找,如果timestamp处的AVPacket的key_frame非1,那么就往前找,直到找到最近一个key_frame为1的AVPacket
AVSEEK_FLAG_BYTE
基于位置进行查找
AVSEEK_FLAG_ANY
基于前面指定的时间戳参数进行查找,不管AVPacket是否key_frame为1都返回
AVSEEK_FLAG_FRAME
基于帧编号进行查找
遇到问题
1、音频正常播放,视频只是播放了很短的几帧画面
分析原因:由于pkt的时间戳没有减去起始时间导致了音视频的时间戳错乱
解决方案:音频时间戳减去起始时间即可
最后还有一些ffmpeg sdk推流的代码 有需要交流的欢迎加我讨论哦~~~
whaosoft aiot http://143ai.com