自定义视频采集

功能介绍

ARTC SDK支持客户自定义视频采集的功能,客户通过此功能实现自定义管理视频设备,且阿里云支持动态切换内部采集和外部采集。

实现步骤

image

代码实现

打开或关闭内部采集

  • android平台

    /* 关闭内部采集 */
    mAliRtcEngine.enableLocalVideo(false);
    
    /* 打开内部采集,阿里内部默认状态是true,所以如果不需要控制的情况下不需要调用此api */
    mAliRtcEngine.enableLocalVideo(true);
  • ios平台

    /* 关闭内部采集 */
    [_engine enableLocalVideo:NO];
    
    /* 打开内部采集,阿里内部默认状态是true,所以如果不需要控制的情况下不需要调用此api */
    [_engine enableLocalVideo:YES];

开启或关闭外部视频源

  • android平台

    • YUV方式输入示例

      /* YUV方式输入 */
      /* 打开外部采集,这里以camera流为例,具体可以根据sourceType指定,渲染模式也可以根据需要指定 */
      mAliRtcEngine.setExternalVideoSource(true,false, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
      
      /* 关闭外部采集,这里以camera流为例,具体可以根据sourceType指定 */
      mAliRtcEngine.setExternalVideoSource(false,false, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
    • 纹理方式输入示例

      /* 纹理方式输入 */
      /* 打开外部采集,这里以camera流为例,具体可以根据sourceType指定,渲染模式也可以根据需要指定 */
      mAliRtcEngine.setExternalVideoSource(true,true, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
      
      /* 关闭外部采集,这里以camera流为例,具体可以根据sourceType指定 */
      mAliRtcEngine.setExternalVideoSource(false,true, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
  • ios平台

    /* 打开外部采集,这里以camera流为例,具体可以根据sourceType指定,渲染模式也可以根据需要指定 */
    [_engine setExternalVideoSource:YES sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto]; 
    
    /* 关闭外部采集,这里以camera流为例,具体可以根据sourceType指定 */
    [_engine setExternalVideoSource:NO sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto]; 

SDK输入外部的视频源

  • android平台

    • YUV方式输入示例:

      /* 以YUV(I420)格式为例 */
      int width = 720;
      int height = 1280;
      AliRtcEngine.AliRtcVideoFormat videoformat = AliRtcEngine.AliRtcVideoFormat.AliRtcVideoFormatI420;
      int[] lineSize = {width, width / 2, width / 2, 0};
      int frameLength = width * height * 3 / 2;
      byte[] buffer = new byte[frameLength];
      
      /* 构造传入SDK的数据对象 */
      AliRtcEngine.AliRtcRawDataFrame rawDataFrame
              = new AliRtcEngine.AliRtcRawDataFrame(buffer,
                                                   videoformat,
                                                   width, 
                                                   height, 
                                                   lineSize, 
                                                   0, 
                                                   buffer.length);
      
      /* 调用API传入数据对象 */
      int ret = mAliRtcEngine.pushExternalVideoFrame(rawDataFrame, AliRtcVideoTrackCamera);
      if (ret != 0) {
          /* 打印下错误信息 */
      }
    • 纹理方式输入示例:

      /* 以纹理格式为例 */
      /* 构造opengl的环境 */
      private static EglBase14 createEglBase14(EGLContext shareEglContext) {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
              EglBase14.Context eglBase14Context = shareEglContext == null ? null : new EglBase14.Context(shareEglContext);
              EglBase14 eglBase14 = new EglBase14(eglBase14Context, EglBase.CONFIG_PIXEL_BUFFER);
              try {
                  eglBase14.createDummyPbufferSurface();
                  eglBase14.makeCurrent();
              } catch (RuntimeException e) {
                  eglBase14.release();
                  Log.e(TAG, "CreateEGLBase14Context, failed, " + e.getMessage());
              }
              return eglBase14;
          }
          return null;
      }
      
      /* 构造传入的数据上下文 */
      float[] transformMatrix = {
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
      };
      int frameWidth = 720; /* 图像的宽 */
      int frameHeight = 1280; /* 图像的高 */
      int textureID = xxx; /* 用户自己的纹理id */
      
      AliRtcEngine.AliRtcRawDataFrame aliRawDataFrame 
        = new AliRtcEngine.AliRtcRawDataFrame(textureID,
                                              AliRtcVideoFormatTexture2D,
                                              frameWidth, 
                                              frameHeight, 
                                              transformMatrix, 
                                              0, 
                                              0, 
                                              frameWidth, 
                                              frameHeight, 
                                              mEglBase14.getEglContext());
      
      /* 调用API传入数据对象 */
      int ret = mAliRtcEngine.pushExternalVideoFrame(aliRawDataFrame, AliRtcVideoTrackCamera);
      if (ret != 0) {
          /* 打印下错误信息 */
      }
  • ios平台

    /* 按照自己的数据格式填写以下内容,下面以I420格式为例 */
    AliRtcVideoDataSample *dataSample = [[AliRtcVideoDataSample alloc] init];
    dataSample.dataPtr = (long)yuv_read_data;
    dataSample.format = AliRtcVideoFormat_I420;
    dataSample.type = AliRtcBufferType_Raw_Data;
    dataSample.width = width;
    dataSample.height = height;
    dataSample.strideY = width;
    dataSample.strideU = width/2;
    dataSample.strideV = width/2;
    dataSample.dataLength = dataSample.strideY * dataSample.height * 3/2;
    
    /* 调用API传入数据对象 */
    int ret = [self.engine pushExternalVideoFrame:dataSample sourceType:AliRtcVideosourceCameraType];
    if (ret != 0) {
        /* 打印下错误信息 */
    }