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

SkeyeVSS中国标GB28181、流媒体源RTMP/RTSP/HTTP/ONVIF、RTMP推流等协议视频流实时播放流程详解

本文基于core/app/sev/vss/internal/logic/http/video/stream_play.go的源码:从参数与设备查询,到按接入协议分支、触发 MS 拉流或 GB28181 Invite,再到返回StreamResp与异步处理。

源码地址 点击直达

一、接口入口与请求体

项目说明
注册internal/handler/http/routers.gorouter.POST(video.VStreamPlayLogic.Path(), ...)
Path/video/stream(挂在 Gin 的/api组下,完整路径为POST /api/video/stream
LogicStreamPlayLogic.DO(req types.VideoStreamReq)

VideoStreamReqinternal/types/types.go)主要字段:

字段含义
deviceUniqueId/channelUniqueId必填;用于拉取设备+通道及绑定 MS。
startAt/endAt毫秒时间戳;均大于 0时视为回放playType = playback)。
download是否下载场景(透传给 GB Invite)。
speed回放倍率等(透传 Invite)。
https影响 MS 节点选择时是否按 HTTPS 能力投票(ms.New(...).WithHttps(req.Https))。

流名称覆盖:若 Handler 注入了*gin.Context且 Query 里存在streamName,则用其覆盖stream.New().Produce(...)的默认流名称(便于与已有会话对齐)。


二、主流程总览

1 流媒体源

2 RTMP推流

3 ONVIF

4 GB28181

5 EHOME

other

校验 device/channel

RPC DeviceChannel

解析 playType 直播或回放

VoteNode 选 MS + Produce streamName

组装 StreamResp 基础字段

MS 是否默认节点 IsDef?

GetMSConf 取监听端口

PlayAddress 用已有节点信息

PlayAddress 多协议播放地址

回放时间格式化写入 StartAt/EndAt

AccessProtocol

设备 StreamUrl + start_relay_pull

不设 streamUrl 不拉流

通道 StreamUrl + start_relay_pull

回放先 StopMultiMSStream + Invite

返回未支持

未匹配协议

streamUrl 非空?

CDN 可选 relay_push

StartRelyPull MS

异步 saveChannelSnapshot

Invite 后直接返回 + 异步处理


三、步骤说明

3.1 参数与设备通道

  • deviceUniqueIdchannelUniqueId为空,直接返回参数错误
  • RpcClients.Device.DeviceChannel拉取DeviceChannel;设备或通道为空则设备获取失败

3.2 直播 / 回放与 MS 超时参数

  • 默认playType = play(直播),autoStopPullAfterNoOutMs = 60000
  • req.EndAt > 0 && req.StartAt > 0playType = playbackautoStopPullAfterNoOutMs = 10000(回放更快放弃无输出拉流,避免长时间占资源)。

3.3 流名称与 MS 节点

  • streamName = stream.New().Produce(device, channel, playType)
    • 直播:stream_{deviceUniqueId}_{channelUniqueId}_play
    • 回放:带全局递增PlaybackCount后缀,保证多路回放流名称隔离(见core/common/stream/main.go)。
  • ms.New(ctx, svcCtx).WithHttps(req.Https).VoteNode(device.MSIds)选择媒体节点;nil则返回「未设置流媒体源」

3.4 响应体StreamResp与播放地址Addresses

填充ctypes.StreamResp:接入协议文案、MS 信息、设备/通道 ID、流名称、通道在线状态、StreamUrl占位等;通道/设备展示名优先Label否则Name

MediaServerNode.IsDef分支(是否「默认/简略」节点):

  • 非默认:再调GetMSConf(http://{msAddress})HTTP/HTTPS/RTSP/RTMP等端口,拼stream.PlayAddress(StreamPlayProxyPath, MSVoteNodeResp+端口, streamName)
  • 默认:直接用已有msNodePlayAddress

回放时间startAt/endAt> 0 时格式化为字符串写入data.StartAt/data.EndAt(供调用端展示)。

PlayAddresscore/common/stream/main.go中根据代理配置、MS 端口与流名称生成多协议播放 URL 集合(HTTP-FLV、WebSocket、HLS 等——具体字段见ctypes.PlayAddress)。

3.5 按AccessProtocol分支(核心)❗❗❗

常量来自repositories/models/devices

含义stream_play行为
1流媒体源streamUrl = device.StreamUrl;传输层MediaProtocolMode == 0rtspMode = 1(UDP),否则 TCP。后续StartRelyPull
2RTMP 推流不配streamUrl,注释说明由设备推流触发on_pub_start不调用start_relay_pull
3ONVIFstreamUrl = channel.StreamUrl,同样按MediaProtocolMode决定 RTSP UDP/TCP,再StartRelyPull
4GB28181回放:先StopMultiMSStream停掉与当前流名称前缀相关、带playback的旧流,睡眠 1s降低抢流冲突;再gbs.InviteLogic.Invite(...)下发SIP Invite(含起止时间、DownloadSpeed、流名称等)。成功则go saveChannelSnapshot直接返回Data不再走本文件末尾的StartRelyPull)。
default其它未匹配的协议类型

传输协议transportProtocol := res.Data.Device.TransportProtocol(),用于 RTSPTCP/UDP与后续 MS 参数一致。

3.6 MSstart_relay_pull

streamUrl != ""时调用:

POST http://{msAddress}/api/ctrl/start_relay_pull

参数包括:stream_nameurlauto_stop_pull_after_no_out_mspull_timeout_msrtsp_mode等(见internal/pkg/ms/api.goStartRelyPull)。失败则整体HTTP 错误响应

3.7 CDN 转发

通道开启 CDNCdnState == 1)且CdnUrlrtmp开头,在返回前go StartRelayPush向 MS 启relay_push,把当前流推到 CDN;错误仅打日志,不阻塞主流程返回。

3.8 异步通道快照saveChannelSnapshot

  • go saveChannelSnapshot(streamName, res.Data)(GB 分支在 Invite 成功后也会调用)。
  • ms.Snapshot(device, streamName)取一帧,经临时.raw/.jpg文件,ff.FFMpeg.SnapFile转码,再MvSaveVideoSnapshotDir下由stream.Snapshot(dir, deviceId, channelId)规则命名的路径。
  • 全程defer recover与日志,失败不影响播放接口成功返回

四、与gbs.Invite的关系

GB28181 路径:是由Invite走完整链路(Catalog 在线、StreamInfoGetStreamGroup、端口范围、防重复 Invite、SipSendVideoLiveInvite等,详见video_live_invite.go)。

stream_play传入的InviteParams包括:设备/通道业务 ID、PlayType、格式化后的起止时间字符串DownloadSpeedStreamName、以及已查好的DeviceItem/ChannelItemCaller标记为http 请求stream play invite,便于日志区分来源。


五、播放流程总结

  1. 统一出口:平台无论网页还是内部服务,只要设备+通道即可拿同一套StreamResp(MS 节点、流名称、多协议地址),客户端按能力选播。
  2. 协议差异分支(switch):流媒体源/ONVIF 走拉流 URL + MS;RTMP 推流走设备主动 pub;GB28181 走信令 Invite,避免一种模式套所有协议。
  3. 直播与回放:用时间区间切换playType流名称生成策略(回放带计数后缀),并差异化autoStopPullAfterNoOutMs
  4. MS 抽象:拉流统一StartRelyPull;GB仍由 RTP/SIP 与 MS API 协作,此接口只负责触发 Invite
  5. 快照与播放解耦:快照慢或失败不影响拉流流程

六、注意点

说明
GB 回放 StopMultiMSStream流名称前缀 + playback模糊停流时,需要注意不同流流名称是否相同。
RTMP(= 2)本请求可能只返回地址信息,需要注意MSon_pub_start通知是否有达到。
Invite 与重复请求Invite内部有InviteRequestState与 MS 上Pub状态判断;
stream_play高频重入,需要注意防抖;防抖可以参考core/pkg/dt
流图片快照临时文件与 FFmpeg 依赖配置FFMpeg、磁盘SaveVideoSnapshotDir;未设置会导致快照失败。

七、相关源码索引

说明路径
流播放 Logiccore/app/sev/vss/internal/logic/http/video/stream_play.go
GB Invitecore/app/sev/vss/internal/logic/http/gbs/video_live_invite.go
MSstart_relay_pull/start_relay_pushcore/app/sev/vss/internal/pkg/ms/api.go
流名称与PlayAddresscore/common/stream/main.go
响应core/common/types/stream.goStreamRespPlayAddress
HTTP 路由core/app/sev/vss/internal/handler/http/routers.go
http://www.jsqmd.com/news/536901/

相关文章:

  • ButtonIn:嵌入式C++轻量级按键消抖库设计与实践
  • OpenClaw进阶调试:Qwen3.5-4B-Claude任务失败原因分析
  • leetcode-hot100-10回溯
  • OpenClaw内存优化:让nanobot镜像在4GB设备上流畅运行
  • C语言变量与函数命名规范详解
  • 树莓派X96 一、智能小车初框架(无视觉)
  • SDMatte Web化服务运维指南:supervisorctl管理与日志定位技巧
  • AI教材写作指南:低查重秘诀,快速生成专业教材不是梦!
  • 济南华泰精工:负压出料/高温齿轮泵/高粘度齿轮泵/高精度计量泵/不锈钢泵/分子蒸馏泵/同步分流马达/数字同步马达/选择指南 - 优质品牌商家
  • 51单片机非接触红外测温
  • KAIST团队突破3D游戏世界生成极限:让AI真正理解你的每一个操作
  • 基于CANopen协议的关节电机位置控制方法与实例
  • 像素幻梦创意工坊效果展示:支持透明通道(Alpha)的像素图生成与导出
  • 微信小程序组件事件冒泡问题排查与解决方案
  • VUE.JS 实践 第三章
  • 揭秘AI专著生成秘诀!掌握这些工具,轻松打造专业学术专著
  • SQL 中聚集函数(Aggregate Functions)与 `ANY`/`ALL` 谓词的核心用法、语义等价关系及实际应用要点
  • 在 SAP 中,Cost Object(成本对象) 是归集、控制与结算成本的核心载体,其设置与定义分为主数据创建(前台操作)和后台配置(SPRO)两大场景,不同类型成本对象路径不同
  • Java中的继承:从入门到精通
  • LD8035显示驱动芯片技术文档为何无法生成?
  • MedGemma-X惊艳效果:上传一张胸片,获得多维度结构化诊断分析
  • PyTorch 2.8镜像应用场景:广告公司定制化AI创意生成私有平台案例
  • ChatTTS与OpenVoice本地部署实战:从语音合成到高效推理的完整指南
  • Llama-3.2V-11B-cot实战教程:上传→提问→展开推演→导出结论四步闭环
  • ABAQUS有限元模型:基于CEL算法的斜桩锤击入土模拟
  • 现代C++ | 基础革命特性
  • 吃透 Android 布局资源:从 Chapter2 实战项目看懂四大核心布局
  • 国家金融监督管理总局地市级分支局计算机岗之日常运维:从基础到进阶的全面解析
  • 无源晶振如何用
  • PCB画板时的层数设置