Linux平台如何实现采集音视频数据并注入轻量级RTSP服务?

技术背景

好多开发者,问我们最多的问题是,为什么要设计轻量级RTSP服务?轻量级RTSP服务,和RTSP服务有什么区别?

针对这个问题,我们的回答是:轻量级RTSP服务解决的核心痛点是避免用户或者开发者单独部署RTSP服务或者RTMP服务,RTSP服务,并发或功能相对强大,数据注入模式一般是外部直接推流到RTSP服务(目前大多流媒体服务,以RTMP居多,RTSP的相对较少,或者说,可以商用的RTSP服务,相对较少,音视频数据推送这块,RTMP推送为主,很少有RTSP推流),轻量级RTSP服务,直接部署在数据源测,相当于采集到的屏幕、摄像头、麦克风数据,直接编码注入本地的轻量级RTSP服务,对外提供个可供拉流的RTSP URL,说到这里,轻量级RTSP服务,更像一个IPC摄像头,侧重的不是并发,而是便捷。

设计架构图

Windows、Android、iOS平台的轻量级RTSP服务,不再赘述,之前都有描述,今天介绍的是Linux平台下的轻量级RTSP服务。

和其他平台一样,我们Linux平台依然实现的是本地的音视频数据(如屏幕、摄像头、麦克风),编码打包后,汇聚到内置RTSP服务,对外提供可供拉流的RTSP URL,轻量级RTSP服务,适用于内网环境下,对并发要求不高的场景,支持H.264/H.265,支持RTSP鉴权、单播、组播模式,考虑到单个服务承载能力,我们支持同时创建多个RTSP服务,并支持获取当前RTSP服务会话连接数。

功能设计

  •  [基础功能]支持常规的屏幕、摄像机、音频采集处理等;
  •  [音频格式]AAC;
  •  [视频格式]H.264、H.265;
  •  [协议类型]RTSP;
  •  [传输模式]支持单播和组播模式;
  •  [端口设置]支持RTSP端口设置;
  •  [鉴权设置]支持RTSP鉴权用户名、密码设置;
  •  [获取session连接数]支持获取当前RTSP服务会话连接数;
  •  [多服务支持]支持同时创建多个内置RTSP服务;
  •  [H.265支持]Windows内置rtsp server支持发布H.265视频(64位库);
  •  [RTSP url回调]支持设置后的rtsp url通过event回调到上层。

接口设计

RTSP Server操作接口设计:

		/** nt_linux_smart_publisher_sdk.h* Created by daniusdk.com*//*+++rtsp server操作接口+++*//** 创建一个rtsp server * pRtspServerHandle: rtsp server 句柄* reserve:保留参数传0* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *OpenRtspServer)(NT_PHANDLE pRtspServerHandle, NT_INT32 reserve);/** 设置rtsp server 监听端口, 在StartRtspServer之前必须要设置端口* rtsp_server_handle: rtsp server 句柄* port: 端口号,可以设置为554,或者是1024到65535之间,其他值返回失败* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerPort)(NT_HANDLE rtsp_server_handle, NT_INT32 port);/** 设置rtsp server 鉴权用户名和密码, 这个可以不设置,只有需要鉴权的再设置* rtsp_server_handle: rtsp server 句柄* user_name: 用户名,必须是英文* password:密码,必须是英文* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerUserNamePassword)(NT_HANDLE rtsp_server_handle, NT_PCSTR user_name, NT_PCSTR password);/** 设置rtsp server 组播, 如果server设置成组播就不能单播,组播和单播只能选一个, 一般来说单播网络设备支持的好,wifi组播很多路由器不支持* rtsp_server_handle: rtsp server 句柄* is_multicast: 是否组播, 1为组播, 0为单播, 其他值接口返回错误, 默认是单播* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerMulticast)(NT_HANDLE rtsp_server_handle, NT_INT32 is_multicast);/** 设置rtsp server 组播组播地址 * rtsp_server_handle: rtsp server 句柄* multicast_address: 组播地址* 如果设置的不是组播地址, 将返回错误* 组播地址范围说明: [224.0.0.0, 224.0.0.255] 为组播预留地址, 不能设置. 可设置范围为[224.0.1.0, 239.255.255.255], 其中SSM地址范围为[232.0.0.0, 232.255.255.255]* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerMulticastAddress)(NT_HANDLE rtsp_server_handle, NT_PCSTR multicast_address);/** 获取rtsp server当前的客户会话数, 这个接口必须在StartRtspServer之后再调用* rtsp_server_handle: rtsp server 句柄* session_numbers: 会话数* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *GetRtspServerClientSessionNumbers)(NT_HANDLE rtsp_server_handle, NT_INT32* session_numbers);/** 启动rtsp server* rtsp_server_handle: rtsp server 句柄* reserve: 保留参数传0* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *StartRtspServer)(NT_HANDLE rtsp_server_handle, NT_INT32 reserve);/** 停止rtsp server* rtsp_server_handle: rtsp server 句柄* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *StopRtspServer)(NT_HANDLE rtsp_server_handle);/** 关闭rtsp server* 调用这个接口之后rtsp_server_handle失效,* 成功返回 NT_ERC_OK*/NT_UINT32 (NT_API *CloseRtspServer)(NT_HANDLE rtsp_server_handle);/*---rtsp server操作接口---*/

发布RTSP流相关接口设计:

		/** nt_linux_smart_publisher_sdk.h* Created by daniusdk.com*//*+++发布rtsp流相关接口+++*//** 设置rtsp的流名称* stream_name: 流程名称,不能为空字符串,必须是英文* 这个作用是: 比如rtsp的url是:rtsp://192.168.0.111/test, test就是设置下去的stream_name* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspStreamName)(NT_HANDLE handle, NT_PCSTR stream_name);/** 给要发布的rtsp流设置rtsp server, 一个流可以发布到多个rtsp server上,rtsp server的创建启动请参考OpenRtspServer和StartRtspServer接口* handle: 推送实例句柄* rtsp_server_handle:rtsp server句柄 * reserve: 保留参数,传0*/NT_UINT32(NT_API *AddRtspStreamServer)(NT_HANDLE handle, NT_HANDLE rtsp_server_handle, NT_INT32 reserve);/** 清除设置的rtsp server*/NT_UINT32(NT_API *ClearRtspStreamServer)(NT_HANDLE handle);/*启动rtsp流reserve: 保留参数,传0*/NT_UINT32(NT_API *StartRtspStream)(NT_HANDLE handle, NT_INT32 reserve);/*停止rtsp流*/NT_UINT32(NT_API *StopRtspStream)(NT_HANDLE handle);/*---发布rtsp流相关接口---*/

调用实现

启动RTSP Server:

	NT_HANDLE start_rtsp_server(NT_SmartPublisherSDKAPI* push_api, int port, std::string user_name, std::string password) {NT_HANDLE rtsp_server_handle = nullptr;if (NT_ERC_OK != push_api->OpenRtspServer(&rtsp_server_handle, 0)) {fprintf(stderr, "OpenRtspServer failed\n");return nullptr;}if (nullptr == rtsp_server_handle) {fprintf(stderr, "rtsp_server_handle is null\n");return nullptr;}if (NT_ERC_OK != push_api->SetRtspServerPort(rtsp_server_handle, port)) {push_api->CloseRtspServer(rtsp_server_handle);return nullptr;}if (!user_name.empty() && !password.empty())push_api->SetRtspServerUserNamePassword(rtsp_server_handle, user_name.c_str(), password.c_str());if (NT_ERC_OK == push_api->StartRtspServer(rtsp_server_handle, 0))return rtsp_server_handle;fprintf(stderr, "StartRtspServer failed\n");push_api->CloseRtspServer(rtsp_server_handle);return nullptr;}

停止RTSP Server:

	void stop_rtsp_server(NT_SmartPublisherSDKAPI* push_api, NT_HANDLE& rtsp_server_handle) {if (nullptr == rtsp_server_handle)return;NT_HANDLE handle = rtsp_server_handle;rtsp_server_handle = nullptr;push_api->StopRtspServer(handle);push_api->CloseRtspServer(handle);}

开始发布RTSP Stream:

	bool start_rtsp_stream(NT_SmartPublisherSDKAPI* push_api, NT_HANDLE rtsp_server_handle, NT_HANDLE handle, const std::string stream_name) {push_api->SetRtspStreamName(handle, stream_name.c_str());push_api->ClearRtspStreamServer(handle);push_api->AddRtspStreamServer(handle, rtsp_server_handle, 0);if (NT_ERC_OK != push_api->StartRtspStream(handle, 0))return false;return true;}

如需停止RTSP流的发布,直接调用:

	stop_rtsp_server(&push_api, rtsp_server_handle);

如果需要采集到的音视频数据预览,调用预览接口即可:

	// 开启预览,也可以不开启, 根据需求来push_api.SetPreviewXWindow(push_handle, "", sub_wid);push_api.StartPreview(push_handle, 0, nullptr);

总结

轻量级RTSP服务,并发这块不是强项,不过确实解决了单独部署RTSP或RTMP服务的痛点,减少了工程实施成本,在并发量要求不高的场景下,非常方便。

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

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

相关文章

dll修复精灵,dll修复工具下载方法分享,mfc140u.dll缺失损坏一键修复

今天,我将为大家分享一个关于mfc140u.dll的问题。首先,我想问一下在座的网友们,有多少人知道mfc140u.dll是什么?又有多少人知道它的作用以及如何解决这个问题呢?在接下来的演讲中,我将详细介绍mfc140u.dll的…

C#使用proto

写多了go代码,被go mod tidy惯坏了,还以为全天下的都很好用呢,结果发现并不是这样。尤其是项目组的proto还是又封了个工具直接就能跑得,导致以为没那么复杂的事情变得复杂了起来。是有两套生成的规则,时间有点晚&#…

虹科分享 | 解决外科医生的担忧:AR让技术自己开口说话

在手术室中,分心可能导致严重错误和伤害,这凸显了在手术过程中减少对外科医生干扰的重要性。对于外科医生来说,在长时间的手术过程中,引入新技术设备时需要考虑多种因素。根据Vuzix对500多名外科医生的综合调查显示,使…

LeetCode 865. Smallest Subtree with all the Deepest Nodes【树,DFS,BFS,哈希表】1534

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

机械零件保养3d模拟演示打消客户购买顾虑

复杂机械的工作运转是复杂的,想要对机械有深度的理解和迭代,必须了解它的运转原理及参数,复杂机械运行原因教学存在着不可视、系统庞杂及知识点多等弊病,3D虚拟展示是基于web3d网页运行的三维页面,可以将复杂机械运行过…

Java复习-20-接口(3)- 代理设计模式

代理设计模式(Proxy) 功能:可以帮助用户将所有的开发注意力只集中在核心业务功能的处理上。 代理模式(Proxy Pattern)是一种结构性模式。代理模式为一个对象提供了一个替身,以控制对这个对象的访问。即通过代理对象访问目标目标对象,可以在目…

uni-app开发小程序时ucharts图表如何使用

在此不会具体告诉大家怎么做,我只告诉大家方法: 第一步,推荐使用组件方法进行绘图,首先去官网下载这个ucharts的插件: 秋云 ucharts echarts 高性能跨全端图表组件 - DCloud 插件市场 下载完毕导入到所需要用到的项目…

数据结构与算法基础-学习-33-归并排序

目录 一、基本思想 二、算法思路 1、合并两个有序序列 2、分治法 三、算法源码 1、MergeSortTwoSortData 2、TwoWayMergeSortRecurtionSentryQueue 四、算法效率分析 五、Linux环境编译测试 六、小感慨 排序的其他相关知识点和源码分享可以参考之前的博客&#xff1a…

Docker入门,Docker是什么?有什么用?该怎么用?

目录 1. 项目部署时的复杂性? 2. Docker是如何解决依赖兼容问题的? 3. 众多Linux操作系统发行版的区别 4. Docker 是如何实现跨系统运行的? 5. Docker与虚拟机的差别 6. 镜像(Image)与容器(Container) 7. DockerHub 8. Docker 架构 …

安防监控/视频汇聚/云存储/AI智能视频分析平台EasyCVR显示CPU过载,该如何解决?

视频云存储/安防监控/视频汇聚平台EasyCVR基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防视频监控系统EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、云…

Java知识总结(持续更新)

一、JDK、JRE、JVM三者之间的关系? 1. **JDK (Java Development Kit)**: JDK 是 Java 开发工具包,它包含了用于开发 Java 应用程序的所有必要工具和库。这包括 Java 编译器(javac)、Java 核心类库、开发工具&#x…

《React vs. Vue vs. Angular:2023年的全面比较》

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

【LeetCode-简单题】844. 比较含退格的字符串

文章目录 题目方法一:单指针方法二:双指针方法三:栈 题目 方法一:单指针 首先每次进入循环处理之前需要对第一个字符进行判断,若是退格符,直接删掉,结束此次循环fast从0开始,如果fa…

每日一练 | 网络工程师软考真题Day32

阅读以下说明,答复以下【问题1】至【问题5】 【说明】 某公司内部效劳器S1部署了重要的应用,该应用只允许特权终端PC1访问,如图4-1所示。为保证通信平安,需要在S1上配置相应的IPSec策略。综合考虑后,确定该IPSec策略如…

pdf.js 微信公众号不显示问题

问题1: 在浏览器中能够正常显示, 但是在微信浏览器中不行!解决: 这个是pdf.js 版本问题, 用2.4版本,微信打开就没问题了 问题2: 如何关闭侧边栏? 修改这个地方, 将 -1 改…

QLineEdit 类(行编辑器)

1、 QLineEdit 类是 QWidget 类的直接子类,该类实现了一个单行的输入部件,即行编辑器; 2、验证器(QValidator 类)和输入掩码简介:主要作用是验证用户输入的字符是否符合验证器 的要求,即限制对用户的输入,比…

发UPS国际快递到墨西哥的收费标准

UPS国际快递是目前全球范围内最为知名和可靠的快递服务提供商之一,无论是个人还是企业都可以通过UPS将包裹快速送达世界各地,其中包括墨西哥。所以,对于许多人来说,了解到发UPS国际快递到墨西哥的收费标准是十分重要的。 发UPS国际…

Linux常见进程类别

目录 常见进程类别 守护进程&精灵进程 任务管理 进程组 作业 作业 | 进程组 会话 w命令 守护进程 守护进程的创建 setsid()函数 daemon()函数 模拟实现daemon函数 前台进程 | 后台进程 僵尸进程 | 孤儿进程 僵尸进程的一些细节 守护进程 | 后台进程 守护…

C++-map和set

本期我们来学习map和set 目录 关联式容器 键值对 pair 树形结构的关联式容器 set multiset map multimap 关联式容器 我们已经接触过 STL 中的部分容器,比如: vector 、 list 、 deque 、forward_list(C11)等,这些容器统称为序列式…

关于软件的功能复用

有一些人总在说软件要复用,开发一个项目时要想想怎么在另一个项目中能重用。你问他怎么做到复用,就会听到微服务、中台一些名词 复用的层次 说到复用,首先要想明白复用的是啥 级别越低,粒度越小,复用的范围越广&#…