如何在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播放端,依然可以实现毫秒级延迟的推拉流体验。

目录
相关文章
|
2月前
|
存储 安全 PHP
通过eXtplorer+cpolar,搭建个人云存储并实现访问内网服务器数据
通过eXtplorer+cpolar,搭建个人云存储并实现访问内网服务器数据
39 0
|
3月前
|
存储 弹性计算 安全
ECS技术专家教你如何保证业务数据全流程安全
本文内容整理自【弹性计算技术公开课——ECS安全季】中阿里云弹性计算技术专家陈怀可带来的课程《如何保证业务数据的全流程安全》。
156078 106
|
3月前
|
数据挖掘 Windows
【服务器数据恢复】服务器迁移数据时数据丢失的数据恢复案例
一台安装Windows操作系统的服务器。工作人员在迁移该服务器中数据时突然无法读取数据,服务器管理界面出现报错。经过检查发现服务器中一个lun的数据丢失。
|
22天前
|
弹性计算 网络安全 虚拟化
ECS数据问题之升级配置预防数据丢失如何解决
ECS(Elastic Compute Service,弹性计算服务)是云计算服务提供商提供的一种基础云服务,允许用户在云端获取和配置虚拟服务器。以下是ECS服务使用中的一些常见问题及其解答的合集:
|
25天前
|
安全 数据处理 C#
C# Post数据或文件到指定的服务器进行接收
C# Post数据或文件到指定的服务器进行接收
|
1月前
|
消息中间件 关系型数据库 MySQL
Flink CDC产品常见问题之把flink cdc同步的数据写入到目标服务器失败如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
3月前
|
存储 数据挖掘 数据库
服务器RAID0:提高数据传输速度 (服务器raid0作用)与RAID1的区别
服务器RAID0:提高数据传输速度 (服务器raid0作用)与RAID1的区别
|
3月前
|
数据采集 编解码 图形学
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
100 0
|
3月前
|
应用服务中间件 nginx Windows
ffmpeg推流到nginx服务器,并使用vlc播放rtmp视频
ffmpeg推流到nginx服务器,并使用vlc播放rtmp视频
|
4月前
|
XML JSON Apache
【Android】如何获得Apache服务器的JSON文件数据
【Android】如何获得Apache服务器的JSON文件数据
56 0