当前位置: 首页 > news >正文

保姆级教程:用FFmpeg API将RTSP/HLS流实时录制成MP4(附完整C代码)

从零构建RTSP/HLS流录制工具:FFmpeg API实战指南

在视频监控和直播领域,实时录制网络视频流是常见需求。无论是安防摄像头还是在线直播平台,都需要将RTSP或HLS流可靠地保存为MP4文件。本文将带你从零开始,用FFmpeg API构建一个专业的流录制工具。

1. 环境准备与项目搭建

首先需要配置开发环境。FFmpeg作为多媒体处理的瑞士军刀,提供了丰富的API供我们调用。对于C/C++项目,我们需要:

  1. 下载FFmpeg开发包(建议使用4.x以上版本)
  2. 配置编译环境(Windows下可使用MSYS2或Visual Studio)
  3. 设置正确的包含路径和库链接

关键依赖

# Ubuntu下安装开发依赖 sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev

项目目录结构建议如下:

/rtsp_recorder ├── include/ # FFmpeg头文件 ├── lib/ # FFmpeg库文件 ├── src/ │ ├── main.c # 主程序 │ └── recorder.c # 录制核心逻辑 └── Makefile

2. FFmpeg核心API解析

理解FFmpeg的工作流程是关键。录制网络流主要涉及以下几个核心组件:

  • AVFormatContext:格式上下文,管理输入输出
  • AVCodecParameters:编解码参数
  • AVPacket:压缩后的数据包

初始化流程

AVFormatContext *input_ctx = NULL; AVFormatContext *output_ctx = NULL; // 打开输入流 avformat_open_input(&input_ctx, rtsp_url, NULL, NULL); avformat_find_stream_info(input_ctx, NULL); // 创建输出上下文 avformat_alloc_output_context2(&output_ctx, NULL, NULL, output_file);

3. 流配置与参数设置

正确配置视频流参数是保证录制质量的关键。对于H.264/H.265流,需要特别注意:

  1. 关键帧识别:通过SPS/PPS(VPS)判断流格式
  2. 时间基准(time_base):确保时间戳计算准确
  3. extradata设置:包含重要的编解码信息

参数配置示例

AVStream *out_stream = avformat_new_stream(output_ctx, NULL); avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar); // 特别处理H.265的AVI格式 if(codec_id == AV_CODEC_ID_HEVC && format_is_avi) { out_stream->codecpar->codec_tag = MKTAG('H','2','6','5'); }

4. 实时录制核心逻辑

录制过程需要处理以下几个关键问题:

  • 数据包处理:正确解析和写入视频帧
  • 时间戳计算:保证视频同步和正确时长
  • 错误恢复:网络中断时的重连机制

数据包写入示例

AVPacket pkt; while(av_read_frame(input_ctx, &pkt) >= 0) { if(pkt.stream_index == video_stream_idx) { // 转换时间戳 pkt.pts = av_rescale_q(pkt.pts, input_ctx->streams[video_stream_idx]->time_base, output_ctx->streams[0]->time_base); pkt.dts = pkt.pts; av_interleaved_write_frame(output_ctx, &pkt); } av_packet_unref(&pkt); }

5. 完整工程实现

下面提供一个可直接编译运行的完整示例。该实现包含:

  1. 网络流连接管理
  2. 录制状态控制
  3. 错误处理和日志记录

核心结构体设计

typedef struct { AVFormatContext *input_ctx; AVFormatContext *output_ctx; int video_stream_idx; int running; pthread_t thread; } StreamRecorder;

录制线程函数

void* recording_thread(void *arg) { StreamRecorder *rec = (StreamRecorder*)arg; AVPacket pkt; while(rec->running) { int ret = av_read_frame(rec->input_ctx, &pkt); if(ret < 0) { // 处理错误或重连 break; } if(pkt.stream_index == rec->video_stream_idx) { // 处理并写入视频帧 process_video_packet(rec, &pkt); } av_packet_unref(&pkt); } return NULL; }

6. 高级功能与优化

对于生产环境应用,还需要考虑以下高级功能:

  1. 分段录制:按时间或大小分割文件
  2. 元数据写入:记录摄像头信息等
  3. 性能优化:内存管理和IO优化

分段录制实现思路

void check_file_split(StreamRecorder *rec) { time_t now = time(NULL); if(now - rec->last_split_time > SPLIT_INTERVAL) { close_current_file(rec); open_new_file(rec); rec->last_split_time = now; } }

在实际项目中,我发现最容易出错的地方是时间戳处理。特别是在长时间录制时,确保pts持续递增且不发生回绕至关重要。一个实用的技巧是在每次文件分割时记录最后一个pts值,并在新文件中以此为基准继续递增。

http://www.jsqmd.com/news/693752/

相关文章:

  • 联易融从稳居第一到解锁全球——2026年价值重估逻辑
  • 多元布局,智启未来,洽客科技用创新赋能高质量发展 - 博客湾
  • OpenAI 推出「工作区智能体」升级 GPTs,2026 下半年企业 AI 三国杀将更激烈!
  • RAG评估体系构建指南:如何知道你的检索增强系统真的好用
  • 从Proteus仿真到实物:用Keil MDK-ARM给STM32F103C8T6最小系统板下载第一个程序
  • 学习总结及学习案例
  • SQL优化十大技巧,查询速度提升10倍!
  • 为什么有的工业相机一插就能用,有的却必须配采集卡?
  • 【CrewAI系列7】我用 AI Agent 做性能测试,发现了 1 个致命瓶颈
  • 2026年果蔬专用锋利刀选购分析:主流品牌性能与适配场景专业推荐 - 商业小白条
  • EMAGE:从音频到全身动作,揭秘统一框架如何重塑数字人动画生成
  • 如何用AI智能图像分层工具彻底改变你的设计工作流
  • Anaconda环境激活失败?可能是你的系统PATH“太挤了”!一个分号引发的Invoke-Expression血案
  • 保姆级教程:在浪潮F37X加速卡上从零部署Xilinx QDMA驱动与测试环境
  • 如何用机器学习5步快速评估专利价值?开源专利权利要求广度分析实战指南
  • 别再画用户画像了!试试用JTBD模型,从“用户想完成什么”重新定义你的产品
  • 终极指南:如何在Windows电脑上直接安装安卓APK文件
  • 2026年避暑房公司好评榜:康养房/避暑洋房/景区养老房康养房/养老房 - 品牌策略师
  • macOS百度网盘高效提速完整指南:免费突破下载限制的实用方案
  • AI团队革命:让智能体分工协作改变未来
  • 超越clip:用QtGraphicalEffects为你的QML组件实现高级圆角与异形遮罩
  • eCodeSDK发票组件三步搭建
  • 别再用固定阈值了!用C++实现3σ法则,智能分割图像缺陷(附完整代码)
  • APK Installer:在Windows上无缝运行Android应用的技术实现与最佳实践
  • 从入门到精通:手把手教你用WPF的ItemsControl家族(ListBox/ListView/DataGrid)打造一个高交互性后台管理系统UI
  • 高压均质机HPH构造全解:三大系统一图看懂
  • MySQL Innodb 页缓存管理原理
  • 告别截图!用Python的PyMuPDF库,5分钟搞定PDF批量转高清PNG/JPEG
  • 别再死记硬背了!用Tiny210原理图,手把手拆解DDR内存Bank和Rank的硬件连接
  • 2026摩尔元数AI转型:以AI原生智能体,重构新一代工业软件