Unity3D下如何采集camera场景数据并推送RTMP服务?

Unity3D使用场景

Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下:

  1. 游戏开发:Unity3D是一个广泛用于游戏开发的环境,适用于创建各种类型的游戏,包括动作游戏、角色扮演游戏、策略游戏、冒险游戏等。
  2. 虚拟现实:Unity3D也常用于虚拟现实(VR)开发,它提供了对VR设备的支持,如Oculus Rift和HTC Vive。
  3. 交互式演示:Unity3D可以用于创建各种类型的交互式演示,如产品原型、建筑和设计模拟器、教育应用程序等。
  4. 实时渲染:Unity3D的实时渲染功能可以用于创建电影级的特效和动画,以及用于视觉预览和产品渲染。
  5. 跨平台开发: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中,可以通过采集实际场景的画面,将虚拟元素与现实场景进行融合,增强沉浸感和互动性。

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

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

相关文章

C语言每日一练--Day(16)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;寻找奇数 峰值 二分查找 &#x1f493;博主csdn个人主页&#xff1a;小…

go学习part21 Redis和Go(2)

1.三方库安装 309_尚硅谷_Go连接到Redis_哔哩哔哩_bilibili 借鉴&#xff1a; Golang 安装 Redis_go fiber 安装redis_柒柒伍贰玖。的博客-CSDN博客 三方redis库已经迁移到以下网址&#xff0c;go get github.com/gomodule/redigo/redis gomodule/redigo: Go client for Red…

UE5打完包后,启动程序不能全屏

最近看到ue5的打包程序后不能默认自动全屏&#xff0c;效果如下&#xff0c;发现并不是全屏的&#xff0c;而且就算点击放大也不是全屏 解决办法&#xff1a;设置如下之后在打包就可以了 但是会一直打印错误的日志&#xff0c;不过这个不影响使用

【IIS搭建网站】本地电脑做服务器搭建web站点并公网访问「内网穿透」

1.前言 在网上各种教程和介绍中&#xff0c;搭建网页都会借助各种软件的帮助&#xff0c;比如网页运行的Apache和Nginx、数据库软件MySQL和MSSQL之类&#xff0c;为方便用户使用&#xff0c;还出现了XAMPP、PHPStudy、宝塔面板等等一系列集成服务&#xff0c;都是为了方便我们…

weblogic/CVE-2018-2894文件上传漏洞复现

启动docker环境 查看帮助文档 环境启动后&#xff0c;访问http://your-ip:7001/console&#xff0c;即可看到后台登录页面。 执行docker-compose logs | grep password可查看管理员密码&#xff0c;管理员用户名为weblogic&#xff0c;密码为lFVAJ89F 登录后台页面&#xff0c;…

在 Python 中构建卷积神经网络; 从 0 到 9 的手绘数字的灰度图像预测数字

一、说明 为了预测从0到9的数字&#xff0c;我选择了一个基于著名的Kaggle的MNIST数据集的数据集。数据集包含从 <0> 到 <9> 的手绘图数字的灰度图像。在本文中&#xff0c;我将根据像素数据&#xff08;即数值数据&#xff09;和卷积神经网络预测数字。 二、 卷积…

新方案unity配表工具

工具下载&#xff1a;网盘链接 工具结构&#xff1a;针对每张表格生成一个表格类&#xff0c;其中默认包含一个list和字典类型参数记录表格数据&#xff0c;初始化项目时将list中的数据转为按id索引的dictionary&#xff0c;用于访问数据。额外包含一个同名Temp后缀的类&#…

Python爬虫(十七)_糗事百科案例

糗事百科实例 爬取糗事百科段子&#xff0c;假设页面的URL是: http://www.qiushibaike.com/8hr/page/1 要求&#xff1a; 使用requests获取页面信息&#xff0c;用XPath/re做数据提取获取每个帖子里的用户头像连接、用户姓名、段子内容、点赞次数和评论次数保存到json文件内…

Nginx笔记(安装+使用)

Nginx开源版安装、启动 版本区别 Nginx开源版 Nginx plus 商业版 openresty Tengine 安装 将.tar.gz放到linux系统下, 使用tar -zxvf减压 进入减压目录>>>命令安装指令&#xff1a;安装到usr/local/nginx路径下 ./configure --prefix/usr/local/nginxmake &…

APP出海:如何在美国市场推广?

作为出海探宝热度最高市场&#xff0c;美国在吸引了全球全球开发者争先抢滩的同时&#xff0c;也造就了该地区高昂的买量、宣发、获客成本。 面对日渐紧迫的局势&#xff0c;中国游戏出海广告主该如何打破传统“买量”思路&#xff0c;提升在当地的品牌影响力&#xff1f; 1、…

AZ900备考

文章目录 云服务的概念云服务模型云服务类型消费的模型云服务的好处可靠性和可预测性的优势云中的管理 Azure 体系结构和服务核心结构组件物理基础结构组件 Azure计算和网络服务Azure 存储服务身份认证AD身份认证 Azure 管理和治理成本管理治理合规性的功能和工具管理和部署Azu…

低代码赋能| 绿色智慧矿山解决方案

在世界能源日趋紧张的背景下&#xff0c;能源产业的数字化升级是大势所趋。矿山行业作为国家能源安全的“压舱石”&#xff0c;也必须进行产业升级。一直以来&#xff0c;国家都在大力推动智慧矿山建设。通过大数据、GIS、物联网、云计算、人工智能等新兴技术&#xff0c;实现矿…