Unity3D下如何采集camera场景数据并推送RTMP服务?
Unity3D使用场景
Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下:
- 游戏开发:Unity3D是一个广泛用于游戏开发的环境,适用于创建各种类型的游戏,包括动作游戏、角色扮演游戏、策略游戏、冒险游戏等。
- 虚拟现实:Unity3D也常用于虚拟现实(VR)开发,它提供了对VR设备的支持,如Oculus Rift和HTC Vive。
- 交互式演示:Unity3D可以用于创建各种类型的交互式演示,如产品原型、建筑和设计模拟器、教育应用程序等。
- 实时渲染:Unity3D的实时渲染功能可以用于创建电影级的特效和动画,以及用于视觉预览和产品渲染。
- 跨平台开发:Unity3D支持多个平台,包括PC、Mac、Linux、Android、iOS、Windows等,这使得开发者可以更容易地将他们的应用程序和游戏移植到不同的平台。
无论你是在哪个领域使用Unity3D,都需要了解其基本的工具和功能,包括场景编辑器、游戏对象、组件、脚本等。同时,还需要掌握一些基本的编程语言,如C#,以编写游戏逻辑和控制流程。
如何获取Camera场景数据
Unity3D获取摄像机数据通常用RenderTexture和RenderTexture.GetPixel方法来获取数据,把捕获屏幕的图像,存储在一个Texture2D实例中,用这个实例获取RGB数据。需要注意的是,需要为输出纹理创建一个新的纹理对象,否则可能会在屏幕上看到一片空白。示例代码如下:
using UnityEngine; public class GetCameraData : MonoBehaviour
{ public Texture2D outputTexture; // 输出纹理,用于存储RGB数据 public RenderTexture renderTexture; // RenderTexture实例,用于捕获屏幕图像 void Start() { // 创建一个RenderTexture实例 renderTexture = new RenderTexture(Screen.width, Screen.height, 24); // 获取当前摄像机 Camera camera = GetComponent<Camera>(); // 将当前摄像机的屏幕输出设置为刚刚创建的RenderTexture实例 camera.targetTexture = renderTexture; // 创建一个空的Texture2D实例,用于存储从RenderTexture读取的RGB数据 outputTexture = new Texture2D(Screen.width, Screen.height); } void Update() { // 从RenderTexture中读取RGB数据,并存储到outputTexture中 RenderTexture.active = renderTexture; outputTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); outputTexture.Apply(); }
}
如何实现RTMP推送服务
本文以大牛直播SDK开发的Unity3D下Android平台的RTMP推送camera场景的demo为例,结合Unity和原生模块交互,大概介绍下核心实现逻辑。

开始推送RTMP服务:
public bool StartRtmpPusher(){if (is_pushing_rtmp_){Debug.Log("已推送.."); return false;}if(!is_rtsp_publisher_running_){InitAndSetConfig();}if (pusher_handle_ == 0) {Debug.LogError("StartRtmpPusher, publisherHandle is null..");return false;}NT_PB_U3D_SetPushUrl(pusher_handle_, rtmp_push_url_);int is_suc = NT_PB_U3D_StartPublisher(pusher_handle_);if (is_suc == DANIULIVE_RETURN_OK){Debug.Log("StartPublisher success.."); is_pushing_rtmp_ = true;}else{Debug.LogError("StartPublisher failed..");return false;}return true;}
InitAndSetConfig()完成常规参数设置,比如软硬编码、帧率、码率等参数设置,如果需要采集audio,还可以把麦克风采集到的audio和audioclip获取到的audio数据mix后输出:
private void InitAndSetConfig(){if ( java_obj_cur_activity_ == null ){Debug.LogError("getApplicationContext is null");return;}int audio_opt = 1;int video_opt = 3;video_width_ = camera_.pixelWidth;video_height_ = camera_.pixelHeight;pusher_handle_ = NT_PB_U3D_Open(audio_opt, video_opt, video_width_, video_height_);if (pusher_handle_ != 0){Debug.Log("NT_PB_U3D_Open success");NT_PB_U3D_Set_Game_Object(pusher_handle_, game_object_);}else{Debug.LogError("NT_PB_U3D_Open failed!");return;}int fps = 30;int gop = fps * 2;if(video_encoder_type_ == (int)PB_VIDEO_ENCODER_TYPE.VIDEO_ENCODER_HARDWARE_AVC){int h264HWKbps = setHardwareEncoderKbps(true, video_width_, video_height_);h264HWKbps = h264HWKbps * fps / 25;Debug.Log("h264HWKbps: " + h264HWKbps);int isSupportH264HWEncoder = NT_PB_U3D_SetVideoHWEncoder(pusher_handle_, h264HWKbps);if (isSupportH264HWEncoder == 0) {NT_PB_U3D_SetNativeMediaNDK(pusher_handle_, 0);NT_PB_U3D_SetVideoHWEncoderBitrateMode(pusher_handle_, 1); // 0:CQ, 1:VBR, 2:CBRNT_PB_U3D_SetVideoHWEncoderQuality(pusher_handle_, 39);NT_PB_U3D_SetAVCHWEncoderProfile(pusher_handle_, 0x08); // 0x01: Baseline, 0x02: Main, 0x08: High// NT_PB_U3D_SetAVCHWEncoderLevel(pusher_handle_, 0x200); // Level 3.1// NT_PB_U3D_SetAVCHWEncoderLevel(pusher_handle_, 0x400); // Level 3.2// NT_PB_U3D_SetAVCHWEncoderLevel(pusher_handle_, 0x800); // Level 4NT_PB_U3D_SetAVCHWEncoderLevel(pusher_handle_, 0x1000); // Level 4.1 多数情况下,这个够用了//NT_PB_U3D_SetAVCHWEncoderLevel(pusher_handle_, 0x2000); // Level 4.2// NT_PB_U3D_SetVideoHWEncoderMaxBitrate(pusher_handle_, ((long)h264HWKbps)*1300);Debug.Log("Great, it supports h.264 hardware encoder!");}}else if(video_encoder_type_ == (int)PB_VIDEO_ENCODER_TYPE.VIDEO_ENCODER_HARDWARE_HEVC){int hevcHWKbps = setHardwareEncoderKbps(false, video_width_, video_height_);hevcHWKbps = hevcHWKbps*fps/25;Debug.Log("hevcHWKbps: " + hevcHWKbps);int isSupportHevcHWEncoder = NT_PB_U3D_SetVideoHevcHWEncoder(pusher_handle_, hevcHWKbps);if (isSupportHevcHWEncoder == 0) {NT_PB_U3D_SetNativeMediaNDK(pusher_handle_, 0);NT_PB_U3D_SetVideoHWEncoderBitrateMode(pusher_handle_, 0); // 0:CQ, 1:VBR, 2:CBRNT_PB_U3D_SetVideoHWEncoderQuality(pusher_handle_, 39);// NT_PB_U3D_SetVideoHWEncoderMaxBitrate(pusher_handle_, ((long)hevcHWKbps)*1200);Debug.Log("Great, it supports hevc hardware encoder!");}}else {if (is_sw_vbr_mode_) //H.264 software encoder{int is_enable_vbr = 1;int video_quality = CalVideoQuality(video_width_, video_height_, true);int vbr_max_bitrate = CalVbrMaxKBitRate(video_width_, video_height_);vbr_max_bitrate = vbr_max_bitrate * fps / 25;NT_PB_U3D_SetSwVBRMode(pusher_handle_, is_enable_vbr, video_quality, vbr_max_bitrate);//NT_PB_U3D_SetSWVideoEncoderSpeed(pusher_handle_, 2);}}NT_PB_U3D_SetAudioCodecType(pusher_handle_, 1);NT_PB_U3D_SetFPS(pusher_handle_, fps);NT_PB_U3D_SetGopInterval(pusher_handle_, gop);if (audio_push_type_ == (int)PB_AUDIO_OPTION.AUDIO_OPTION_MIC_EXTERNAL_PCM_MIXER|| audio_push_type_ == (int)PB_AUDIO_OPTION.AUDIO_OPTION_TWO_EXTERNAL_PCM_MIXER){NT_PB_U3D_SetAudioMix(pusher_handle_, 1);}else{NT_PB_U3D_SetAudioMix(pusher_handle_, 0);}}
投递video数据的逻辑实现如下:
void PostVideoData() {if(pusher_handle_ == 0)return;if(!is_pushing_rtmp_ && !is_rtsp_publisher_running_)return;if (textures_poll_ == null)return;int w = camera_.pixelWidth;int h = camera_.pixelHeight;if (w != video_width_ || h != video_height_) {Debug.Log("PostVideoData resolution changed++ width: " + w + " height: " + h);if(render_texture_ != null) {render_texture_.Release();render_texture_ = null;}video_width_ = w;video_height_ = h;}if (null == render_texture_ ) {render_texture_ = new RenderTexture(video_width_, video_height_, 16);render_texture_.Create();}Texture2D image_texture = textures_poll_.get(video_width_, video_height_);if (null == image_texture)return;...image_texture.ReadPixels(new Rect(0, 0, video_width_, video_height_), 0, 0, false);...post_image_worker_.post(image_texture, is_vertical_flip_, is_horizontal_flip_, scale_width_, scale_height_);}
如果需要停止RTMP推送:
private void StopRtmpPusher(){if(!is_pushing_rtmp_)return;NT_PB_U3D_StopPublisher(pusher_handle_);if(!is_rtsp_publisher_running_){NT_PB_U3D_Close(pusher_handle_);pusher_handle_ = 0;NT_PB_U3D_UnInit();}is_pushing_rtmp_ = false;}
技术总结
Unity3D下采集camera场景并推送RTMP具有重要的意义,可以为实时监控、在线直播、视频教程制作、增强现实和虚拟现实应用以及数据记录和分析等领域提供有力的支持。比如,采集camera场景可以用于增强现实和虚拟现实应用。在AR中,可以通过采集实际场景的画面,将虚拟元素与现实场景进行融合,增强沉浸感和互动性。
相关文章:
Unity3D下如何采集camera场景数据并推送RTMP服务?
Unity3D使用场景 Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下: 游戏开发:Unity3D是一个广泛用于游戏开发的环境,适用于创建各种类型的游戏,包括动作游戏、角…...
黑客可利用 Windows 容器隔离框架绕过端点安全系统
新的研究结果表明,攻击者可以利用一种隐匿的恶意软件检测规避技术,并通过操纵 Windows 容器隔离框架来绕过端点安全的解决方案。 Deep Instinct安全研究员丹尼尔-阿维诺姆(Daniel Avinoam)在本月初举行的DEF CON安全大会上公布了…...
STM32注入通道
什么是注入通道? 注入通道是ADC的一种采样方式,主要用于在规则通道转换期间并行处理快速变化信号的采样。注入通道的转换可以在规则通道转换时强行插入,相当于一个“中断通道”。当有注入通道需要转换时,规则通道的转换会停止,优先执行注入通道的转换,当注入通道的转换执…...
WebVR — 网络虚拟现实
推荐:使用 NSDT编辑器 快速搭建3D应用场景 虚拟现实设备 随着Oculus Rift和许多其他生产设备即将上市,未来看起来很光明——我们已经有足够的技术来使VR体验“足够好”,可以玩游戏。有许多设备可供选择:像Oculus Rift或HTC Vive这…...
ASP.NET Core 的 Routing
ASP.NET Core 的 Routing ASP.NET Core 的 controllers 使用Routing 中间件匹配客户端的 url 请求,然后映射到对应的 controller 的处理方法(Action)上。 Actions 可以是 常规路由 或 属性路由 的映射。 MVC App一般使用常规路由。 REST API…...
IBM Spectrum LSF Explorer 为要求苛刻的分布式和任务关键型高性能技术计算环境提供强大的工作负载管理
IBM Spectrum LSF Explorer 适用于 IBM Spectrum LSF 集群的强大、轻量级报告解决方案 亮点 ● 允许不同的业务和技术用户使用单一解决方案快速创建和查看报表和仪表板 ● 利用可扩展的库提供预构建的报告 ● 自定义并生成性能、工作负载和资源使用情况的报…...
RHCE——十一、NFS服务器
NFS服务器 一、简介1、NFS背景介绍2、生产应用场景 二、NFS工作原理1、示例图2、流程 三、NFS的使用1、安装2、配置文件3、主配置文件分析3.1 实验1 4、NFS账户映射4.1 实验24.2 实验3 四、autofs自动挂载服务1、产生原因2、安装3、配置文件分析4、实验45、实验5 一、简介 1、…...
Python编程练习与解答 练习100:随机密码
编写一个生成最忌密码的函数,密码的长度应该在7-10个字符之间。每个字符应该从ASCII表的第33位到126位中随机选择。函数不接受任何参数,返回随机生成的密码作为位移结果。在文件的main程序中显示随机生成的密码。main程序只在解答没有被导入另一个文件时…...
华为云云服务器评测 | 从零开始:云耀云服务器L实例的全面使用解析指南
文章目录 一、前言二、云耀云服务器L实例要点介绍2.1 什么是云耀云服务器L实例2.1.1 浅析云耀云服务器L实例 2.2 云耀云服务器L实例的产品定位2.3 云耀云服务器L实例优势2.4 云耀云服务器L实例支持的镜像与应用场景2.5 云耀云服务器L实例与弹性云服务器(ECS…...
欧科云链研究院探析Facebook稳定币发行经历会不会在PayPal重演
引言 作者最近的报告-探析PayPal发行稳定币是否会重蹈Facebook覆辙-近期被英国的金融时报(中文版)刊登。由于该报告在欧科云链研究院内部反响较好,下面就带大家简单的剖析这篇报告的主要内容。 *这篇文章主要由对比分析(已删减&a…...
docker 容器pip、git安装异常;容器内web对外端口ping不通
1、docker 容器pip、git安装异常 错误信息: git clone https://github.com/vllm-project/vllm.git Cloning into ‘vllm’… fatal: unable to access ‘https://github.com/vllm-project/vllm.git/’: Failed to connect to 127.0.0.1 port 10808: Connection ref…...
SpringBoot Mybatis 多数据源 MySQL+Oracle+Redis
一、背景 在SpringBoot Mybatis 项目中,需要连接 多个数据源,连接多个数据库,需要连接一个MySQL数据库和一个Oracle数据库和一个Redis 二、依赖 pom.xml <dependencies><dependency><groupId>org.springframework.boot&l…...
【JavaScript 16】对象继承 原型对象属性 原型链 构造函数属性 instanceof运算符 继承 多重继承 模块
对象继承 原型对象概述instanceof运算符构造函数的继承多重继承模块 A 对象通过继承 B 对象,就能 直接拥有 B 对象的所有属性和方法(利于代码复用) 大部分面向对象的编程语言都是通过类(class)实现对象的继承 但 传统…...
地下管线三维自动建模软件MagicPipe3D V3.0发布
2023年9月1日经纬管网建模系统MagicPipe3D V3.0正式发布,该版本经过众多用户应用和反馈,在三维地下管线建模效果、效率、适配性等方面均有显著提升!MagicPipe3D本地离线参数化构建地下管网模型(包括管道、接头、附属设施等&#x…...
百度等8家企业首批上线大模型服务;大语言模型微调之道
🦉 AI新闻 🚀 百度等8家企业首批上线大模型服务 摘要:百度、字节、中科院旗下8家企业/机构的大模型通过备案,正式面向公众提供服务。百度旗下AI大模型产品文心一言率先开放,用户可下载App或登录官网体验。百川智能也…...
二、Mycat2 相关概念及读写分离
第三章 Mycat2 相关概念 3.1 概念描述 1、分库分表 按照一定规则把数据库中的表拆分为多个带有数据库实例,物理库,物理表访问路 径的分表。 解读:分库:一个电商项目,分为用户库、订单库等等。 分表:一张订单表数据数百万ÿ…...
react利用wangEditor写评论和@功能
先引入wangeditor写评论功能 import React, { useEffect, useState, useRef, forwardRef, useImperativeHandle } from react; import wangeditor/editor/dist/css/style.css; import { Editor, Toolbar } from wangeditor/editor-for-react; import { Button, Card, Col, For…...
Android之布局转圆角
Android之布局转圆角 文章目录 Android之布局转圆角说明一、效果图二、实现步骤1.自定义RoundRelativeLayout2.使用 总结 说明 很多需求比较无语,需要某个布局转圆角,像个显眼包一样,所以为了满足显眼包,必须整呐提示:…...
Linux的目录结构特点
Linux的目录结构特点 1、使用树形目录结构来组织和管理文件。 2、整个系统只有一个根目录(树根),Linux的根目录用“/”表示。 3、其他所有分区以及外部设备(如硬盘,光驱等)都是以根目录为起点࿰…...
【算法与数据结构】654、LeetCode最大二叉树
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:【算法与数据结构】106、LeetCode从中序与后序遍历序列构造二叉树这两道题有些类似,相关代…...
通过 Langchain 框架实现 ChatGPT 的使用
一. 简介Langchain 框架:LangChain 是一个开源框架,是一个让大语言模型(如ChatGPT)能连接外部工具、记忆对话、执行复杂任务的“智能助手”开发框架,解决了LLM应用开发中的各种工程化问题。# LangChain 的核心定位&…...
OpenModScan:免费开源的Modbus调试工具完整指南
OpenModScan:免费开源的Modbus调试工具完整指南 【免费下载链接】OpenModScan Open ModScan is a Free Modbus Master (Client) Utility 项目地址: https://gitcode.com/gh_mirrors/op/OpenModScan 在工业自动化领域,Modbus通讯协议的调试和测试是…...
ai辅助开发,让快马智能生成centos下openclaw安装与配置的疑难解决方案
在CentOS系统上安装和配置OpenClaw这类工具时,经常会遇到各种依赖冲突、环境配置问题,以及需要定制化爬取规则的情况。传统方式下,我们需要手动查阅文档、调试命令,甚至反复尝试不同版本的依赖包,过程相当耗时。而借助…...
TheAmazingAudioEngine实战案例:构建完整的音乐制作应用
TheAmazingAudioEngine实战案例:构建完整的音乐制作应用 【免费下载链接】TheAmazingAudioEngine 项目地址: https://gitcode.com/gh_mirrors/th/TheAmazingAudioEngine TheAmazingAudioEngine是一款功能强大的音频处理框架,专为移动应用开发打造…...
3个高效Searchkit高亮技巧:让你的搜索结果直观又专业
3个高效Searchkit高亮技巧:让你的搜索结果直观又专业 【免费下载链接】searchkit Search UI for Elasticsearch & Opensearch. Compatible with Algolias Instantsearch and Autocomplete components. React & Vue support 项目地址: https://gitcode.com…...
Transformer位置编码避坑指南:手把手教你用RoPE解决长文本外推难题(附Torch复现)
Transformer长文本处理实战:RoPE位置编码的工程化解决方案 在构建现代NLP系统时,处理长文本序列一直是Transformer架构面临的重大挑战。当序列长度超过模型预训练时的最大位置编码范围时,传统方法的性能会显著下降。这种现象在构建聊天机器人…...
鸿蒙应用开发实战:手把手教你封装一个可复用的音乐播放器管理类(ArkTS版)
鸿蒙应用开发实战:构建高可复用的音乐播放器管理类(ArkTS版) 在鸿蒙应用开发中,音频播放功能是许多应用的核心需求。本文将深入探讨如何设计一个健壮、可复用的音乐播放器管理类,采用ArkTS语言实现,帮助开发…...
阿里开源Z-Image镜像体验:ComfyUI可视化生成汉服美女实战
阿里开源Z-Image镜像体验:ComfyUI可视化生成汉服美女实战 1. 开篇:当汉服遇见AI绘画 想象一下,你只需要输入"一位穿着汉服的中国女性站在樱花树下",AI就能在几秒钟内生成一张细节精致的写实风格图像。这不再是科幻场景…...
如何从其他理财应用迁移到Ivy Wallet:数据导入完全指南
如何从其他理财应用迁移到Ivy Wallet:数据导入完全指南 【免费下载链接】ivy-wallet Ivy Wallet is an open-source money manager app for android that you can either build or download from Google Play. 项目地址: https://gitcode.com/gh_mirrors/iv/ivy-w…...
YOLOv8与SenseVoice-Small的多模态安防监控系统设计
YOLOv8与SenseVoice-Small的多模态安防监控系统设计 1. 系统设计背景与价值 在现代安防监控领域,单纯依靠视频分析已经无法满足复杂场景下的安全需求。传统的监控系统往往需要人工实时监控,不仅效率低下,而且容易遗漏关键信息。特别是在夜间…...
