录制视频的基本步骤是:

1. 初始化ffmpeg的基本对象,并将这些对象关联起来,然后打开文件并写入文件头。

2. 编码视频,并将编码后数据存写到文件中。

3. 写入文件尾,并清理ffmpeg对象。

首先,需要初始化ffmpeg的一些对象,初始化的顺序为:

创建并初始化AVOutputFormat, 基于AVOutputFormat创建并初始化AVFormatContext。

然后查找AVCodec, 基于找到的AVCodec创建并初始化AVCodecContext,打开AVCodec。

然后基于找到的AVCodec创建AVStream。

然后创建并初始化AVIOContext。

其中AVStream, AVCodec, AVCodecContext可能会有两组,一组用来录制音频,一组用来录制视频,如下:

AVOutputFormat和AVFormatContext可以通过avformat_alloc_output_context函数来初始化。

AVCodec通过avcodec_find_encoder函数来查找

AVCodecContext通过avcodec_alloc_context3来分配

AVCodecContext初始化完成后,可以通过avcodec_open2打开编码器

AVStream通过avformat_new_stream来分配

以上对象初始化完成后,需要将codec的信息拷贝到AVFormatContext对象中,以便与将编码器信息存储到文件中,这个操作可以通过avcodec_parameters_from_context操作

最后通过avio_open打开文件并初始化AVIOContext。

最后通过avformat_write_header写入文件头,整个初始化阶段就算是完成了

以下初始化代码供参考:

avformat_alloc_output_context2(&format_context_, nullptr, nullptr, file_path.c_str());if(format_context_ == nullptr){avformat_alloc_output_context2(&format_context_, nullptr, "mpeg", file_path.c_str());}if(format_context_ == nullptr){return false;}AVOutputFormat *output_format = format_context_->oformat;output_format->video_codec = AV_CODEC_ID_H264;AVCodec *codec = avcodec_find_encoder(output_format->video_codec);codec_context_ = avcodec_alloc_context3(codec);codec_context_->codec_id = output_format->video_codec;codec_context_->pix_fmt = AV_PIX_FMT_YUV420P;codec_context_->width = width;codec_context_->height = height;codec_context_->time_base = {1, 1000};codec_context_->gop_size = 12;if (codec_context_->codec_id == AV_CODEC_ID_MPEG2VIDEO){codec_context_->max_b_frames = 2;}if (codec_context_->codec_id == AV_CODEC_ID_MPEG1VIDEO){codec_context_->mb_decision = 2;}if (output_format->flags & AVFMT_GLOBALHEADER)codec_context_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;int ret = avcodec_open2(codec_context_, codec, nullptr);if(ret != 0){return false;}video_stream_ = avformat_new_stream(format_context_, codec);if(video_stream_ == nullptr){return false;}ret = avcodec_parameters_from_context(video_stream_->codecpar, codec_context_);if(ret != 0){return false;}ret = avio_open(&format_context_->pb, file_path.c_str(), AVIO_FLAG_WRITE);if(ret != 0){return false;}ret = avformat_write_header(format_context_, nullptr);if(ret != 0){return false;}

注意,有些编码器只支持一些固定的帧率,对于这样的编码器,AVCodecContext中的time_base是不能随便设置的,当写文件头失败时,可以检查一下这一点

初始化完成后,就可以进行视频编码录制了,跟初始化相比,编码录制的过程要简单的多,核心函数就三个:

avcodec_send_frame进行视频编码

avcodec_receive_packet用于获取编码后的数据

av_write_frame用于将编码后的数据写入文件

以下代码供参考:

av_image_fill_arrays(src_frame_->data, src_frame_->linesize, data,AV_PIX_FMT_RGB24, src_frame_->width, src_frame_->height, 1);sws_scale(sws_context_, src_frame_->data, src_frame_->linesize, 0, src_frame_->height,dst_frame_->data, dst_frame_->linesize);auto now_time = std::chrono::steady_clock::now();dst_frame_->pts = std::chrono::duration_cast<std::chrono::milliseconds>(now_time - start_time_point_).count();int ret = avcodec_send_frame(codec_context_, dst_frame_);if(ret == 0){AVPacket packet;av_init_packet(&packet);ret = avcodec_receive_packet(codec_context_, &packet);if(ret == 0){av_packet_rescale_ts(&packet, codec_context_->time_base, video_stream_->time_base);av_write_frame(format_context_, &packet);}av_packet_unref(&packet);}

这里的第16行注意一下,将编码后的数据写入文件之前,一定要进行时间转换,否则播放视频时会出现视频播放速度太快的问题

最后就是结束录制了,这个过程就不用多说了,看代码:

if(format_context_ != nullptr){av_write_trailer(format_context_);}if(sws_context_ != nullptr){sws_freeContext(sws_context_);sws_context_ = nullptr;}if(codec_context_ != nullptr){avcodec_close(codec_context_);avcodec_free_context(&codec_context_);}if(format_context_ != nullptr){avio_close(format_context_->pb);avformat_free_context(format_context_);format_context_ = nullptr;}

ffmpeg视频录制相关推荐

  1. FFmpeg视频录制(WIN)

    FFmpeg视频录制(WIN) 命令 查看当前平台可用的设备 ffmpeg -devices// 结果如下: Devices:D. = Demuxing supported.E = Muxing su ...

  2. FFmpeg视频录制压缩处理走过的坑

    在公司里面开发项目做视频处理时遇到了问题,这个问题困扰我很久了,解决了只想给大家说出来,虽然很简单的问题,免得你们遇到我类似的问题再次难以自拔! 视频压缩处理我用了两种方式来解决的,一种是第三方,一种 ...

  3. FFmpeg 视频录制 - 视频添加滤镜和编码

    前言 音视频开发中,视频编码是另一个重要的部分,基于 FFmpeg 软件解码前面系列文章已经介绍过了. 接下来主要介绍软件编码这一块,包括视频编码.音频编码.为视频添加滤镜等,后续文章安排介绍 And ...

  4. FFmpeg 开发(10):FFmpeg 视频录制 - 视频添加滤镜和编码

    音视频开发中,视频编码是另一个重要的部分,基于 FFmpeg 软件解码前面系列文章已经介绍过了,接下来主要介绍软件编码这一块,包括视频编码.音频编码.为视频添加滤镜等.后期文章安排将介绍 Androi ...

  5. FFmpeg 开发(12):Android FFmpeg 实现带滤镜的微信小视频录制功能

    前文利用 FFmpeg 分别实现了对 Android Camera2 采集的预览帧进行编码生成 mp4 文件,以及对 Android AudioRecorder 采集 PCM 音频进行编码生成 aac ...

  6. ffmpeg命令录制windows音视频

    欢迎转载请注明出处:海漩涡 http://blog.csdn.net/tanhuifang520                 ffmpeg命令录制windows音视频 一.下载ffmpeg 存放在 ...

  7. android+高仿视频录制,高仿微信视频录制, 涂鸦水印添加, 基于 ffmpeg 视频编辑

    功能主要包含5点: 1.基于ffmpeg的视频拍摄及合成; 2.自定义拍摄按钮, 长按放大并且显示拍摄进度; 3.自定义view, 实现手绘涂鸦; 4.自定义可触摸旋转缩放位移的表情文字view; 5 ...

  8. android仿微信拍摄视频教程,仿微信视频拍摄UI, 基于ffmpeg的视频录制编辑(上)

    本项目所使用的so库是VCamera,个人免费, 禁止商用,只用作demo演示 因为最近项目做了关于视频拍摄和视频处理的需求, 所以特来分享一下, 做了一个基于微信录制,  分析ffmpeg视频编辑的 ...

  9. 利用FFmpeg玩转Android视频录制与压缩(二)

    请尊重原创,转载请注明出处:http://blog.csdn.net/mabeijianxi/article/details/72983362 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个 ...

  10. 利用FFmpeg玩转Android视频录制与压缩(三)

    请尊重原创,转载请注明出处http://blog.csdn.net/mabeijianxi/article/details/73011313 前言 上一回说到啊,这千秋月没是佳人离别,时逢枯枝落旧城, ...

最新文章

  1. 快过年了,博客园里的文章也变少了
  2. Nature综述:皮肤微生物群-宿主相互作用
  3. 3D打印机分类与速度
  4. org.quartz.CronTrigger cannot be cast to org.springframework.scheduling.quartz.CronTriggerBean
  5. 网络推广离不开关键词的精准挖掘
  6. jcmd 命令_jcmd:一个可以全部统治的JDK命令行工具
  7. WCF分布式安全开发实践(6):传输安全模式之自定义X509Certificate证书验证
  8. YAML,另一种标记语言?不止是标记语言!
  9. Postgresql - MATERIALIZED VIEW
  10. 【报告分享】腾讯研究院-AI生成内容报告2020.pdf(附下载链接)
  11. python里氏替换原则_php设计模式的六大原则(三):里氏替换原则
  12. spring mvc异步操作处理,注解方式
  13. (转)android之Fragment(官网资料翻译)
  14. C语言实现数据结构——单链表
  15. java mencoder_mencoder java linux
  16. 通过DLL文件实现函数共有及通过调用_stdcall来减少程序文件的大小
  17. 登陆远程kvm_通过IPMI kvm控制台远程重装服务器系统
  18. python输出奇数个数_Python实践|输出0-7组成八位奇数总数
  19. 互联网思维之流量思维
  20. Java 7 - TWR 和 多异常捕获 示例

热门文章

  1. skyWalking相关
  2. delphi调用dll
  3. Ubuntu 14.04 卸载搜狗拼音输入法及后续问题解决
  4. 2022-2027年中国家用清洁产品行业发展监测及投资战略研究报告
  5. 基于Goolgle最新NavigationDrawer实现全屏水平平移
  6. Microsoft SQL Server 2008R2企业版64位(带密钥)
  7. android音乐播放器横评,14款Android音乐播放器年度横评 安卓播放器对比测评
  8. java求100以内的素数
  9. WebView启动支付宝客户端支付失败的解决办法
  10. 如何获取国际短信验证码---创蓝253国际短信接口调用demo