Unity3d C#快速打开萤石云监控视频流(ezopen)支持WebGL平台,替代UMP播放视频流的方案(含源码)
前言
Universal Media Player算是视频流播放功能常用的插件了,用到现在已经不知道躺了多少坑了,这个插件虽然是白嫖的,不过被甲方和领导吐槽的就是播放视频流的速度特别慢,可能需要几十秒来打开监控画面,等待的时间较久。还有当输出WebGL的时候视频无法播放,这个问题也一直没法解决。而我们常用的萤石云监控视频流在小程序端或者Web端打开却快速了很多,这也就启发了在Unity3d中也使用这种嫁接的方式来实现。就是通过打开网页,在网页中播放视频流的方式来解决该问题。实验结果就是能比Universal Media Player打开快2-3倍。本文是Unity3d 2020.3.28f1c1 Personal版本以萤石云的ezopen协议为例,实现该功能。
如果你的视频流协议是其它的(如rtmp、rtsp等),则需要将摄像头的协议转成能够在浏览器中播放的协议,具体方式需要做网页的相关人员进行。这个是我在网上搜到的方法,本人并未进行实操测试,仅供参考:
1、Nginx的RTMP模块配置方法,通过Ffmpeg将RTSP转成RTMP协议,然后Nginx中配置RTMP到HLS协议的映射,最后按照指定的规则路径请求即可。
2、Ffmpeg将RTSP协议直接转成HLS协议,写入到Nginx的指定目录下,然后Nginx将该目录代理成HTTP访问的方式,浏览器直接请求即可,这种方法会生成很多ts文件,需要做清理处理,尝试过可行,但是不建议使用。
效果
Windows效果一:
Windows效果二:
WebGL平台:
如果设备有问题会直接提示在播放界面上:
以上动态图没有展示成功的画面,因为设备非个人持有,所以播放成功的画面未进行直接展示。
工作准备
笔者所用的插件:
LitJson 用于生成/解析网络请求的json。
DOTweenPro 用于制作简单的窗口弹出、关闭动画;
3D WebView for Windows and macOS (Web Browser) 用于打开网页(使用说明(https://blog.csdn.net/qq_33789001/article/details/126180804))的插件(看需求使用Embedded Browser也可以),需要WebGL 平台的还需要2D WebView for WebGL (Web Browser IFrame)插件。
参考文章:
之前笔者写过关于萤石云监控相关的操作可以进行一些参考复用。
获取accessToken:https://blog.csdn.net/qq_33789001/article/details/117251545
获取视频流地址:https://blog.csdn.net/qq_33789001/article/details/128223680
Unity WebGl发布问题:
https://blog.csdn.net/qq_33789001/article/details/128900799
功能实现
获取accessToken
管理员账号根据appKey和secret获取accessToken接口.
请求地:https://open.ys7.com/api/lapp/token/get 请求方式:POST
① AccessToken,即访问令牌。接口调用必备的公共参数之一,用于校验接口访问/调用是否有权限,有效期为7天,有效期内不需要重复申请,可以重复使用;
② 有效期7天无法变更,请在业务端使用AccessToken的场景中,校验老Token的有效性和失效时重新获取Token的机制;
③ 新获取Token不会使老Token失效,每个Token独立拥有7天生命周期 接口列表如下:
返回字段
字段名 类型 描述
accessToken String 获取的accessToken
expireTime long 具体过期时间,精确到毫秒
这里的实现代码如下:
//令牌相关[Header("设置萤石云的appKey")]public string appKey = "";[Header("设置萤石云的appSecret")]public string appSecret = "";string GetATUrl = "https://open.ys7.com/api/lapp/token/get";[HideInInspector]public string AT = "";DateTime AtEdTime; //令牌失效时间
//请求萤石云的令牌void GetAccessToken(){isGetATing = true;List<IMultipartFormSection> formData = new List<IMultipartFormSection>();formData.Add(new MultipartFormDataSection("appKey", appKey));formData.Add(new MultipartFormDataSection("appSecret", appSecret));Global.DoReqWebApiPost(GetATUrl, formData, (bytes) =>{try{if (string.IsNullOrEmpty(bytes)) return;JsonData datas = JsonMapper.ToObject(bytes);if (!datas.ContainsKey("data")) return;if (!datas["data"].ContainsKey("accessToken") || !datas["data"].ContainsKey("expireTime")) return;AT = datas["data"]["accessToken"].ToString();AtEdTime = ConvertToDateTime(datas["data"]["expireTime"].ToString());}catch (Exception e){Debug.LogWarning("获取萤石云AccessToken异常:" + e);}finally {isGetATing = false;}});
}
要注意的是,如果程序长期运行,需要判断accessToken的过期时间,即使获取并更新,不然会导致功能异常。
获取监控视频流
获取单个的视频流地址,需要使用accessToken为参数,并且protocol的协议必须是ezopen,同时过期时间需要尽量长一些。
[Header("是否同步流地址")]public bool isSyncUrl = true;[Header("选择视频流类型")]public Streaming_Type streamingType = Streaming_Type.ezopen;[Header("监控设备编号")]public string deviceSerial;[Header("监控频道号")]
public string channelNo;//获取视频地址void GetSteamingUrl(){List<IMultipartFormSection> formData = new List<IMultipartFormSection>();formData.Add(new MultipartFormDataSection("accessToken", YsAccessTokenMgr.instance.AT));formData.Add(new MultipartFormDataSection("deviceSerial", deviceSerial));formData.Add(new MultipartFormDataSection("channelNo", channelNo));formData.Add(new MultipartFormDataSection("expireTime", "2592000"));formData.Add(new MultipartFormDataSection("protocol", ((int)streamingType).ToString()));formData.Add(new MultipartFormDataSection("quality", "1"));Global.DoReqWebApiPost(StreamUrl, formData, (bytes) =>{try{if (string.IsNullOrEmpty(bytes))return;JsonData datas = JsonMapper.ToObject(bytes);if (!datas.ContainsKey("data")|| !datas["data"].ContainsKey("url"))return;videourl = datas["data"]["url"].ToString();}catch (Exception e){Debug.LogWarning("获取萤石云视频流地址异常:" + e);}});}
这里也可以不获取视频流地址,只有视频嵌入式需要ezopen的地址,isSyncUrl 为false时,就不会获取。
打开网页播放视频
我们在点击了监控视频的标签后,就根据视频标签的信息打开监控视频的网页。
这里有两种方式进行播放视频流:视频嵌入式和跳转播放页式,详细说明请看:https://open.ys7.com/bbs/article/20
因为我们的视频窗口是在UI上,所以使用CanvasWebViewPrefab进行网页打开:
canvasWebView.WebView.LoadUrl(url);
视频嵌入式
代码如下:
string url = "https://open.ys7.com/ezopen/h5/iframe_se?url=" + path + "&autoplay=1&audio=0&accessToken=" + YsAccessTokenMgr.instance.AT;canvasWebView.WebView.LoadUrl(url);
说明如下:
url:监控地址,包含验证码、设备序列号、通道号、清晰度、播放类型
autoplay:1-开启自动播放,未显示字段-关闭自动播放
audio:1-开启音频,未显示字段-关闭音频
accessToken:访问令牌,播放监控地址的必要参数
笔者在测试该方式时发现,在WebGL时,这种方式在一定情况下会出现网页错误,视频未播放的情况:
跳转播放页式
代码如下:
string url = " https://open.ys7.com/ezopen/h5/live?autoplay=1&audio=0&accessToken=" + YsAccessTokenMgr.instance.AT + "&hd=1&deviceSerial=" + camlab.deviceSerial + "&channelNo=" + camlab.channelNo;canvasWebView.WebView.LoadUrl(url);
说明如下:
live后缀:预览
rec后缀:回放
autoplay:1-开启自动播放,未显示字段-关闭自动播放
audio:1-开启音频,未显示字段-关闭音频
accessToken:访问令牌,播放监控地址的必要参数
validCode:验证码,加密设备播放需要验证码
hd:1-高清(实际为主码流),未显示字段-流畅(实际为子码流)
deviceSerial:设备序列号
channelNo:通道号
工程源码
完整的工程源码:https://download.csdn.net/download/qq_33789001/88135255
无法打开说明审核未通过。
现在工程后,打开项目中的Main.unity场景,选中FunNodes>YsAccessTokenMgr节点设置您自己的appKey和appSecret:
选中Icon_Camera修改视频标签的信息deviceSerial和channelNo:
确保的信息都是同一个账号下面的,运行后点击视频图标即可看到播放的效果了。
相关文章:

Unity3d C#快速打开萤石云监控视频流(ezopen)支持WebGL平台,替代UMP播放视频流的方案(含源码)
前言 Universal Media Player算是视频流播放功能常用的插件了,用到现在已经不知道躺了多少坑了,这个插件虽然是白嫖的,不过被甲方和领导吐槽的就是播放视频流的速度特别慢,可能需要几十秒来打开监控画面,等待的时间较…...

【Android】APP启动优化学习笔记
启动优化目的 用户体验: 应用的启动速度直接影响用户体验。用户希望应用能够快速启动并迅速响应他们的操作。如果应用启动较慢,用户可能会感到不满,并且有可能选择卸载或切换到竞争对手的应用。通过启动优化,可以提高应用的启动…...

docker的使用
docker安装 https://docs.docker.com/engine/install/debian/ 设置国内镜像 创建或修改 /etc/docker/daemon.json 文件,修改为如下形式 {"registry-mirrors": ["https://registry.hub.docker.com","http://hub-mirror.c.163.com"…...
iOS使用Rust调研
编辑已恢复 我们已与您断开连接。尝试重连时会保存您所做的变更。尝试重连 标题 1 已保存 Bin Song B 要发布此内容,请选择键盘上的 ⌘Enter。 发布 关闭 Rust技术空间 … 跨平台使用调研 iOS使用Rust调研 添加表情符号 添加标题图像 添加状态 一、iOS 项…...

抖音引流推广的几个方法,抖音全自动引流脚本软件详细使用教学
大家好我是你们的小编一辞脚本,今天给大家分享新的知识,很开心可以在CSDN平台分享知识给大家,很多伙伴看不到代码我先录制一下视频 在给大家做代码,给大家分享一下抖音引流脚本的知识和视频演示 不懂的小伙伴可以认真看一下,我们…...

k8s概念-DaemonSet
回到目录 参考链接https://v1-23.docs.kubernetes.io/zh/docs/concepts/workloads/controllers/daemonset/ DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本 当节点加入到K8S集群中,pod会被(DaemonSet)调度到…...

Mac 终端快捷键设置:如何给 Mac 中的 Terminal 设置 Ctrl+Alt+T 快捷键快速启动
Mac 电脑中正常是没有直接打开终端命令行的快捷键指令的,但可以通过 commandspace 打开聚焦搜索,然后输入 ter 或者 terminal 全拼打开。但习惯了 linux 的同学会觉得这个操作很别扭。于是我们希望能通过键盘按键直接打开。 操作流程如下: 1…...

VR 变电站事故追忆反演——正泰电力携手图扑
VR(Virtual Reality,虚拟现实)技术作为近年来快速发展的一项新技术,具有广泛的应用前景,支持融合人工智能、机器学习、大数据等技术,实现更加智能化、个性化的应用。在电力能源领域,VR 技术在高性能计算机和专有设备支…...

fpga开发——蜂鸣器
蜂鸣器的原理 有源蜂鸣器和无源蜂鸣器 无源蜂鸣器利用电磁感应现象,为音圈接入交变电流后形成的电磁铁与永磁铁相吸或相斥而推动振膜发声,接入直流电只能持续推动振膜而无法产生声音,只能在接通或断开时产生声音。无源蜂鸣器的工作原理与扬声…...

【Liux下6818开发板(ARM)】触摸屏
(꒪ꇴ꒪ ),hello我是祐言博客主页:C语言基础,Linux基础,软件配置领域博主🌍快上🚘,一起学习!送给读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!作者水平很有限,如果发现错误&#x…...

苍穹外卖day11——数据统计图形报表(Apache ECharts)
效果展示 Apache ECharts 介绍 常见图表 入门案例 快速上手 - Handbook - Apache ECharts 营业额统计——需求分析与设计 产品原型 接口设计 VO设计 营业额统计——代码开发 Controller中 /*** 数据统计相关接口*/ RestController RequestMapping("/admin/report&qu…...
在制作PC端Game Launcher游戏启动器时涉及到的技术选型
1)在制作PC端Game Launcher游戏启动器时涉及到的技术选型 2)如何将图片显示到Canvas的Raw Image上面 3)Unity 2018.4.4f1退出重启后出现黑屏 4)如何获取到GPU耗时 这是第346篇UWA技术知识分享的推送,精选了UWA社区…...
SQL力扣练习(九)
目录 1.订单最多的用户(586) 示例 1 解法一(limit) 解法二(dense_rank()) 2.体育馆的人流量 示例 1 解法一(临时表) 解法二(三表法) 1.订单最多的用户(586) 表: Orders --------------------------- | Column Name | Type | ---------…...

软考高级架构师笔记-10数学计算题
目录 1. 前文回顾 & 考情分析2. 最小生成树3. 最短路径4. 网络与最大流量5. 线性规划6. 动态规划/决策表7. 博弈论8. 状态转移矩阵9. 决策论10. 结语1. 前文回顾 & 考情分析 前文回顾: 软考高级架构师笔记-1计算机硬件软考高级架构师笔记-2计算机软件(操作系统)软考…...
设计模式五:建造者模式(Builder Pattern)
建造者模式(Builder Pattern)是一种创建型设计模式,用于通过一系列步骤来构建复杂对象。它将对象的构建过程与其表示分离,从而允许相同的构建过程可以创建不同的表示。 建造者模式中的几个角色: 产品(Product):表示被构建的复杂…...

C++多线程编程(包含c++20内容)
C多线程编程(包含c20内容) 文章目录 C多线程编程(包含c20内容)线程通过函数指针创建线程通过函数对象创建线程通过lambda创建线程通过成员函数创建线程线程本地存储取消线程自动join线程从线程获得结果 原子操作库原子操作原子智能指针原子引用使用原子类型等待原子变量 互斥互…...

【C语言】通讯录2.0 (动态增长版)
前言 通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。 文章的一二三章均于上一篇相同,可以直接看第四章改造内容。 此通讯录是基于通讯录1.0(静态版)的基础上进行改进,请先看系列文字第…...

详解AMQP协议以及JAVA体系中的AMQP
目录 1.概述 1.1.简介 1.2.抽象模型 2.spring中的amqp 2.1.spring amqp 2.2.spring boot amqp 1.概述 1.1.简介 AMQP,Advanced Message Queuing Protocol,高级消息队列协议。 百度百科上的介绍: 一个提供统一消息服务的应用层标准高…...

跨境电商外贸常态下,深度分析Live Market的优势
据统计,今年上半年,面对复杂严峻的外部环境,我国外贸进出口规模在历史同期首次突破20万亿元,展现较强韧性。我国正处于大力支持跨境电商发展的时代节点。在此背景下,无数商家准备抓住时代机遇,将品牌影响力从国内延伸至全世界。同…...
vue2企业级项目(八)
vue2企业级项目(八) 组件封装(二) 4、searchForm 创建components/searchForm/index.js import XSearchForm from "./index.vue"; export default XSearchForm;使用案例 <template><div class"wrap"…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...