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

Windows平台Unity Camera场景实现轻量级RTSP服务和RTMP推送

技术背景

随着VR技术在医疗、军事、农业、学校、景区、消防、公共安全、研学机构、展厅展馆,商场等场所普及,开发者对Unity平台下的直播体验提出了更高的要求。

技术实现

Unity平台下的RTMP推流、RTMP、RTSP播放前几年已经覆盖了Windows、Linux、Android、iOS平台。本文主要介绍Windows平台Unity环境下的轻量级RTSP服务。通过对外提供RTSP拉流URL的形式,供内网其他终端调用。

RTMP的技术方案,我们之前有探讨过,这里先说轻量级RTSP服务,轻量级RTSP服务,我们的设计是,可以启动一个RTSP Service,然后发布多个RTSP流实例,这个在多实例的设计,非常有价值,简单来说,一个RTSP Service下面挂载多个RTSP Stream,对外提供RTSP拉流的URL,整体设计方案如下:

我们看看支持的音视频采集选项,其中视频这块,除了Unity下的Camera场景覆盖,还有Windows摄像头、屏幕数据,音频采集覆盖了Unity声音、扬声器、麦克风,还有混音数据。

音视频原始数据采集到后,编码注入RTSP服务和RTMP推送模块。二者可以单独使用,也可同时使用。其中轻量级RTSP服务,可实时查看链接的RTSP会话数。

首先看启动RTSP service封装:

/** PublisherWrapper.cs* Author: daniusdk.com*/
public bool StartRtspService()
{if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_OpenRtspServer(ref rtsp_handle_, 0)){Debug.LogError("创建rtsp server实例失败! 请检查sdk有效性.");return false;}if (IntPtr.Zero == rtsp_handle_){Debug.LogError("创建rtsp server实例失败! 请检查sdk有效性.");return false;}int port = 28554;if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_SetRtspServerPort(rtsp_handle_, port)){NTSmartPublisherSDK.NT_PB_CloseRtspServer(rtsp_handle_);rtsp_handle_ = IntPtr.Zero;Debug.LogError("设置rtsp server端口失败,请检查端口是否重复或者端口不在范围内!");return false;}//String user_name = "admin";//String password = "123456";//NTSmartPublisherSDK.NT_PB_SetRtspServerUserNamePassword(rtsp_handle, user_name, password);if (NTBaseCodeDefine.NT_ERC_OK == NTSmartPublisherSDK.NT_PB_StartRtspServer(rtsp_handle_, 0)){Debug.Log("StartRtspServer suc..");}else{NTSmartPublisherSDK.NT_PB_CloseRtspServer(rtsp_handle_);rtsp_handle_ = IntPtr.Zero;Debug.LogError("启动rtsp server失败, 请检查设置的端口是否被占用!");return false;}is_rtsp_service_running_ = true;return true;
}

停止RTSP Service:

public void StopRtspService()
{if (is_rtsp_service_running_ == false) return;NTSmartPublisherSDK.NT_PB_StopRtspServer(rtsp_handle_);NTSmartPublisherSDK.NT_PB_CloseRtspServer(rtsp_handle_);rtsp_handle_ = IntPtr.Zero;is_rtsp_service_running_ = false;
}

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

public bool StartRtspStream()
{if (CheckPublisherHandleAvailable() == false) return false;if (publisher_handle_ == IntPtr.Zero){return false;}if (publisher_handle_count_ < 1){SetCommonOptionToPublisherSDK();}String rtsp_stream_name = "stream1";NTSmartPublisherSDK.NT_PB_SetRtspStreamName(publisher_handle_, rtsp_stream_name);NTSmartPublisherSDK.NT_PB_ClearRtspStreamServer(publisher_handle_);NTSmartPublisherSDK.NT_PB_AddRtspStreamServer(publisher_handle_, rtsp_handle_, 0);if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartRtspStream(publisher_handle_, 0)){if (0 == publisher_handle_count_){NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);publisher_handle_ = IntPtr.Zero;}Debug.LogError("调用发布rtsp流接口失败");return false;}publisher_handle_count_++;is_rtsp_publisher_running_ = true;return true;
}

停止RTSP流:

public void StopRtspStream()
{publisher_handle_count_--;NTSmartPublisherSDK.NT_PB_StopRtspStream(publisher_handle_);if (0 == publisher_handle_count_){NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);publisher_handle_ = IntPtr.Zero;}is_rtsp_publisher_running_ = false;
}

获取RTSP session连接数:

public int GetRtspSessionNumbers()
{int num = 0;if (rtsp_handle_!=IntPtr.Zero){if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_GetRtspServerClientSessionNumbers(rtsp_handle_, ref num)){Debug.LogError("Call NT_PB_GetRtspServerClientSessionNumbers failed..");}}return num;
}

封装部分看过后,我们看看我们Unity下调用示例:

启动、停止RTSP服务:

public void btn_rtsp_service_Click()
{if (publisher_wrapper_.IsRtspServiceRunning()){publisher_wrapper_.StopRtspService();btn_rtsp_service_.GetComponentInChildren<Text>().text = "启动RTSP服务";btn_rtsp_publisher_.interactable = false;return;}if (!publisher_wrapper_.StartRtspService()){Debug.LogError("调用StartRtspService失败..");return;}btn_rtsp_publisher_.interactable = true;btn_rtsp_service_.GetComponentInChildren<Text>().text = "停止RTSP服务";
}

发布、停止RTSP流:

public void btn_rtsp_publisher_Click()
{if (publisher_wrapper_.IsRtspPublisherRunning()){publisher_wrapper_.StopRtspStream();if (!publisher_wrapper_.IsPreviewing() && !publisher_wrapper_.IsPushingRtmp()){StopCaptureAvData();if (coroutine_ != null){StopCoroutine(coroutine_);coroutine_ = null;}}btn_rtsp_service_.interactable = true;btn_rtsp_publisher_.GetComponentInChildren<Text>().text = "发布RTSP";}else{if (!publisher_wrapper_.IsRtspServiceRunning()){Debug.LogError("RTSP service is not running..");return;}if (!publisher_wrapper_.IsPreviewing() && !publisher_wrapper_.IsPushingRtmp()){publisher_wrapper_.SetVideoPushType(video_push_type_);publisher_wrapper_.SetAudioPushType(audio_push_type_);}publisher_wrapper_.StartRtspStream();if (!publisher_wrapper_.IsPreviewing() && !publisher_wrapper_.IsPushingRtmp()){StartCaptureAvData();coroutine_ = StartCoroutine(OnPostVideo());}btn_rtsp_publisher_.GetComponentInChildren<Text>().text = "停止RTSP";btn_rtsp_service_.interactable = false;}
}

获取RTSP Session链接数:

public void btn_get_rtsp_session_numbers_Click()
{if (publisher_wrapper_.IsRtspServiceRunning()){btn_get_rtsp_session_numbers_.GetComponentInChildren<Text>().text = "RTSP会话数:" + publisher_wrapper_.GetRtspSessionNumbers();}
}

RTMP推送、停止推送:

public void btn_start_rtmp_pusher_Click()
{if (publisher_wrapper_.IsPushingRtmp()){StopPushRTMP();btn_rtmp_pusher_.GetComponentInChildren<Text>().text = "推送RTMP";return;}String url = rtmp_pusher_url_.text;if (url.Length < 8){publisher_wrapper_.Close();Debug.LogError("请输入RTMP推送地址");return;}if (!publisher_wrapper_.IsPreviewing() && !publisher_wrapper_.IsRtspPublisherRunning()){publisher_wrapper_.SetVideoPushType(video_push_type_);publisher_wrapper_.SetAudioPushType(audio_push_type_);}if (!publisher_wrapper_.StartRtmpPusher(url)){Debug.LogError("调用StartPublisher失败..");return;}btn_rtmp_pusher_.GetComponentInChildren<Text>().text = "停止推送";if (!publisher_wrapper_.IsPreviewing() && !publisher_wrapper_.IsRtspPublisherRunning()){StartCaptureAvData();coroutine_ = StartCoroutine(OnPostVideo());}
}

总结

轻量级RTSP服务和RTMP推送的区别在于,轻量级RTSP服务不需要单独部署流媒体服务器(类似于网络摄像头),在内网小并发场景下,使用起来非常方便,如果需要上公网,还是需要用RTMP推送,感兴趣的开发者可酌情参考。

相关文章:

Windows平台Unity Camera场景实现轻量级RTSP服务和RTMP推送

技术背景随着VR技术在医疗、军事、农业、学校、景区、消防、公共安全、研学机构、展厅展馆&#xff0c;商场等场所普及&#xff0c;开发者对Unity平台下的直播体验提出了更高的要求。技术实现Unity平台下的RTMP推流、RTMP、RTSP播放前几年已经覆盖了Windows、Linux、Android、i…...

LSB 题解

今天来刷一道Misc的题目&#xff0c;LSB原理进行图片隐写 LSB原理 LSB是一种利用人类视觉的局限性设计的幻术 PNG和BMP图片中的图像像素一般是由RGB(RED红 GREEN绿 BLUE蓝)三原色组成 记住&#xff0c;JPG图片是不适合使用LSB隐写的&#xff0c;JPG图片对像数进行了有损压缩…...

离线部署docker与镜像

离线部署docker与镜像 1.离线部署docker 1).在docker官网上下载&#xff0c;合适的安装文件 本次使用的是“docker-20.10.9.tgz ” 下载地址&#xff1a;https://download.docker.com/linux/static/stable/x86_64/ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下…...

Linux文件系统介绍(上)

使用 Linux 系统时&#xff0c;需要作出的决策之一就是为存储设备选用什么文件系统。大多数 Linux 发行版在安装时会非常贴心地提供默认的文件系统&#xff0c;大多数入门级用户想都不想就用了默认的那个。 使用默认文件系统未必就不好&#xff0c;但了解一下可用的选择有时也会…...

创建SpringBoot注意事项

作为一个java小白&#xff0c;你是否因为创建SpringBoot项目那些莫名其妙的错误搞得头皮发麻。不要慌张&#xff0c;这篇文章能帮你解决90%的问题【持续更新…】 本文结合创建SpringBoot项目的完整过程来讲 在idea中新建项目 虽然SpringBoot项目是由maven内核组成的&#xff0…...

2023年全国最新二级建造师精选真题及答案9

百分百题库提供二级建造师考试试题、二建考试预测题、二级建造师考试真题、二建证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 11.关于施工合同违约赔偿损失范围的说法&#xff0c;正确的是&#xff08;&#xff09;。 A.…...

解决MySQL的 Row size too large (> 8126).

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;无尽的折腾后&#xff0c;终于又回到…...

最优传输问题和Sinkhorn

最优传输问题 假设有M堆土&#xff0c;每堆土的大小是ama_mam​&#xff0c;有N个坑&#xff0c;每个坑的大小是bnb_nbn​&#xff0c;把单位土从土堆m运送到坑n的代价是c(m,n)c(m,n)c(m,n)&#xff0c;如何找到一种运输方法填满坑&#xff0c;并且代价最小&#xff0c;这就是…...

Netty核心组件EventLoop源码解析

源码解析目标 分析最核心组件EventLoop在Netty运行过程中所参与的事情&#xff0c;以及具体实现 源码解析 依然用netty包example下Echo目录下的案例代码&#xff0c;单我们写一个NettyServer时候&#xff0c;第一句话就是 EventLoopGroup bossGroup new NioEventLoopGroup(…...

排障命令-汇总

目录 日志查询 1. grep 2. zgrep cpu 1. top 内存 1. free tcp相关 1. netstat 2. ulimit 3. lsof jvm常用 1. jps 2. jinfo 3. jstack 4. jmap 5. jstat 进制转换 1. 十进制转16进制 日志查询 1. grep 定义&#xff1a;(global regular expression) 命令用于查…...

python+pytest接口自动化(4)-requests发送get请求

python中用于请求http接口的有自带的urllib和第三方库requests&#xff0c;但 urllib 写法稍微有点繁琐&#xff0c;所以在进行接口自动化测试过程中&#xff0c;一般使用更为简洁且功能强大的 requests 库。下面我们使用 requests 库发送get请求。requests库简介requests 库中…...

开源电子书工具Calibre 6.3 发布

Calibre 开源项目是 Calibre 官方出的电子书管理工具。它可以查看&#xff0c;转换&#xff0c;编辑和分类所有主流格式的电子书。Calibre 是个跨平台软件&#xff0c;可以在 Linux、Windows 和 macOS 上运行。Calibre 6.3 正式发布&#xff0c;此次更新内容如下&#xff1a;新…...

C++ STL:适配器 Adapter

文章目录1、容器适配器1.1、stack1.2、queue1.3、priority_queue2、迭代器适配器2.1、插入迭代器2.2、反向迭代器2.3、流迭代器3、函数适配器3.1、* bindbind 使用方法bind 简化原理3.2、mem_fn适配器就是接口&#xff0c;对容器、迭代器、算法进行包装&#xff0c;但其实质还是…...

防抖和节流

防抖和节流的区别&#xff1f;防抖&#xff1a;触发高频事件后n 秒内 函数只会执行一次&#xff0c;如果n秒内 高频事件在在次触发&#xff0c;则会重新计算节流&#xff1a;高频事件触发&#xff0c;但在n 秒内 只会执行一次&#xff0c;所以节流会稀释函数的执行频率下面就是…...

vue3 微信扫码登录及获取个人信息实现的三种方法

一、流程&#xff1a; 微信提供的扫码方式有两种,分别是: 跳转二维码扫描页面 内嵌式二维码根据文档我们可以知道关于扫码授权的模式整体流程为: 1. 第三方发起微信授权登录请求&#xff0c;微信用户允许授权第三方应用后&#xff0c;微信会拉起应用或重定向到第三方网站&…...

Java8 新特性强大的Stream API

一、Stream API 说明 Java8中有两大最为重要的改变。第一个是 Lambda 表达式&#xff1b;另外一个则是 Stream API。 Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充&#xff0c;因为Stream API可以极大提供Ja…...

day22_IO

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、缓冲流 三、字符流 四、缓冲字符流 五、匿名内部类 零、 复习昨日 File: 通过路径代表一个文件或目录 方法: 创建型,查找类,判断类,其他 IO …...

第三十八章 linux-并发解决方法二(信号量)

第三十八章 linux-并发解决方法二&#xff08;信号量&#xff09; 文章目录第三十八章 linux-并发解决方法二&#xff08;信号量&#xff09;信号量的定义DOWN操作UP操作相对于自旋锁&#xff0c;信号量的最大特点是允许调用它的线程进入睡眠状态这意味着试图获得某一信号的进程…...

数据结构-考研难点代码突破(C++实现树型查找 - B树插入与遍历,B+树基本概念)

数据结构&#xff08;C&#xff09;[B树&#xff08;B-树&#xff09;插入与中序遍历&#xff0c;效率分析]、B树、B*树、B树系列应用 文章目录1. B树B树的插入与删除流程2. B树&#xff08;MySQL&#xff09;3. B树与B树对比4. C实现B树插入&#xff0c;中序遍历1. B树 B树类…...

Python可视化界面编程入门

Python可视化界面编程入门具体实现代码如所示&#xff1a; &#xff08;1&#xff09;普通可视化界面编程代码入门&#xff1a; import sys from PyQt5.QtWidgets import QWidget,QApplication #导入两个类来进行程序界面编程if __name__"__main__":#创建一个Appl…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

Python环境安装与虚拟环境配置详解

本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南&#xff0c;适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者&#xff0c;都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...

Django RBAC项目后端实战 - 03 DRF权限控制实现

项目背景 在上一篇文章中&#xff0c;我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统&#xff0c;为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...