Unity环境下实现Camera高帧率RTMP推送

简介: Unity下RTMP直播背景方面不再赘述,今天主要讨论的是,Unity环境下,如何实现Camera高帧率RTMP推送,这里提到的高帧率,不再局限于常规环境下的30帧,以VR头显为例,更高的帧率(比如50帧),体验会更好。

Unity下RTMP直播背景方面不再赘述,今天主要讨论的是,Unity环境下,如何实现Camera高帧率RTMP推送,这里提到的高帧率,不再局限于常规环境下的30帧,以VR头显为例,更高的帧率(比如50帧),体验会更好。

1851fdf3cecadecb9d6a467e6ebf5e26.jpg

Android平台Unity推送Camera

160f79affe4fc7e9e1d83f221e377273.png

Windows平台Unity推送Camera


之前,我们老早实现了Unity环境下的RTMP低延迟推送,原生环境下,比如windows下,可轻松实现50帧+的编码和RTMP推送(需要播放端也有高帧率播放的能力)。


好多开发者对这块比较感兴趣,今天分享几个点,权当抛砖引玉:


1.数据源:拿到期望的高帧率数据是基础,以Android或Windows的Unity环境为例,如果你想推50帧,起码camera能每秒读到超过50帧的数据,这个在好多开发者看来,可能觉得不是难事,实际你会发现,在复杂场景下,ReadPixel()耗时还是比较大的,特别是Android端;


2.数据读取和数据投递、编码等拆分,确保不至于因为数据投递、编码等,彼此相互影响;


3.针对横竖屏或camera分辨率实时变化的处理;


4.编码瓶颈:高帧率环境下,如果是windows还好,android端,编超过30帧,特别是分辨率比较大的话还是吃力的,这时候需要酌情考虑硬编或高效的软编方案,一般来说,建议H.264;


5.帧率控制:帧率控制这块,好多开发者可能会忽略,比如,我每秒需要编45帧,实际可以拿到60帧数据,如何用合理的算法处理数据,确保投递60帧数据,编码45帧(drop 15帧)的情况下,还能流畅无卡顿感,在设备无性能瓶颈的情况下,如何实现设置45帧,实际编码出来45帧数据;


6.音频方面:一般来说,常用的无非几种组合模式:麦克风、Unity内部音频、麦克风+unity内部音频混音或Unity下2路内部音频混音,麦克风的话,可以原生实现,然后直接调用即可,Unity内部音频可以通过AudioClip读取数据,编码的话,考虑到通用性,一般建议AAC;


Frame的构建,可以参考一下设计:

/*
* FrameTexture构建
* WebSite: https://github.com/daniulive/SmarterStreaming
*/
public class FrameTexture {
  public FrameTexture(Texture2D texture, int is_vertical_flip, int is_horizontal_flip, int scale_width, int scale_height) {
    texture_ = texture;
    is_vertical_flip_ = is_vertical_flip;
    is_horizontal_flip_ = is_horizontal_flip;
    scale_width_ = scale_width;
    scale_height_ = scale_height;
  }
  public Texture2D texture_ ;
  public int is_vertical_flip_ ;
  public int is_horizontal_flip_;
  public int scale_width_;
  public int scale_height_;
}

数据投递接口设计(Android):

/**
   * 投递层RGBA8888图像,如果不需要Aplpha通道的话, 请使用RGBX8888接口, 效率高
   *
   * @param index: 层索引, 必须大于等于0, 注意:如果index是0的话,将忽略Alpha通道
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param rgba_plane: rgba 图像数据
   *
   * @param offset: 图像偏移, 这个主要目的是用来做clip的, 一般传0
   *
   * @param row_stride: stride information
   *
   * @param width: width, 必须大于1, 如果是奇数, 将减1
   *
   * @param height: height, 必须大于1, 如果是奇数, 将减1
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBA8888ByteBuffer(long handle, int index, int left, int top,
                       ByteBuffer rgba_plane, int offset, int row_stride, int width, int height,
                       int is_vertical_flip,  int is_horizontal_flip,
                       int scale_width,  int scale_height, int scale_filter_mode,
                       int rotation_degree);
  /**
   * 投递层RGBA8888图像, 详细说明请参考PostLayerImageRGBA8888ByteBuffer
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBA8888ByteArray(long handle, int index, int left, int top,
                            byte[] rgba_plane, int offset, int row_stride, int width, int height,
                            int is_vertical_flip,  int is_horizontal_flip,
                            int scale_width,  int scale_height, int scale_filter_mode,
                            int rotation_degree);

Windows的话,构建图层:

NT_PB_ExternalVideoFrameLayerConfig external_layer_c1 = new NT_PB_ExternalVideoFrameLayerConfig();
external_layer_c1.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME;
external_layer_c1.base_.index_ = 0;
external_layer_c1.base_.enable_ = 1;
external_layer_c1.base_.region_.x_ = 0;
external_layer_c1.base_.region_.y_ = 0;
external_layer_c1.base_.region_.width_ = video_width_;
external_layer_c1.base_.region_.height_ = video_height_;
external_layer_c1.base_.offset_ = Marshal.OffsetOf(external_layer_c1.GetType(), "base_").ToInt32();
external_layer_c1.base_.cb_size_ = (uint)Marshal.SizeOf(external_layer_c1);
IntPtr external_layer_conf = Marshal.AllocHGlobal(Marshal.SizeOf(external_layer_c1));
Marshal.StructureToPtr(external_layer_c1, external_layer_conf, true);
UInt32 external_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
                                                             external_layer_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME,
                                                             0, IntPtr.Zero);
Marshal.FreeHGlobal(external_layer_conf);


然后通过NT_PB_PostLayerImage()给图层投递数据即可:

/*
         * 给index层投递Image数据,目前主要是用来把rgb和yuv视频数据传给相关层
         * reserve: 保留字段,请传0
         * index: 层索引
         * image: 图像
         * flag: 请传0
         * pReserve: 保留字段,请传0
         * 
         * 成功返回 NT_ERC_OK
     */
[DllImport("SmartPublisherSDK", EntryPoint = "NT_PB_PostLayerImage", CallingConvention = CallingConvention.StdCall)]
        public static extern UInt32 NT_PB_PostLayerImage(IntPtr handle, Int32 reserve,
                                                         Int32 index, IntPtr image,
                                                         UInt32 flag, IntPtr pReserve);

以上是Unity环境下高帧率RTMP推送一点抛砖引玉的介绍,实际开发过程中,可能还需要考虑多实例、异常网络环境处理等各种情况,如果原生开发这块,有很好的积累,这块都不难。

相关文章
|
1天前
|
图形学 异构计算
蓝易云 - Unity下如何实现低延迟的全景RTMP|RTSP流渲染
以上就是在Unity中实现低延迟的全景RTMP/RTSP流渲染的基本步骤。具体的实现可能会根据你的具体需求和所使用的库有所不同。
11 0
|
22天前
|
数据采集 编解码 图形学
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
132 0
|
9月前
|
编解码 数据处理 vr&ar
VR头显Unity下如何实现毫秒级延迟的RTMP或RTSP播放?
VR头显Unity下如何实现毫秒级延迟的RTMP或RTSP播放?
189 1
|
9月前
|
Linux 开发工具 图形学
Unity下如何实现RTMP或RTSP播放端录像?
Unity下如何实现RTMP或RTSP播放端录像?
236 0
|
9月前
|
编解码 开发工具 图形学
Unity环境下RTMP推流+RTMP播放低延迟解决方案
在本文之前,我们发布了Unity环境下的RTMP推流(Windows平台+Android平台)和RTMP|RTSP拉流(Windows平台+Android平台+iOS平台)低延迟的解决方案,今天做个整体汇总,权当抛砖引玉。
463 0
|
9月前
|
编解码 监控 vr&ar
Unity3D下如何采集camera场景数据并推送RTMP服务?
Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下:
|
9月前
|
编解码 监控 图形学
Windows平台Unity下播放RTSP或RTMP如何开启硬解码?
我们在做Windows平台Unity播放RTMP或RTSP的时候,遇到这样的问题,比如展会、安防监控等场景下,需要同时播放多路RTMP或RTSP流,这样对设备性能,提出来更高的要求。
104 1
|
9月前
|
图形学 开发者 Windows
Unity平台如何实现RTSP转RTMP推送?
Unity平台下,RTSP、RTMP播放和RTMP推送,甚至包括轻量级RTSP服务这块都不再赘述,今天探讨的一位开发者提到的问题,如果在Unity下,实现RTSP播放的同时,随时转RTMP推送出去?
|
9月前
|
Linux 图形学 Android开发
Unity3D下如何实现跨平台低延迟的RTMP、RTSP播放
好多开发者,希望我们能探讨下Unity平台RTMP或RTSP直播流数据播放和录制相关的模块,实际上,这块流程我们已经聊过多次,无非就是通过原生的RTMP或者RTSP模块,先从协议层拉取到数据,并解包解码,回调YUV或RGB数据,然后,在Unity创建响应的shader,获取图像数据填充纹理即可,说起来流程很简单,但是每个环节,如果做到极致体验,都非常难。简单来说,多一次拷贝,都会增大性能瓶颈或延迟。
|
9月前
|
数据采集 vr&ar 图形学
Windows平台Unity Camera场景实现轻量级RTSP服务和RTMP推送
随着VR技术在医疗、军事、农业、学校、景区、消防、公共安全、研学机构、展厅展馆,商场等场所普及,开发者对Unity平台下的直播体验提出了更高的要求。