SRT协议分析以及收拉流测试

news2024/9/21 0:51:21

文章目录

  • 介绍
  • 协议概述
    • 协议常用URL格式
    • 协议工作流程
    • 协议包格式
      • 数据包和控制包
      • 数据包
      • 控制包
        • ACK
        • NACK
  • 开源协议栈
    • libSRT
    • FFmpeg
    • VLC Media Player
    • SRT Alliance
    • SRS
  • 测试
    • 使用ffmpeg+srs
      • 推流端
      • 接收端
      • 播放端
      • srs配置
    • 使用 libSRT
      • 发送端
      • 接收端

介绍

SRT(Secure Reliable Transport)安全 可靠 传输协议 SRT协议基于UDT(UDP-based Data
Transfer)协议,继承了UDP开销低、速度快的优点,并结合了TCP的可靠性特性,为视频流媒体传输提供了全新的解决方案。

详细说明

https://github.com/Haivision/srt

特点

  • 安全性:
    • SRT支持AES加密,保障端到端的视频传输安全。可以选择AES-128或AES-256位加密,确保数据在传输过程中不被窃取或篡改。
    • 握手过程支持出站连接,无需在防火墙中打开永久外部端口,维护公司安全策略。
  • 可靠性:
    • SRT使用ARQ(Automatic Repeat Request)技术和FEC(前向纠错)技术来确保数据的可靠传输。ARQ通过反馈循环来检测和纠正数据包的丢失和损坏,FEC则通过奇偶校验编码来恢复丢失的数据包。
    • 支持多种流类型,包括多个并发流和不同的媒体流,如多个摄像机角度或可选音频轨道。
  • 低延迟:
    • SRT通过优化数据包大小和发送时间来降低传输延迟。其基于UDP的传输机制减少了协议开销,使得传输速度更快、延迟更低。
    • 提供了灵活的流控制机制和带宽自适应功能,可以根据网络状况动态调整传输速率,确保最佳的传输性能。
  • 灵活性:
    • 支持点对点直接传输数据,也可借助网关或服务器实现点对多端数据传输。
    • 支持多种传输模式,如UDP、TCP、HTTP等,用户可以根据需求选择合适的传输模式。

协议概述

协议常用URL格式

推流

			srt://host:port?streamid=#!::r=live/test,m=publish
ffmpeg -re -stream_loop -1 -i "test.ts" -c copy -f mpegts 'srt://127.0.0.1:1234?streamid=#!::r=srtlive/test,m=publish'

SRT Stream ID 的格式
#!:::这是一个特殊的标记,表示 SRT 协议中的 Stream ID。streamid 参数通常使用 #!:: 作为前缀,但这不是强制性的。你可以直接使用数字或其他标识符 比如1234

srt://127.0.0.1:1234?streamid=1234:r=srtlive/test,m=publish’

r=:指定资源名称,用于标识流的来源。
m=publish:指定模式为 publish。

播放、拉流

ffplay -i 'srt://ip:port?streamid=#!::r=live/test,m=request'

SRT协议通过简单的握手、固定的延时量、ARQ(自动重传请求)、FEC(前向纠错)以及ACK、NACK等策略解决TCP协议在流媒体业务上存在的问题。

协议工作流程

核心流程包括

  • 握手

客户端和服务器之间进行握手以建立连接。握手过程中,双方交换必要的信息,如版本号、身份验证信息等

  • 能力协商

-双方协商传输能力,确定最佳的传输参数,如最大带宽、加密方式 是否使用FEC、ARQ、拥塞控制策略、传输包大小、最大重传次数等。

  • 身份验证

非必须,证书交换:如果启用了安全模式,双方可能会交换证书以进行身份验证。 密钥交换:协商共享密钥,用于加密和解密数据

  • 数据传输(数据分组 前向纠错 ARQ 拥塞控制 加密)

1 数据分组:数据被分割成较小的数据包(称为分组或帧),每个分组包含一部分原始数据。
2 前向纠错 (FEC):为了提高可靠性,SRT使用前向纠错技术,在每个数据分组中添加冗余信息。如果某些分组丢失,接收方可以利用冗余信息重建丢失的数据。
3 自动请求重传(ARQ):如果接收方检测到数据包丢失或损坏,可以请求发送方重传丢失的数据包。
4 拥塞控制:SRT实施拥塞控制机制,根据网络状况动态调整发送速率,以避免网络拥塞。
5 加密:SRT 支持端到端加密,确保数据在传输过程中的安全性。可以使用AES-128 或 AES-256 加密算法。

  • 流量监控
  • 速率控制:SRT 通过速率控制来调整发送速率,确保网络资源得到充分利用,同时避免过度使用带宽。 缓冲管理:SRT 使用缓冲区来存储数据包,以应对网络延迟和抖动
  • 错误处理

丢包检测:SRT 可以检测数据包丢失,并通过 FEC 和 ARQ 机制进行修复。 错误检测:SRT 使用校验和等技术来检测数据包中的错误。
重传请求:如果检测到数据包丢失或损坏,接收方可以请求发送方重传丢失的数据包

  • 关闭连接

SRT 协议中最常用的工作模式为“呼叫 - 监听”(Caller-Listener)模式,监听方(Listener)会持续监听本方的固定
UDP 端口,呼叫方(Caller)通过访问监听方的公网 IP 地址和该固定端口来建立 SRT 连接。 呼叫和监听的角色主要在 SRT
协议握手阶段起作用,无论是编码端还是解码端都可以担任呼叫者或监听者的角色。
在这里插入图片描述

协议包格式

在这里插入图片描述

SRT协议中包含两类数据包:数据包(Data Packet)和控制包(Control Packet)

数据包和控制包

他们通过SRT首部的最高位(标志位)来区分,0代表信息数据包,1代表控制数据包。控制数据包又包含了 握手(Handshake)、肯定应答(ACK)、否定应答(NAK)、对肯定应答的应答(ACKACK),保持连接(Keepalive)、关闭连接(Shutdown) 等多种类型

数据包

在这里插入图片描述
解析

  • 最高字节 0 标识数据包 1 是控制包
  • 数据包序列号:数据包序号的初始值在握手时确定,之后每发一个数据包,数据包序号就会加1;
  • PP:占2位,数据包位置标志位。“10”代表第一个数据包,10”代表第一个数据包,“00”代表中间数据包,“01”代表最后一个数据包,“11”代表单个数据包。
  • O:占1位,顺序标志位。是否按顺序发送 一般为1
  • KK:占2位,加密密钥标志位。“00”代表不用加密,“01”代表偶数密钥,“10”代表奇数密钥。
  • R:占1位,重传包标志位。
  • 报文序号:报文序号从0开始,之后每发一个数据包,报文序号就会加1,报文序号前4个标志位功能如图3所示;数据包序列号对每个数据包进行独立计数,而报文序列号则是在报文范围内进行计数,比如一帧数据
  • 时间戳:以建立时间为基准,单位为微秒;
  • 目的地端口套接字ID:在多路复用的时候可以用来区分不同的SRT流。

SRT通过数据包序列号和报文序号,能明确那些数据包已经被发送出去,通过接收端发送过来的ACK控制指令就知道发送出去的哪些数据已经被成功接收了。如果出现丢包等情况,接收端通过NAK控制指令(如图5所示)通知发送端重传数据

控制包

在这里插入图片描述

  • 最高字节 0 标识数据包 1 是控制包
  • 控制类型
    控制包类型
    不同控制类型有不同结构
    以ACK和NACK举例说明
ACK

ACK用于表示数据包到达确认。所有ACK包可能会携带额外信息,比如RTT、链路容量、传输速率。ACK控制包结构如下:
在这里插入图片描述

通过RTT时间和链路带宽等参数,SRT就可以估计整个网络状态,从而实现自适应的调整

NACK

Negative Acknowlegement(NAK)也是属于控制包,用于表示否定应答(没有收到数据包)。与TCP的NACK否定应答不同的是,SRT采用NAK表示否定应答。NAK控制包结构如下
在这里插入图片描述

开源协议栈

以下是一些常用的 SRT 协议栈:

libSRT

libSRT 是最著名的 SRT 协议实现之一,由 Haivision Systems Inc. 开发并维护。它是一个跨平台的库,

  • 支持多种操作系统,包括 Windows、Linux 和 macOS。
  • 支持 SRT 协议的所有核心功能,包括低延迟、高可靠性、安全性和拥塞控制。
  • 提供了丰富的 API 接口,方便开发者集成 SRT 功能。
  • 支持 RTMP、RTSP、HLS 等其他流媒体协议的转换
- https://github.com/Haivision/libSRT

FFmpeg

ffmpeg 已经集成了 SRT 支持,可以通过简单的命令行参数启用 SRT。此外GStreamer 也集成了srt
注意 ffmpeg 可以用来发送和接收 SRT 流,接受的srt流主要作为录制或者转码。如果要实现一个完整的 SRT 服务器,对众多客户端提供服务,需要其他专门的软件比如srs配合或者自己开发
推流
ffmpeg -re -i input.mp4 -vcodec copy -acodec copy -f srt srt://localhost:1234
接受srt保存为文件
ffmpeg -i srt://localhost:1234 -c copy output.mp4

VLC Media Player

VLC Media Player 是一个流行的多媒体播放器,支持多种编解码器和传输协议,包括 SRT,可以作为客户端或服务器,支持 SRT 流的播放和传输。

SRT Alliance

SRT Alliance 是一个社区驱动的组织,致力于推广和发展 SRT 协议。它不仅提供 SRT 协议的规范和技术支持,还汇集了多个支持 SRT 的开源项目

SRS

SRS (Simple-RTMP-Server): 这是一个高性能的实时流媒体服务器,支持 RTMP、HLS、HTTP-FLV、WebSocket-FLV、GB28181 和 SRT 等多种协议。

测试

确保ffmpeg支持srt 如果不支持需要重新编译

ffmpeg -protocols

使用ffmpeg+srs

  • 使用ffmpeg将文件采用srt协议推到srt服务器
  • 使用 srs接收 SRT 流,
  • 并通过 FFplay 播放 SRT 流,

推流端

 ffmpeg -re -i input.mp4 -vcodec copy -acodec copy -f srt srt://localhost:1234

参数解释

  • -re:使 FFmpeg 以实时模式工作。
  • -i input.mp4:指定输入文件为 input.mp4。
  • -c copy:复制输入流而不进行重新编码。
  • -f srt:指定输出格式为 SRT。
  • srt://localhost:1234:指定目标地址为本地主机的端口 1234。

接收端

ffmpeg -hide_banner -re -i srt://:1234 -c copy -f matroska pipe:1
  • -hide_banner:隐藏 FFmpeg 的启动横幅。
  • -re:使 FFmpeg 以实时模式工作。
  • -i srt://:1234:指定输入为 SRT 协议,监听端口 1234。
  • -c copy:复制输入流而不进行重新编码。
  • -f matroska pipe:1:将输出格式设置为 Matroska 并通过管道输出到标准输出(stdout)。

还可以转发到udp服务器

ffmpeg -hide_banner -re -i srt://:1234 -c copy -f mpegts udp://localhost:1235
  • -f mpegts:指定输出格式为 MPEG-TS。
  • udp://localhost:1235:指定 UDP 输出的地址和端口

播放端

注意 确保FFmpeg已经集成了libsrt库,否则ffplay无法播放srt链接

ffplay srt://localhost:1234

如果需要从标准输入读取使用下面命令

打开第三个终端窗口,执行以下命令
ffplay -

将标准输出的输出重定向到 FFplay:

ffmpeg -hide_banner -re -i srt://:1234 -c copy -f matroska pipe:1 | ffplay -

srs配置

https://ossrs.net/lts/zh-cn/docs/v5/doc/srt
srs中srt介绍

使用 libSRT

发送端

#include <srt/srt.h>
#include <string.h>

int main() {
    SRTSOCKET sock;
    char *url = "srt://localhost:1234";
    
    sock = srt_socket(NULL, SRT_SO_REUSEADDR, 0);
    if (sock == SRT_INVALID_SOCK) {
        fprintf(stderr, "Failed to create socket\n");
        return 1;
    }
    
    int ret = srt_connect(sock, url, strlen(url));
    if (ret < 0) {
        fprintf(stderr, "Failed to connect to %s\n", url);
        return 1;
    }
    
    const char *data = "Hello, SRT!";
    int len = strlen(data);
    ret = srt_send(sock, (const unsigned char *)data, len, 0);
    if (ret != len) {
        fprintf(stderr, "Failed to send data\n");
        return 1;
    }
    
    srt_close(sock);
    
    return 0;
}

接收端

#include <srt/srt.h>
#include <string.h>

int main() {
    SRTSOCKET sock;
    char *url = "srt://*:1234";
    
    sock = srt_socket(NULL, SRT_SO_REUSEADDR, 0);
    if (sock == SRT_INVALID_SOCK) {
        fprintf(stderr, "Failed to create socket\n");
        return 1;
    }
    
    int ret = srt_bind(sock, url, strlen(url));
    if (ret < 0) {
        fprintf(stderr, "Failed to bind to %s\n", url);
        return 1;
    }
    
    ret = srt_listen(sock, 5);
    if (ret < 0) {
        fprintf(stderr, "Failed to listen\n");
        return 1;
    }
    
    SRTSOCKET client = srt_accept(sock, NULL, NULL);
    if (client == SRT_INVALID_SOCK) {
        fprintf(stderr, "Failed to accept connection\n");
        return 1;
    }
    
    char buffer[1024];
    int len = sizeof(buffer);
    ret = srt_recv(client, (unsigned char *)buffer, len, 0);
    if (ret > 0) {
        buffer[ret] = '\0';
        printf("Received: %s\n", buffer);
    } else {
        fprintf(stderr, "Failed to receive data\n");
        return 1;
    }
    
    srt_close(client);
    srt_close(sock);
    
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2107676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣: 有效的字母异位词

文章目录 需求数组map结尾 需求 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 字母异位词 是通过重新排列不同单词或短语的字母而形成的单词或短语&#xff0c;通常只使用所有原始字母一次。 示例 1: 输入: s “anagram”, t “nagaram…

9、类和对象

9.1 封装 9.1.1 封装的例子 class Student { public:string name;int age; public:void setName(string name_) {name name_;} }; int main() {Student s1;s1.setName("zhangsan");return 0; }类中的行为都叫做成员&#xff0c;例如成员属性&#xff0c;成员变量&…

磁吸轨道灯的优缺点深度解析:为你的家居照明提供新选择

在现代家居装修中&#xff0c;照明设计已成为提升居住品质的重要一环。磁吸轨道灯作为一种新兴的照明解决方案&#xff0c;以其独特的灵活性和美观性逐渐受到市场的青睐。然而&#xff0c;任何产品都有其两面性&#xff0c;磁吸轨道灯也不例外。本文将深入探讨磁吸轨道灯的优缺…

产品起名|给你的产品插上会飞的翅膀

引言&#xff1a;在品牌的世界里&#xff0c;产品的名字不仅仅是一个标签&#xff0c;它是品牌个性、价值和承诺的直接体现。一个好的产品名能够快速传达产品特性&#xff0c;吸引消费者&#xff0c;并在市场中建立独特的品牌形象。 好产品从起名开始 品牌介绍&#xff1a;南京…

使用卫星仿真软件STK的一些应用和思考(星地链路、星间链路)

目录 任务描述利用STK建模星地协同系统3个GEO高轨卫星240/20/1 Walker-Star Constellation 低轨卫星星座地面站或者地面设备 链路建模与数据提取处理星地链路星间链路数据读取的几种方法最麻烦的方法使用Matlab与STK互联接口使用大规模使用Chain 总结 任务描述 在一个星地协同…

【小设计】基于宏实现的C++ 可复用setter 和getter设计

前言 最近在开发unity游戏的时候&#xff0c;面对庞大复杂的不同类之间进行数据交换和调用&#xff0c;我们必须做好类数据的信息管理&#xff0c;往往我希望暴露给其他类越少越好&#xff0c;这时候我就利用了C#的一个语言特性 public PlayerStateMachine stateMachine{get;…

创建锁对象/函数

描述&#xff1a;某些单据进行修改时&#xff0c;需要锁定数据 方法步骤&#xff1a; 1、se11&#xff1a;可copy创建新锁 EZSDDH 2、输入需要锁定的主表&#xff0c;锁参数会根据主键自动补填 3、激活后&#xff0c;会生成对应的锁函数 ENQUEUE_EZSDDH &#xff1a;锁定表 …

评论的组件封装

主评论的人在数组第一层级&#xff0c;回复的评论都在children里面 【{ name:"张三" idGenerator: 475403892531269 info_Conmment":"今天天气晴朗&#x1f600;" children:[ { mainIdGenerator:475388950118469 name:"张三" name1&#x…

Java 入门指南:Java 并发编程 —— 并发容器 BlockingDeque、LinkedBlockingDeque

BlockingQueue BlockingQueue 是Java并发包&#xff08;java.util.concurrent&#xff09;中提供的一个阻塞队列接口&#xff0c;它继承自 Queue 接口。 BlockingQueue 中的元素采用 FIFO 的原则&#xff0c;支持多线程环境并发访问&#xff0c;提供了阻塞读取和写入的操作&a…

Jenkins构建CI/CD

CI/CD 软件开发的连续方法基于自动执行脚本&#xff0c;以最大限度地减少在开发应用程序时引入错误的可能性。从新代码的开发到部署&#xff0c;它们需要较少的人为干预甚至根本不需要干预。 它涉及在每次小迭代中不断构建&#xff0c;测试和部署代码更改&#xff0c;从而减少…

多线程 | synchronized的简单使用

synchronized 关键字是 Java 中解决并发问题的一种常用方法&#xff0c;也是最简单的一种方法&#xff0c;其作用有三个: &#xff08;1&#xff09;互斥性&#xff1a;确保线程互斥的访问同步代码 &#xff08;2&#xff09;可见性&#xff1a;保证共享变量的修改能够及时可见…

UOS系统通过Remmina远程windows系统桌面

windows系统之间可以互相进行远程桌面连接&#xff0c;那么UOS系统是否可以远程到windows系统桌面呢&#xff1f;请见下面的文章。 下载安装Remmina软件 首先我们需要在UOS系统上面找到应用商店&#xff0c;下载并安装一个Remmina软件 windows系统开启允许远程桌面连接 wind…

记录ssl epoll的tcp socket服务端在客户端断开时崩溃的问题

文章目录 当客户端关闭后&#xff0c;Epoll 的 TCP socket 服务端会收到两次断开事件可能有以下原因及解决方法&#xff1a;原因分析解决方法 问题ssl socket服务端代码出错现象第一次尝试修改正确改法附上客户端代码 记录ssl epoll的tcp socket服务端在客户端断开时接收到多次…

聚铭网络入选“2024年南京市工程研究中心”认定名单

为深入实施创新驱动发展战略&#xff0c;因地制宜发展新质生产力充分发挥工程研究中心对推进产业强市的重要支撑作用&#xff0c;根据《南京市工程研究中心管理办法》&#xff0c;南京市发展和改革委员会于2024年5月组织开展了本年度南京市工程研究中心遴选工作。经企业申报、各…

编译安装调试 scaLapack 和 openmpi 以及 lapack

编译安装调试 scaLapack /home/hipper/ex_scalapack/ mkdir ./lapack mkdir -p ./lapack/local/lib mkdir ./openmpi mkdir ./scalapack 1&#xff0c;编译安装 Lapack 下载代码&#xff1a; cd lapack wget https://github.com/Reference-LAPACK/lapack/archive/refs/tags/…

[全网首发]2024国赛数学建模ABCE题完整思路+py(matlab)代码+成品论文参考+持续更新

AB题详细思路(含问题一问题二模型) CE题问题一代码思路已经写好[pythonmatlab两种都会更新 需要完整版的看这里&#xff1a; 点击链接加入群聊【2024数学建模国赛资料汇总】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&klZncBILk30DuPRI1Bd8X-3Djv7ZVZyAv&…

【非零段划分 / 2】

题目 思路 第一种思路&#xff1a;按照表面题意&#xff0c;枚举p&#xff0c;处理数组后进行计数&#xff1a; 复杂度 ∈ O ( n ⋅ m ) 复杂度 \in O(n \cdot m) 复杂度∈O(n⋅m) 第二种思路&#xff1a;把数组看成一个二维的山形图&#xff0c;先将相邻的水平线段转化成点…

Java核心知识体系-并发与多线程:线程基础

1 先导 Java线程基础主要包含如下知识点&#xff0c;相信我们再面试的过程中&#xff0c;经常会遇到类似的提问。 1、线程有哪几种状态? 线程之间如何转变&#xff1f; 2、线程有哪几种实现方式? 各优缺点&#xff1f; 3、线程的基本操作&#xff08;线程管理机制&#xff…

数据资产入表元年,企业如何抓住数据资产增值的机遇?

近年来&#xff0c;政府将数据要素纳入了经济发展的重要指示性文件当中&#xff0c;希望利用数据驱动。《全国数据资源调查报告&#xff08;2023年&#xff09;》显示&#xff0c;2024年以来不少地方纷纷成立“数据集团”&#xff0c;加快盘活数据资产。作为数字经济时代的首要…

Java | Leetcode Java题解之第389题找不同

题目&#xff1a; 题解&#xff1a; class Solution {public char findTheDifference(String s, String t) {int ret 0;for (int i 0; i < s.length(); i) {ret ^ s.charAt(i);}for (int i 0; i < t.length(); i) {ret ^ t.charAt(i);}return (char) ret;} }