• Windows下如何实现Unity3D下的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上层刷下即可,如下图:

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

  • 相关阅读:
    微信小程序UI组件、开发框架、实用库...
    关于Web中的图标使用问题
    通过jQuery Ajax使用FormData对象上传文件
    css3 动画demo
    css知识汇总
    git初体验(三)git分支
    js数组去重的三种常用方法总结
    JavaScript继承方式详解
    面试题连接收集
    城市列表的实例
  • 原文地址:https://www.cnblogs.com/daniulivesdk/p/13086344.html
Copyright © 2020-2023  润新知