RTSP 媒体协议流的录制方案及其覆盖策略详解

简介: 在安防和监控领域,RTSP 媒体协议流有很广泛的使用。本文将介绍一种针对 RTSP 媒体流的录制方案及其相应的覆盖策略。常见的实时录制功能支持三种模式,分别是云端录制、本地服务端录制和页面录制,今天我们介绍的录制方案属于云端录制。

前言

在安防和监控领域,RTSP 媒体协议流有很广泛的使用。本文将介绍一种针对 RTSP 媒体流的录制方案及其相应的覆盖策略。实时录制功能一般支持三种模式,分别是云端录制、本地服务端录制和页面录制,今天我们介绍的录制方案是云端录制。

正文

本文将从录制视频格式的调研、录制方案的选择、异常状况的处理、覆盖策略的执行四个大方面进行介绍。

1. 录制视频格式调研

如果想要实现 RTSP 媒体流的录制功能,就需要考虑录制目标文件的格式,也就是把媒体流录制成哪种格式的视频文件。起初我们预设了三种方案,经过一系列调研后,最终选择了 m3u8。接下来,我们简单介绍一下这个选择过程。

1.1 为什么不用 mp4 格式

mp4 是点播视频中最为常见的视频格式,综合分析下来并不符合我们的使用场景。一般情况下,一个电影视频的最大时长也就两到三个小时左右,保存成一个 mp4 文件就够用了,但是在安防和监控场景下,一个摄像头对应的录制视频文件的长度可能是十几个小时,甚至是十几天。所以,对比下来,mp4 格式更适用于电影网站。


这就引出了 mp4 格式的一个缺点,如果录制存储为一个 mp4 格式,那文件体积可能会非常大。那么,存储的时候就会面临一系列问题,比如磁盘空间不足、大文件分片等状况的处理,特别是录制过程中数据流异常中断可能会导致已经录制的 mp4 文件不可用,这是其一。

image.png

我们知道 mp4 文件是由许多 Box 和 FullBox 组成的,可以参考上图的 Box 树形图,其中,FullBox 是 Box 的扩展,每个 Box 又包含 Header 和 Data 两部分,moov Box 记录了整个 mp4 文件的音视频媒体信息。而 moov Box 一般是在 mp4 文件写完时才在文件尾部添加。因此,又引出了另外一个缺点,如果 mp4 文件特别大,那么在播放的时候,播放器需要加载全部的视频文件到内存中,如果视频文件特别大,这几乎是不现实的。因此,我们在录制结束保存 mp4 的时候,需要把 moov Box 调整到文件头部来避免这个问题。

1.2 为什么不用 mpd 格式

mpd 格式类似于 m3u8 格式,但是它采用的是 XML 的组织形式。我们不选择它的原因也有两个,其一,mpd 格式在现有产品线上没有类似使用场景,我们使用更多的是 m3u8,换句话说就是技术储备不足。


其二,播放器方案的通用性上存在问题,如果使用 mpd 格式,那么我们的播放器方案需要调整,能够支持 mpd 格式媒体的播放,这样一来会给播放器带来一定的工作量和隐含的问题。


最后,给出一个 mpd 的文件示例,让大家对其有一个更加直观的了解。

<?xmlversion="1.0" encoding="UTF-8"?><!--Generated with https://github.com/google/shaka-packager version 97fc982-release--><MPDxmlns="urn:mpeg:dash:schema:mpd:2011"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xlink="http://www.w3.org/1999/xlink"xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"xmlns:cenc="urn:mpeg:cenc:2013"minBufferTime="PT2S"type="static"profiles="urn:mpeg:dash:profile:isoff-on-demand:2011"mediaPresentationDuration="PT734S"><Periodid="0"><AdaptationSetid="0"contentType="audio"lang="en"><Representationid="0"bandwidth="131596"codecs="mp4a.40.2"mimeType="audio/mp4"audioSamplingRate="44100"><AudioChannelConfigurationschemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011"value="2"/><BaseURL>tears_audio_eng.mp4</BaseURL><SegmentBaseindexRange="745-1664"timescale="44100"><Initializationrange="0-744"/></SegmentBase></Representation></AdaptationSet><AdaptationSetid="1"contentType="video"maxWidth="1920"maxHeight="856"frameRate="12288/512"par="38:17"><Representationid="1"bandwidth="769255"codecs="avc1.42c01e"mimeType="video/mp4"sar="852:857"width="320"height="142"><BaseURL>tears_h264_baseline_240p_800.mp4</BaseURL><SegmentBaseindexRange="827-1602"timescale="12288"><Initializationrange="0-826"/></SegmentBase></Representation><Representationid="2"bandwidth="1774254"codecs="avc1.4d401f"mimeType="video/mp4"sar="2242:2249"width="854"height="380"><BaseURL>tears_h264_main_480p_2000.mp4</BaseURL><SegmentBaseindexRange="829-1604"timescale="12288"><Initializationrange="0-828"/></SegmentBase></Representation><Representationid="3"bandwidth="7203938"codecs="avc1.4d4028"mimeType="video/mp4"sar="855:857"width="1280"height="570"><BaseURL>tears_h264_main_720p_8000.mp4</BaseURL><SegmentBaseindexRange="830-1605"timescale="12288"><Initializationrange="0-829"/></SegmentBase></Representation><Representationid="4"bandwidth="18316946"codecs="avc1.64002a"mimeType="video/mp4"sar="856:857"width="1920"height="856"><BaseURL>tears_h264_high_1080p_20000.mp4</BaseURL><SegmentBaseindexRange="832-1607"timescale="12288"><Initializationrange="0-831"/></SegmentBase></Representation></AdaptationSet></Period></MPD>


通过上述文件,我们可以知道这个 mpd 文件包含了一路音频流,同时支持三种不同分辨率和码率的视频流。不同的媒体类型是用 AdaptationSet 标签表示的,内部还可以使用 Representation 标签标记不同分辨率和码率的媒体流。

1.3 为什么最终选择 m3u8 格式

选择 m3u8 的话,优势就会更加明显,除了规避上述方案的问题外,还有一些自身的优势,具体表现如下:

1)本身就是 ts 分片存储形式,不需要再单独考虑大文件的切片问题。

2)现有播放器方案支持 m3u8 格式,不需要再单独进行适配。

3)具有一定的技术储备,开发上手快,开发周期可控。

4)相应的覆盖策略执行起来会更加方便。


最后,给出一个 m3u8 的文件示例,让大家对其有一个更加直观的了解。

#EXTM3U#EXT-X-VERSION:3#EXT-X-TARGETDURATION:17#EXT-X-MEDIA-SEQUENCE:0#EXTINF:11.933333,index_0000.ts#EXTINF:3.866667,index_0001.ts#EXTINF:7.333333,index_0002.ts#EXTINF:16.666667,index_0003.ts#EXTINF:4.133333,index_0004.ts#EXT-X-ENDLIST


通过上述文件,我们可以知道这个 m3u8 文件包含了 5 个 ts 分片,以及它们各自的时长信息。文件以 #EXTM3U 标签开始,并以 #EXT-X-ENDLIST 标签结束。这里有一点需要注意,如果是直播使用的 m3u8 文件,它是没有 #EXT-X-ENDLIST 标签的。

2. 录制方案选择

既然已经确定了目标文件的格式,那么我们就要考虑怎么实现了。目前有两个方案可以考虑,一个是 Golang 纯原生方案,另一个是利用 ffmpeg 实现,接下来分别介绍。

2.1 Go 原生

利用纯原生的 Golang 实现,其实,Golang 处理音视频数据还是有一定优势的,通过解封装 RTSP 媒体流,得到音频数据和视频数据,然后创建对应的解码器,得到对应的原始音频 PCM 数据和原始视频 YUV 数据,再分别编码成 AAC 的音频和 H264 的视频,最后保存成 m3u8 格式的录制文件。整个过程可以参考下图:

image.png

这种方案,编码的工作量会稍微大一些,同时有很多音视频数据处理的细节问题,负载度和难易程度上不如 ffmpeg 方案。

2.2 ffmpeg

利用 ffmpeg 工具库,通过启用 ffmpeg 进程来完成对应的 RTSP 流数据接收和 m3u8 文件录制保存工作,这样会更加简单,我们只需要管理好进程的创建、释放和异常处理工作。

3. 异常处理

录制过程中会遇到各种各样的问题,接下会分别介绍。有一点是相同的,所有的异常状况都会通知到录制调度服务,由调度服务进行统一分析和管理,同时支持热备机制,我们通过 Nacos 的服务发现机制监测录制调度服务的运行状态,具体关系可以参考下图:

image.png

3.1 CPU、磁盘

CPU 负载过高和磁盘空间不足是最为常见的两种录制时的异常状况,大致的处理逻辑也是较为相似的。

CPU 过高的处理逻辑,可以参考下图:

image.png

当前机器接收到任务后,进行自检操作,发现 CPU 负载过高会停止当前录制任务的执行,同时上报调度服务,重新分配别的机器执行该录制任务。

当前机器正在执行录制任务,突然发现 CPU 负载超过阈值,会持续观察一段时间,假定观察周期为 10 秒,如果 CPU 负载连续 10 秒钟超高,那么会停止当前录制任务,同时上报调度服务,请求别的机器继续执行该录制任务,最后将两台机器上的录制文件进行逻辑关联保存到数据库中。如果 CPU 负载在 10 秒内恢复到正常值,我们将继续执行当前录制任务。


磁盘空间不足的处理逻辑和 CPU 负载过高有类似的处理逻辑,具体可以参考下图:

image.png

通过流程图,我们也可以知道磁盘空间不足的处理逻辑和 CPU 负载过高时类似,上图已经展示的非常明确了,这里就不过多赘述了。

3.2 异常处理

一些其他的异常处理情况,比如崩溃,整体流程可以参考下图:

image.png

异常发生时,如果是一般异常,我们只需要将状态通知调度服务即可,调度服务记录相关日志,综合分析整个录制服务的状态。如果 60%的录制机器触发了相同的异常,调度服务就要采取相应的策略。如果是崩溃等重大异常,就需要重启机器或者调度新的机器继续执行录制任务。

3.3 录制超时

如果发生了录制超时,比如我们想录制 24 个小时的视频,现在时长已经录够了,接下来应该怎么做呢?一般有两种处理方法,第一种是直接停止当前录制,上报通知调度服务即可,这种处理方式比较简单粗暴,但是在安防和监控领域是不合适的。第二种是执行特定规则的覆盖策略,实现循环覆盖,始终保留最近 24 小时之内的视频画面内容。

image.png


对比上述两种处理方式,当发生录制超时时,第二种方式是最符合安防和监控领域的通用做法。那么覆盖策略又是怎么实现的呢,这就引出了下面的内容——覆盖策略。

4. 覆盖策略

覆盖策略在原理上理解起来很简单,但是具体执行时,就不那么简单了。首先,我们也先通过一个流程图对覆盖策略的处理逻辑有一个整体上的认识。

image.png

4.1 一级定时器

当录制任务启动时,我们同时启动一个定时器(一级定时器),定时器的时长就是录制任务的目标时长,这个非常好理解。但是,这个定时器只生效一次或者一次都不生效。只有一级定时器生效后,才会启动二级定时器。如果一级定时器没有启动,那么二级定时器也不会启动。


我们可以这样理解,只有一级定时器触发,录制服务才会执行对应的覆盖策略。当覆盖策略启动后,一级定时器销毁,二级定时器生效。

4.2 二级定时器

当文件时长达到了预设的最大时长时,我们将启动二级定时器。其实,二级定时器控制的是覆盖策略的删除频率,每次时间到了,就删除早些时候到录制文件分片。

4.3 执行覆盖

具体覆盖的执行逻辑是,根据 ts 分片的时长和二级定时器的时间周期,计算需要删除的 ts 分片个数,同时更新 m3u8 中的索引列表,然后循环执行该策略,最终实现动态循环的录制覆盖策略。

image.png

覆盖策略的执行过程如上图所示,相信通过上文的解释,大家理解起来还是非常容易的。需要特别说明的是,由于二级定时器执行周期 t 的限制,录制文件的实际时长在最大录制时长 T 和(T+t)之间。

结尾

好了,现在关于 RTSP 媒体流的录制方案和覆盖策略就介绍完了,相信大家对云端录制方案也有了一定认识,有自己想法和感兴趣的小伙伴,欢迎评论留言。关注我,分享更多音视频和流媒体服务器内容。

目录
相关文章
|
Android开发 开发者 UED
Android平台RTMP推送端实现外部数据对接推送和录像
好多开发者在做Android平台RTMP推送对接的同时,除了编码前的数据外,还有些外部编码数据推送诉求,他们希望外部的编码音视频数据不止可以实现RTMP推送,还可以同时在推送端实时录制下来,本文以我们(官方)Android平台RTMP直播推送模块为例,介绍下外部数据对接流程和数据录制流程。
109 0
|
4月前
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
|
18天前
|
编解码 vr&ar 图形学
Unity下如何实现低延迟的全景RTMP|RTSP流渲染
随着虚拟现实技术的发展,全景视频逐渐成为新的媒体形式。本文详细介绍了如何在Unity中实现低延迟的全景RTMP或RTSP流渲染,包括环境准备、引入依赖、初始化客户端、解码与渲染、优化低延迟等步骤,并提供了具体的代码示例。适用于远程教育、虚拟旅游等实时交互场景。
26 2
|
25天前
|
编解码 JavaScript 前端开发
使用 MediaSource 规范实现自适应流播放
【10月更文挑战第26天】通过以上步骤,就可以使用MediaSource规范实现自适应流播放,根据网络状况动态地调整播放的码率,为用户提供更流畅的观看体验。需要注意的是,实际应用中还需要处理更多的细节和错误情况,以确保播放的稳定性和可靠性。
|
4月前
|
编解码 Linux 开发工具
Windows平台RTSP|RTMP播放器如何实现细粒度录像控制
大牛直播SDK为Windows平台提供了细致的RTSP/RTMP直播播放及录像功能。支持多平台(Windows/Linux/Android/iOS)的推送端录像,并具备轻量级RTSP服务及GB28181设备接入能力。其特性包括:拉取RTSP/RTMP流录像、推送端同步录像、录像过程中的实时暂停与恢复、支持中文路径设置、单文件大小限制、纯音频/视频或音视频录制模式、音频转码至AAC、H.265编码支持、URL切换时自动文件分割等功能。此外,还提供丰富的事件回调机制以监测录像状态。通过细粒度的接口设计,满足了多样化的应用场景和技术需求。
|
4月前
|
监控 开发工具 数据安全/隐私保护
Windows平台如何实现多路RTSP|RTMP流合成后录像或转发RTMP服务
本文介绍了在Windows平台上实现多路RTSP/RTMP视频流的合并技术。主要应用场景包括驾考、全景摄像头以及多路会议录制等。技术实现上,文章详细展示了如何使用特定的SDK来解码并回调YUV或RGB数据,再将这些数据按照图层形式进行合成。示例代码中给出了初始化参数、设置视频帧回调函数、以及如何配置不同图层的具体步骤。最终,合成后的视频可以推送到RTMP服务器、注入到本地RTSP服务,或是直接录制为MP4文件。此外,还提供了添加实时文字水印的方法,并展示了四路视频流合成后的“四宫格”效果。
|
6月前
|
图形学 异构计算
蓝易云 - Unity下如何实现低延迟的全景RTMP|RTSP流渲染
以上就是在Unity中实现低延迟的全景RTMP/RTSP流渲染的基本步骤。具体的实现可能会根据你的具体需求和所使用的库有所不同。
113 0
|
数据采集 开发工具 Android开发
Android平台如何实现屏幕数据采集并推送至RTMP服务器
随着无纸化、智慧教室等场景的普及,好多企业或者开发者开始寻求更高效稳定低延迟的RTMP同屏方案,本文以大牛直播SDK(Github)的同屏demo(对应工程:SmartServicePublisherV2)为例,介绍下如何采集编码推送RTMP数据到流媒体服务器。
187 0
|
编解码 监控 网络协议
Android平台GB28181设备接入侧如何实现按需打开视音频采集传输
Android平台GB28181设备接入侧如何实现按需打开视音频采集传输
160 2
|
存储 编解码 缓存
海康摄像头开发笔记(一):连接防爆摄像头、配置摄像头网段、设置rtsp码流、播放rtsp流、获取rtsp流、调优rtsp流播放延迟以及录像存储
Hik防爆摄像头录像,因为防爆摄像头会有对应的APP软件,与普通的网络摄像头和球机不一样,默认认为它不可以通过web网页配置,所以弄了个来实测确认。经测试实际上也是可以通过web网页配置(与网络摄像头基本是一致的,在码流方面可能会有些不一样),然后提取rtsp流的,界面与球机无异,只是没有球机的云台控制功能,但是界面上也是有的。
海康摄像头开发笔记(一):连接防爆摄像头、配置摄像头网段、设置rtsp码流、播放rtsp流、获取rtsp流、调优rtsp流播放延迟以及录像存储