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

这篇具有很好参考价值的文章主要介绍了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和原生模块交互,大概介绍下核心实现逻辑。

Unity3D下如何采集camera场景数据并推送RTMP服务?,Unity RTMP直播推送播放,VR RTMP推送,VR头显 RTMP,AR RTMP,XR RTMP,大牛直播SDK

开始推送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:CBR
                NT_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 4
                NT_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:CBR
                NT_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中,可以通过采集实际场景的画面,将虚拟元素与现实场景进行融合,增强沉浸感和互动性。文章来源地址https://www.toymoban.com/news/detail-690204.html

到了这里,关于Unity3D下如何采集camera场景数据并推送RTMP服务?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity3D学习记录02——PloyBrush场景搭建

    首先在Window-Package Manager里面搜索Poly Brush,下载后将URP的Shader样例导入  导入后Asset文件夹下会有Sample的文件夹,在菜单栏 Tools-PolyBrush-PolyBrush Window 打开窗口 这个窗口最上面的五个,第一个是用来调整地形高低的,第二个是进行柔化场景的,第三个是调整颜色的, 第四个可以

    2024年02月08日
    浏览(59)
  • Unity3D项目之游戏场景小地图制作

    创建一个场景资源,可在asset store资源商店下载,选择心仪场景。 链接:https://assetstore.unity.com/?locale=zh-CN 添加一个对象GameObject,命名为player,子物体包括:主摄像机,角色,后面步骤会添加一个plane。 添加一个地图摄像机,命名为MapCamera。修改属性projection为OrthoGraphic;Size为

    2024年02月11日
    浏览(80)
  • Unity3D在车载导航系统的应用场景浅谈

    Unity3D在车载导航系统的应用场景非常广泛,它可以为车载导航系统带来更加逼真、直观和准确的使用体验。以下是几个具体的应用场景: 3D地图导航:Unity3D的实时3D渲染能力使得车载导航系统可以实现3D地图导航功能。通过Unity3D,可以生成超写实风格的3D地图,提供更加逼真

    2024年01月23日
    浏览(60)
  • Unity3D制作注册登录界面,并实现场景跳转

    效果预览图片: 效果预览视频: 一、新建项目工程 1、打开Unity3D,新建一个项目,将其命名为“Login”。我这里用的版本是Unity2018.4.2f1,不同版本制作过程中的界面可能稍有不同,但是不影响具体功能的实现。 2、可以将样例场景SampleScene重命名为Login,最好做到见名知意。

    2024年02月03日
    浏览(82)
  • Unity3D学习记录01:URP渲染管线以及3D游戏场景设置

    以下内容所使用的版本均为Unity2022.3 先在 Window-Package Manager-Unity Registry 里面搜索添加Universal RP   Unity中,创建渲染管线的方式为Asset文件夹下右键 Create-Readering-URP Asset(with Universal Asset) 会创建以下两个Pipeline:  接着在图中的设置里添加这两个渲染管线(Project Setting在Edit窗口下

    2024年02月08日
    浏览(63)
  • Unity3D教程:触发器实现简单的场景跳转

    首先,需确保有一个想要跳转的目标场景。在本案例中,目标场景是ending。 第一步:创建一个碰撞体,放置在需要的触发场景跳转的位置。 第二步:删除多余的脚本,并且新建自己的脚本: 第三

    2024年02月12日
    浏览(56)
  • 【Unity3D】资源文件 ② ( Unity 中场景文件简介 | 查看场景文件内容 | 场景文件相关操作 | 创建场景 | 打开场景 )

    Unity 编辑器中的 场景文件 是以 \\\" .unity \\\" 为后缀的文件 , 该文件中会记录所有 游戏物体 GameObject , 以及游戏物体的相关数据 , 如下内容都是存储在 场景文件 中的 : 游戏物体 GameObject 节点 : 在 Hierarchy 层级窗口 中 场景文件 下的各个节点 都是游戏物体 , 如 主摄像机 , 光源 , 立

    2024年02月09日
    浏览(58)
  • GameFrameWork框架(Unity3D)使用笔记(八) 实现场景加载进度条

            游戏在转换场景的时候,需要花费时间来加载相关的资源。而这个过程往往因为游戏场景的规模和复杂度以及玩家电脑配置的原因花费一小段时间(虽然这个项目里用不到)。         所以,如果这一小段时间,画面就卡在这里,啥也做不了,玩家也不知道啥时候能

    2024年02月02日
    浏览(49)
  • Unity3d 获取场景中摄像头视频流,实现直播效果(无需代码)

    下面是具体操作流程:   1. 搭建服务器,选用github 一个开源的 node.js服务器。 下载地址GitHub - iizukanao/node-rtsp-rtmp-server: RTSP/RTMP/HTTP hybrid server,点击克隆,选择ZIP下载。  2. 下载node.js( 官网链接 Node.js)   选择下载最新版本,并根据提示一步步安装即可。 3.搭建服务器。 找到

    2023年04月08日
    浏览(42)
  • Unity3d C#实现场景编辑/运行模式下3D模型XYZ轴混合一键排序功能(含源码工程)

    在部分场景搭建中需要整齐摆放一些物品(如仓库中的货堆、货架等),因为有交互的操作在单个模型上,每次总是手动拖动模型操作起来也是繁琐和劳累。 在这背景下,我编写了一个在运行或者编辑状态下都可以进行一键排序模型的脚步。方便在场景搭建时,可以快速搭建

    2024年01月17日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包