如何在Unity下采集音视频实现轻量级RTSP服务(类似于IPC)

好多开发者在做虚拟仿真、VR教育等场景的时候,遇到个问题,想把头显里面的画面在内网环境下低延迟的同步出来,又不想单独部署流媒体服务器。为此,我们在Unity下,添加了轻量级RTSP服务模块,通过头显端启动个轻量级RTSP服务,把采集到的音视频数据,通过对外提供RTSP拉流URL的形式,供内网其他终端调用,废话不多说,先上图看效果:

 上图展示的是,Android的Unity下Camera场景获取到texture数据编码后,注入RTSP服务和RTMP推送模块。二者可以单独使用,也可同时使用,相互不影响。其中轻量级RTSP服务,可实时查看链接的RTSP会话数。

由于我们原生Android平台轻量级RTSP服务已经有多年积累,本次只是把相关的接口,同步过来。

首先来看RTSP Server相关的接口设计:

  /** SmartPublisherAndroidMono.cs** Github: https://github.com/daniulive/SmarterStreaming*//*+++++++++++++++SmartRTSPServerSDK+++++++++++++++*//// <summary>/// Init rtsp server(和UnInitRtspServer配对使用,即便是启动多个RTSP服务,也只需调用一次InitRtspServer,请确保在OpenRtspServer之前调用)/// </summary>public int NT_PB_U3D_InitRtspServer(){return pusher_obj_.Call<int>("InitRtspServer");}/// <summary>/// 创建一个rtsp server/// </summary>public long NT_PB_U3D_OpenRtspServer(int reserve){return pusher_obj_.Call<long>("OpenRtspServer", reserve);}/// <summary>/// 设置rtsp server 监听端口, 在StartRtspServer之前必须要设置端口/// @param rtsp_server_handle: rtsp server 句柄/// @param port: 端口号,可以设置为554,或者是1024到65535之间,其他值返回失败/// </summary>public int NT_PB_U3D_SetRtspServerPort(long rtsp_server_handle, int port){return pusher_obj_.Call<int>("SetRtspServerPort", rtsp_server_handle, port);}/// <summary>/// 设置rtsp server 鉴权用户名和密码, 这个可以不设置,只有需要鉴权的再设置/// @param rtsp_server_handle: rtsp server 句柄/// @param user_name: 用户名(必须是英文), password:密码(必须是英文)/// </summary>public int NT_PB_U3D_SetRtspServerUserNamePassword(long rtsp_server_handle, String user_name, String password){return pusher_obj_.Call<int>("SetRtspServerUserNamePassword", rtsp_server_handle, user_name, password);}/// <summary>/// 设置rtsp server 组播, 如果server设置成组播就不能单播,组播和单播只能选一个, 一般来说单播网络设备支持的好,wifi组播很多路由器不支持/// @param rtsp_server_handle: rtsp server 句柄/// @param is_multicast: 是否组播, 1为组播, 0为单播, 其他值接口返回错误, 默认是单播/// </summary>public int NT_PB_U3D_SetRtspServerMulticast(long rtsp_server_handle, int is_multicast){return pusher_obj_.Call<int>("SetRtspServerMulticast", rtsp_server_handle, is_multicast);}/// <summary>/// 设置rtsp server 组播组播地址/// @param rtsp_server_handle: rtsp server 句柄/// 如果设置的不是组播地址, 将返回错误/// 组播地址范围说明: [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]/// </summary>public int NT_PB_U3D_SetRtspServerMulticastAddress(long rtsp_server_handle, String multicast_address){return pusher_obj_.Call<int>("SetRtspServerMulticastAddress", rtsp_server_handle, multicast_address);}/// <summary>/// 获取rtsp server当前的客户会话数, 这个接口必须在StartRtspServer之后再调用/// @param rtsp_server_handle: rtsp server 句柄/// @return {当前rtsp server会话数}/// </summary>public int NT_PB_U3D_GetRtspServerClientSessionNumbers(long rtsp_server_handle){return pusher_obj_.Call<int>("GetRtspServerClientSessionNumbers", rtsp_server_handle);}/// <summary>/// 启动rtsp server/// @param rtsp_server_handle: rtsp server 句柄/// @param reserve: 保留参数传0/// </summary>public int NT_PB_U3D_StartRtspServer(long rtsp_server_handle, int reserve){return pusher_obj_.Call<int>("StartRtspServer", rtsp_server_handle, reserve);}/// <summary>/// 停止rtsp server/// @param rtsp_server_handle: rtsp server 句柄/// </summary>public int NT_PB_U3D_StopRtspServer(long rtsp_server_handle){return pusher_obj_.Call<int>("StopRtspServer", rtsp_server_handle);}/// <summary>/// 关闭rtsp server/// @param rtsp_server_handle: rtsp server 句柄/// NOTE: 调用这个接口之后rtsp_server_handle失效,/// </summary>public int NT_PB_U3D_CloseRtspServer(long rtsp_server_handle){return pusher_obj_.Call<int>("CloseRtspServer", rtsp_server_handle);}/// <summary>/// UnInit rtsp server(和InitRtspServer配对使用,即便是启动多个RTSP服务,也只需调用一次UnInitRtspServer)/// </summary>public int NT_PB_U3D_UnInitRtspServer(){return pusher_obj_.Call<int>("UnInitRtspServer");}/*---------------SmartRTSPServerSDK---------------*/

其次是,用于publisher实例操作的接口,把publisher实例和rtsp实例串起来:

    /*+++++++++++++++SmartRTSPServerSDK供Publisher调用的接口+++++++++++++++*//// <summary>/// 设置rtsp的流名称/// @param handle: 推送实例句柄/// @param stream_name: 流程名称,不能为空字符串,必须是英文/// 这个作用是: 比如rtsp的url是:rtsp://192.168.0.111/test, test就是设置下去的stream_name/// </summary>public int NT_PB_U3D_SetRtspStreamName(long handle, String stream_name){return pusher_obj_.Call<int>("SetRtspStreamName", handle, stream_name);}/// <summary>/// 给要发布的rtsp流设置rtsp server, 一个流可以发布到多个rtsp server上,rtsp server的创建启动请参考OpenRtspServer和StartRtspServer接口/// @param handle: 推送实例句柄/// @param rtsp_server_handle:rtsp server句柄/// @param reserve:保留参数,传0/// </summary>public int NT_PB_U3D_AddRtspStreamServer(long handle, long rtsp_server_handle, int reserve){return pusher_obj_.Call<int>("AddRtspStreamServer", handle, rtsp_server_handle, reserve);}/// <summary>/// 清除设置的rtsp server/// @param handle: 推送实例句柄/// </summary>public int NT_PB_U3D_ClearRtspStreamServer(long handle){return pusher_obj_.Call<int>("ClearRtspStreamServer", handle);}/// <summary>/// 启动rtsp流/// @param handle: 推送实例句柄/// @param reserve: 保留参数,传0/// </summary>public int NT_PB_U3D_StartRtspStream(long handle, int reserve){return pusher_obj_.Call<int>("StartRtspStream", handle, reserve);}/// <summary>/// 停止rtsp流/// @param handle: 推送实例句柄/// </summary>public int NT_PB_U3D_StopRtspStream(long handle){return pusher_obj_.Call<int>("StopRtspStream", handle);}/*---------------SmartRTSPServerSDK供Publisher调用的接口---------------*/

Unity调用demo如下:

启动、停止轻量级服务:

    private void OnRtspServiceBtnClicked(){if (is_rtsp_service_running_) {StopRtspService();btn_rtsp_service_.GetComponentInChildren<Text>().text = "启动RTSP服务";btn_rtsp_publisher_.GetComponent<Button>().interactable = false;return;}rtsp_handle_ = NT_PB_U3D_OpenRtspServer(0);if (rtsp_handle_ == 0) {Debug.LogError("创建rtsp server实例失败! 请检查SDK有效性");} else {int port = 8554;if (NT_PB_U3D_SetRtspServerPort(rtsp_handle_, port) != 0) {NT_PB_U3D_CloseRtspServer(rtsp_handle_);rtsp_handle_ = 0;Debug.LogError("创建rtsp server端口失败! 请检查端口是否重复或者端口不在范围内!");}if (NT_PB_U3D_StartRtspServer(rtsp_handle_, 0) == DANIULIVE_RETURN_OK) {is_rtsp_service_running_ = true;Debug.Log("启动rtsp server 成功!");} else {NT_PB_U3D_CloseRtspServer(rtsp_handle_);rtsp_handle_ = 0;Debug.LogError("启动rtsp server失败! 请检查设置的端口是否被占用!");}btn_rtsp_service_.GetComponentInChildren<Text>().text = "停止RTSP服务";btn_rtsp_publisher_.GetComponent<Button>().interactable = true;}}

服务启动后,可以发布或停止RTSP流:

    private void OnRtspPublisherBtnClicked(){if (is_rtsp_publisher_running_) {StopRtspPublisher();if (!is_pushing_rtmp_){StopCaptureAvData();if (coroutine_ != null) {StopCoroutine(coroutine_);coroutine_ = null;}}btn_rtsp_publisher_.GetComponentInChildren<Text>().text = "发布RTSP流";btn_get_rtsp_session_numbers_.GetComponentInChildren<Text>().text = "RTSP会话数";btn_get_rtsp_session_numbers_.GetComponent<Button>().interactable = false;btn_rtsp_service_.GetComponent<Button>().interactable = true;input_url_.GetComponentInChildren<Text>().text = "";}else{bool is_started = StartRtspPublisher();if(is_started){btn_rtsp_publisher_.GetComponentInChildren<Text>().text = "停止RTSP流";btn_get_rtsp_session_numbers_.GetComponent<Button>().interactable = true;btn_rtsp_service_.GetComponent<Button>().interactable = false;if(!is_pushing_rtmp_){StartCaptureAvData();coroutine_ = StartCoroutine(OnPostVideo());}}}}

发布RTSP流:

    private bool StartRtspPublisher(){if (is_rtsp_publisher_running_){Debug.Log("已推送..");   return false;}if (!is_pushing_rtmp_) {InitAndSetConfig();}if (pusher_handle_ == 0) {Debug.LogError("Start rtsp publisher, pusher handle is null..");return false;}String rtsp_stream_name = "stream1";NT_PB_U3D_SetRtspStreamName(pusher_handle_, rtsp_stream_name);NT_PB_U3D_ClearRtspStreamServer(pusher_handle_);NT_PB_U3D_AddRtspStreamServer(pusher_handle_, rtsp_handle_, 0);int is_suc = NT_PB_U3D_StartRtspStream(pusher_handle_, 0);if (is_suc == DANIULIVE_RETURN_OK){Debug.Log("StartRtspStream success..");is_rtsp_publisher_running_ = true;}else{Debug.LogError("StartRtspStream failed!");return false;}return true;}

停止发布RTSP流:

    //停止发布RTSP流private void StopRtspPublisher() {if(!is_rtsp_publisher_running_)return;NT_PB_U3D_StopRtspStream(pusher_handle_);if(!is_pushing_rtmp_){NT_PB_U3D_Close(pusher_handle_);pusher_handle_ = 0;NT_PB_U3D_UnInit();}is_rtsp_publisher_running_ = false;}

发布RTSP流后,我们可以实时获取到链接的RTSP会话数:

    private void OnGetRtspSessionNumbersBtnClicked(){if (rtsp_handle_ != 0) {int session_numbers = NT_PB_U3D_GetRtspServerClientSessionNumbers(rtsp_handle_);Debug.Log("GetRtspSessionNumbers: " + session_numbers);btn_get_rtsp_session_numbers_.GetComponentInChildren<Text>().text = "RTSP会话数:" + session_numbers.ToString();}}

轻量级RTSP服务,由于不需要单独部署流媒体服务器,在内网小并发场景下,使用起来非常方便,感兴趣的开发者可酌情参考。

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

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

相关文章

【Datawhale 大模型基础】第十一章 环境影响

第十一章 环境影响 This blog is based on datawhale files and a paper. The initial consideration revolves around the potential positive or negative direct impact on the environment. Other transformative technological advancements, like the metaverse, are li…

Android GB28181接入端实时位置订阅和上报之-如何获取当前经纬度

我们在做Android平台GB28181的时候&#xff0c;其中实时位置(MobilePosition)订阅和上报这块&#xff0c;涉及到实时经纬度的获取&#xff0c;特别是执法记录、车载系统的那个等场景&#xff0c;几乎就是标配。 今天主要是分享一段实时获取位置的代码&#xff1a; /** Camera…

如何实现Android平台GB28181设备对接Camera2数据

技术背景 在写如何实现Android平台GB28181设备对接Camera2数据说明之前&#xff0c;我在前两年的blog就有针对camera2的RTMP直播推送模块做过技术分享&#xff1a; 在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用…

Android平台GB28181设备接入端本地SIP端口被占用或屏蔽怎么办?

好多开发者或厂商&#xff0c;对Android平台GB28181接入模块的定位&#xff0c;大多是IPC国标流程打通模拟&#xff0c;基于这个目的&#xff0c;很难按照标准SPEC规范实现Android平台GB28181设备接入&#xff0c;我们在跟第三方国标平台厂商对接时发现&#xff0c;部分公司&am…

Android平台GB28181设备接入端如何实现本地录像?

实现Android平台GB28181设备接入的时候&#xff0c;有个功能点不可避免&#xff0c;那就是本地录像&#xff0c;实际上&#xff0c;在实现GB28181设备接入模块之前&#xff0c;我们前些年做RTMP推送和轻量级RTSP服务的时候&#xff0c;早已经实现了本地录像功能。 本地录像功能…

国网B接口注册(REGISTER)接口描述和消息示例

技术背景 电网视频监控系统是智能电网的一个重要组成部分&#xff0c;广泛应用于电网的建设、生产、运行、经营等方面。由于视频监控系统在不同的建设时期选用了不同的技术和不同厂家的产品&#xff0c;导致了标准不统一、技术路线不一致。目前国家电网公司智能电网建设&#…

国网B接口资源上报(Push_Resourse)接口描述和消息示例

上篇blog&#xff0c;梳理了国网B接口的REGISTER接口描述和消息示例&#xff0c;前端系统加电启动并初次注册成功后&#xff0c;向平台上报前端系统的设备资源信息&#xff08;包括&#xff1a;视频服务器、DVR/DVS、摄像机、告警设备、环境量采集设备等模拟或数字信号采集设备…

Android平台GB28181设备接入端语音广播如何实现实时音量调节

Android平台GB28181设备接入&#xff0c;语音广播功能非常重要&#xff0c;本文要介绍的&#xff0c;不是语音广播的流程&#xff0c;语音广播流程&#xff0c;之前的blog也有非常详细的分享&#xff0c;感兴趣的可以参考官方规范书的交互流程&#xff1a; 语音广播这块&#x…

GB28181基于TCP协议的视音频媒体传输探究及实现

我们先看看官方规范针对TCP协议的视音频传输描述&#xff1a; 实时视频点播、历史视频回放与下载的 TCP媒体传输应支持基于RTP封装的视音频PS流&#xff0c;封装格式参照IETFRFC4571。 流媒体服务器宜同时支持作为TCP媒体流传输服务端和客户端。默认情况下&#xff0c;前端设…

Android平台GB28181接入端如何对接UVC摄像头?

我们在对接Android平台GB28181接入的时候&#xff0c;有公司提出这样的需求&#xff0c;除了采集执法记录仪摄像头自带的数据外&#xff0c;还想通过执法记录仪采集外接UVC摄像头。 实际上&#xff0c;这块对我们来说有点炒冷饭了&#xff0c;不算新的诉求。​大牛直播SDK​在2…

Android平台实现系统内录(捕获播放的音频)并推送RTMP服务技术方案探究

几年来&#xff0c;我们在做无纸化同屏或在线教育相关场景的时候&#xff0c;总是被一件事情困扰&#xff1a;如何实现Android平台的系统内录&#xff0c;并推送到其他播放端&#xff0c;常用的场景比如做无纸化会议或教育的时候&#xff0c;主讲人或老师需要放一个视频&#x…

Android平台GB28181设备接入端PTZ对接详解

PTZCmd实现背景 上一篇blog“Android平台GB28181设备接入模块之球机/云台控制探究”谈到&#xff0c;Android平台做国标GB28181设备接入端的时候&#xff0c;PTZ控制要不要处理&#xff1f;如果处理&#xff0c;难度大不大&#xff1f; 首先说要不要处理&#xff1a;如果只是…

Android平台GB28181设备接入模块摄像头采集方向不对怎么办?

背景 我们在做Android平台GB28181设备接入模块的时候&#xff0c;有开发者提到这样的诉求&#xff1a;他们的智能头盔、执法记录仪等设备&#xff0c;采集到的图像&#xff0c;是旋转了90、180甚至270的&#xff0c;设备本身无法针对图像做翻转或者旋转操作&#xff0c;问我们…

Android平台GB28181设备接入模块分辨率发生变化怎么办?

技术背景 我们在做Android平台gb28181设备接入模块的时候&#xff0c;遇到这样的情况&#xff0c;比如横竖屏分辨率不锁定&#xff0c;采集摄像头的时候&#xff0c;可以实现&#xff0c;横屏状态采集横屏&#xff0c;竖屏状态采集竖屏&#xff0c;简单来说&#xff0c;横屏状…

RTSP、RTMP播放器拉到的视频图像角度不对怎么办?

我们在做RTSP、RTMP播放器的时候&#xff0c;遇到这样的诉求&#xff1a;特别是RTSP&#xff0c;有些摄像头安装可能倒置或者旋转了90亦或270&#xff0c;拉取到图像&#xff0c;势必需要对视频图像做一定的处理&#xff0c;确保显示正常。 为此&#xff0c;我们提供了以下接口…

Android平台GB28181设备接入端如何调节实时音量?

我们在对接Android平台GB28181设备接入端的时候&#xff0c;有开发者提出这样的疑惑&#xff0c;如何调整设备接入端的实时音量&#xff1f; 实际上&#xff0c;这块我们前几年在做RTMP直播推送模块的时候&#xff0c;已经发布了相关的接口&#xff0c;这里再回顾下&#xff1…

【技术分享】如何实现功能完备性能优异的RTMP、RTSP播放器?

技术背景 这几年&#xff0c;我们对接了太多有RTSP或RTMP直播播放器诉求的开发者&#xff0c;他们当中除了寻求完整的解决方案的&#xff0c;还有些是技术探讨&#xff0c;希望能借鉴我们播放端的开发思路或功能特性&#xff0c;完善自己的产品。 忙里偷闲&#xff0c;今天我…

我正在参加2022年度博客之星评选,大家帮我点个五星好评

大家好&#xff0c;我是音视频牛哥&#xff0c;致力于跨平台的实时RTMP推流、转发、RTMP/RTSP直播播放、GB28181设备接入。 有幸参加2022年度博客之星评选&#xff0c;欢迎大家帮点五星好评。如果我的博客能给开发者带来哪怕一丝启发&#xff0c;对博主来说&#xff0c;也甚感…

rtmp/rtsp/hls公网真正可用的测试地址

相信大家在调试播放器的时候&#xff0c;都有这样的困惑&#xff0c;很难找到合适的公有测试源&#xff0c;以下是大牛直播SDK&#xff08;GitHub地址&#xff09;整理的真正可用的直播地址源。 其中&#xff0c;rtmp和rtsp的url&#xff0c;用我们播放器验证通过。 1. rtmp:…

公网可用的RTMP、RTSP测试地址(更新于2021年3月)

好多博客提到的公网可测试的RTSP和RTMP URL大多都不用了&#xff0c;以下是大牛直播SDK(Github)于2021年3月亲测可用的几个URL&#xff0c;有其他可用的URL&#xff0c;也欢迎大家在评论区回复。 RTMP流地址 湖南卫视&#xff1a;rtmp://58.200.131.2:1935/livetv/hunantv (7…