如何在Unity3d下实现RTMP推送摄像头/屏幕数据到RTMP服务器

简介:
+关注继续查看

一直以来,好多开发者苦于很难在unity3d下实现RTMP直播推送,本次以大牛直播SDK(Github)的Windows平台RTMP推送模块(以推摄像头为例,如需推屏幕数据,设置相关参数即可)为例,介绍下unity3d的RTMP推送集成。

简单来说,Unity3D环境下,可以直接调用C#的接口封装,针对此,我们先做了一层封装 (nt_publisher_wrapper.cs),核心代码如下:

初始化和基础参数设置:

   private bool InitSDK()
    {
        if (!is_pusher_sdk_init_)
        {
            // 设置日志路径(请确保目录存在)
            String log_path = "D:\\pulisherlog";
            NTSmartLog.NT_SL_SetPath(log_path);

            UInt32 isInited = NTSmartPublisherSDK.NT_PB_Init(0, IntPtr.Zero);

            if (isInited != 0)
            {
                Debug.Log("调用NT_PB_Init失败..");
                return false;
            }

            is_pusher_sdk_init_ = true;
        }

        return true;
    }

    public bool OpenPublisherHandle(uint video_option, uint audio_option)
    {
        if (publisher_handle_ != IntPtr.Zero)
        {
            return true;
        }

        publisher_handle_count_ = 0;

        if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_Open(out publisher_handle_,
            video_option, audio_option, 0, IntPtr.Zero))
        {
            return false;
        }

        if (publisher_handle_ != IntPtr.Zero)
        {
            pb_event_call_back_ = new NT_PB_SDKEventCallBack(PbEventCallBack);

            NTSmartPublisherSDK.NT_PB_SetEventCallBack(publisher_handle_, IntPtr.Zero, pb_event_call_back_);

            return true;
        }
        else
        {
            return false;
        }
    }
    private void SetCommonOptionToPublisherSDK()
    {
        if (!IsPublisherHandleAvailable())
        {
            Debug.Log("SetCommonOptionToPublisherSDK, publisher handle with null..");
            return;
        }

        CameraInfo camera = cameras_[cur_sel_camera_index_];
        NT_PB_VideoCaptureCapability cap = camera.capabilities_[cur_sel_camera_resolutions_index_];

        SetVideoCaptureDeviceBaseParameter(camera.id_.ToString(), (UInt32)cap.width_, (UInt32)cap.height_);

        SetFrameRate((UInt32)CalBitRate(edit_key_frame_, cap.width_, cap.height_));

        SetVideoEncoderType(is_h264_encoder ? 1 : 2);

        SetVideoQualityV2(CalVideoQuality(cap.width_, cap.height_, is_h264_encoder));

        SetVideoMaxBitRate((CalMaxKBitRate(edit_key_frame_, cap.width_, cap.height_, false)));

        SetVideoKeyFrameInterval((edit_key_frame_));

        if (is_h264_encoder)
        {
            SetVideoEncoderProfile(1);

        }

        SetVideoEncoderSpeed(CalVideoEncoderSpeed(cap.width_, cap.height_, is_h264_encoder));

        // 音频相关设置

        SetAuidoInputDeviceId(0);

        SetPublisherAudioCodecType(1);

        SetPublisherMute(is_mute);

        SetInputAudioVolume(Convert.ToSingle(edit_audio_input_volume_));
    }

预览、停止预览:

   public bool StartPreview()
    {
        if(CheckPublisherHandleAvailable() == false)
            return false;

        video_preview_image_callback_ = new NT_PB_SDKVideoPreviewImageCallBack(SDKVideoPreviewImageCallBack);

        NTSmartPublisherSDK.NT_PB_SetVideoPreviewImageCallBack(publisher_handle_, (int)NTSmartPublisherDefine.NT_PB_E_IMAGE_FORMAT.NT_PB_E_IMAGE_FORMAT_RGB32, IntPtr.Zero, video_preview_image_callback_);

        if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPreview(publisher_handle_, 0, IntPtr.Zero))
        {
            if (0 == publisher_handle_count_)
            {
                NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
                publisher_handle_ = IntPtr.Zero;
            }

            return false;
        }

        publisher_handle_count_++;

        is_previewing_ = true;

        return true;
    }

    public void StopPreview()
    {
        if (is_previewing_ == false) return;

        is_previewing_ = false;

        publisher_handle_count_--;
        NTSmartPublisherSDK.NT_PB_StopPreview(publisher_handle_);

        if (0 == publisher_handle_count_)
        {
            NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
            publisher_handle_ = IntPtr.Zero;
        }
    }

开始推送、停止推送:

    public bool StartPublisher(String url)
    {
        if (CheckPublisherHandleAvailable() == false) return false;

        if (publisher_handle_ == IntPtr.Zero)
        {
            return false;
        }
        if (!String.IsNullOrEmpty(url))
        {
            NTSmartPublisherSDK.NT_PB_SetURL(publisher_handle_, url, IntPtr.Zero);
        }

        if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPublisher(publisher_handle_, IntPtr.Zero))
        {
            if (0 == publisher_handle_count_)
            {
                NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
                publisher_handle_ = IntPtr.Zero;
            }

            is_publishing_ = false;

            return false;
        }

        publisher_handle_count_++;

        is_publishing_ = true;

        return true;
    }

    public void StopPublisher()
    {
        if (is_publishing_ == false) return;

        publisher_handle_count_--;
        NTSmartPublisherSDK.NT_PB_StopPublisher(publisher_handle_);

        if (0 == publisher_handle_count_)
        {
            NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
            publisher_handle_ = IntPtr.Zero;
        }

        is_publishing_ = false;
    }

相关event事件回调:

    private void PbEventCallBack(IntPtr handle, IntPtr user_data, 
        UInt32 event_id,
        Int64 param1,
        Int64 param2,
        UInt64 param3,
        UInt64 param4,
        [MarshalAs(UnmanagedType.LPStr)] String param5,
        [MarshalAs(UnmanagedType.LPStr)] String param6,
        IntPtr param7)
    {
        String event_log = "";

        switch (event_id)
        {
            case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTING:
                event_log = "连接中";
                if (!String.IsNullOrEmpty(param5))
                {
                    event_log = event_log + " url:" + param5;
                }
                break;

            case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTION_FAILED:
                event_log = "连接失败";
                if (!String.IsNullOrEmpty(param5))
                {
                    event_log = event_log + " url:" + param5;
                }
                break;

            case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTED:
                event_log = "已连接";
                if (!String.IsNullOrEmpty(param5))
                {
                    event_log = event_log + " url:" + param5;
                }
                break;

            case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_DISCONNECTED:
                event_log = "断开连接";
                if (!String.IsNullOrEmpty(param5))
                {
                    event_log = event_log + " url:" + param5;
                }
                break;

            default:
                break;
        }

        if(OnLogEventMsg != null) OnLogEventMsg.Invoke(event_id, event_log);
    }

SmartPublishWinMono.cs 调用上述封装的代码即可,本地预览的话,拿到回调的RGB数据,在unity3d上层刷下即可,如下图:

win_unity_publisher

经测试,unity3d下,RTMP推送,配合RTMP播放端,依然可以实现毫秒级延迟的推拉流体验。

目录
相关文章
|
17天前
|
Cloud Native 数据可视化 Go
goalng 如何获取 ldap 服务器的数据?
goalng 如何获取 ldap 服务器的数据?
|
23天前
|
监控 安全 数据安全/隐私保护
服务器数据恢复—如何预防服务器故障?发生故障后如何恢复服务器数据?
服务器常见故障: 硬件故障:磁盘、板卡、电源故障等。 软件故障:操作系统崩溃、程序运行错误等。 入侵破坏:加密、删除服务数据等。 不可控力:浸水、火烧、倒塌等。 误操作:格式化、删除、覆盖等。
|
28天前
|
JSON 小程序 前端开发
小程序模拟请求服务器json数据
小程序模拟请求服务器json数据
45 0
|
2月前
|
Linux
迁移Linux服务器用户数据
迁移Linux服务器用户数据
26 0
|
2月前
|
监控 关系型数据库 Linux
Python采集linux服务器数据在Django Web界面展示
Python采集linux服务器数据在Django Web界面展示
|
3月前
|
Web App开发 前端开发 JavaScript
SAP UI5 应用开发教程之八十六 - 动手开发一个最简单的本地 Mock 数据服务器试读版
SAP UI5 应用开发教程之八十六 - 动手开发一个最简单的本地 Mock 数据服务器试读版
28 0
|
3月前
|
测试技术 Android开发
Fiddler服务器响应数据有乱码,怎么办?一文讲清
Fiddler服务器响应数据有乱码,怎么办?一文讲清
|
3月前
|
算法 API 开发工具
Android平台Camera2数据如何对接RTMP推流到服务器
在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。
103 0
|
4月前
|
存储 前端开发 应用服务中间件
区分WEB服务器与数据服务器
WEB服务器和数据服务器是两个不同的概念噢,它们分别承担着不同的任务和功能。
区分WEB服务器与数据服务器
|
4月前
|
算法 安全 Ubuntu
Linux教程丨使用rsync在服务器中高效传输文件,断点续传快速上传下载数据
Linux教程丨使用rsync在服务器中高效传输文件,断点续传快速上传下载数据
相关产品
云迁移中心
推荐文章
更多