C++如何使用FFmpeg从RTMP流中保存一段视频剪辑

星降

星降

2026-08-04

453人浏览

原创

ffmpeg命令行可直接截取rtmp流,-ss必须置于-i前实现输入侧seek,否则因rtmp无随机访问能力会导致花屏或时长不准;配合-c copy、-avoid_negative_ts make_zero及正确pts处理,即可稳定完成定时录制与裁切。

c++如何使用ffmpeg从rtmp流中保存一段视频剪辑

ffmpeg命令行直接截取RTMP流最简单

不用写C++也能完成需求:FFmpeg本身支持从RTMP拉流并按时间窗口保存为本地文件,90%的剪辑场景用命令就行。关键不是“能不能用C++”,而是“有没有必要用C++”。如果只是定时录几段、按秒裁切、转封装,ffmpeg命令足够稳定且调试快。

常见错误是直接用-ss + -t在RTMP源上硬切,结果首帧花屏或时长不准——因为RTMP没有随机访问能力,-ss必须放在输入参数前(即“输入侧seek”),否则会先解码再丢帧,延迟大还不准。

  • ffmpeg -i "rtmp://example.com/live/stream" -ss 00:01:20 -t 30 -c copy -f mp4 output.mp4 → 错误:-ss放后面,实际从连接开始解码后才截,不准
  • ffmpeg -ss 00:01:20 -i "rtmp://example.com/live/stream" -t 30 -c copy -f mp4 output.mp4 → 正确:-ss在-i前,FFmpeg尝试在协议层跳转(依赖服务器支持)
  • 若服务器不支持seek(如多数Nginx-rtmp),则必须用-c:v copy -c:a copy配合-avoid_negative_ts make_zero防止时间戳错乱

用libavcodec/libavformat写C++要绕开RTMP协议栈

FFmpeg的C API本身不处理RTMP;它靠librtmp(或libswscale等)作为第三方协议后端。你调avformat_open_input()打开"rtmp://..." URL时,背后其实是librtmp在干活。这意味着:不能假设RTMP连接行为和本地文件一致,尤其超时、重连、断流恢复都得自己管。

容易踩的坑是忽略AVFormatContext->interrupt_callback——RTMP流可能卡住不动,av_read_frame()会无限阻塞。必须设回调函数+超时逻辑,否则程序假死。

  • 初始化时务必调avformat_network_init(),否则RTMP/HTTP等网络协议不可用
  • avformat_find_stream_info()对RTMP可能耗时长甚至失败,可设fmt_ctx->probesize = 1024*1024fmt_ctx->max_analyze_duration = 5000000限制分析深度
  • 音频/视频流时间基(time_base)来自服务器,不一定等于AV_TIME_BASE_Q,计算PTS时别硬除,要用av_rescale_q()

保存剪辑的关键是PTS控制而非单纯计数帧

RTMP流没有全局时间线,每帧的PTS是相对于流启动时刻的。想截取“从第80秒开始的30秒”,不能靠frame_count * frame_duration估算,必须用PTS做判断。而且不同流的时间基不同,比如H.264流常用{1, 1000},AAC音频可能是{1, 44100}

C函数速查手册(CHM版)
C函数速查手册(CHM版)

C函数速查手册(CHM版)

下载

典型做法是记录第一个视频包的pkt.dts(或pts),然后把目标起始时间(如80秒)换算成该流的时间基单位,再逐包比较。注意:AVPacket.dts可能为AV_NOPTS_VALUE,此时需回退到pts或用前序包推算。

  • 起始时间换算:target_dts = av_rescale_q(80 * AV_TIME_BASE, AV_TIME_BASE_Q, stream->time_base)
  • 保存条件:当pkt.dts != AV_NOPTS_VALUE && pkt.dts >= target_dts && pkt.dts
  • 务必用av_interleaved_write_frame()写入,否则音视频包顺序错乱,播放器无法同步

输出MP4必须处理moov位置和B帧依赖

RTMP流里H.264通常带B帧,而MP4容器要求关键帧(IDR)开头。直接把截下来的包喂给avformat_write_header()再写帧,大概率生成无法播放的文件——要么没moov box,要么第一帧不是IDR。

解决方案只有两个:一是用-c copy模式(命令行)或C++中复用原始packet(不做解码/重编码),但要求起始点恰好是IDR帧;二是解码+重新编码,确保输出第一帧是IDR。后者更可靠但CPU贵。

  • 判断IDR帧:if (pkt->flags & AV_PKT_FLAG_KEY && codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
  • 写MP4前必须调avformat_write_header(),且AVFormatContext.oformat->flagsAVFMT_GLOBALHEADER时,需手动设置codec_ctx->extradata
  • av_write_trailer()关闭输出——漏掉这步,文件末尾moov缺失,几乎所有播放器打不开

真正麻烦的不是代码量,而是RTMP流的不可控性:服务器时间戳漂移、关键帧间隔不定、网络抖动导致包乱序。哪怕逻辑写对,实测时仍要反复调av_packet_rescale_ts()和丢弃非单调DTS包。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++ c++标准整数类型

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

833

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

753

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

244

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

242

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

224

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

462

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1107

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

858

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1023

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
RabbitMQ 教程手册
RabbitMQ 教程手册

共0课时 | 0人学习

Linux man-pages 项目
Linux man-pages 项目

共0课时 | 0人学习

C# 教程
C# 教程

共94课时 | 20.2万人学习