音视频通话 2.0
Android
动态与公告
更新日志(V4.6)
更新日志(V5)
活动与公告
【活动】音视频通话内容安全检测限时补贴
【活动】赠送100万分钟音视频通话时长
【邀测】音视频通话2.0V5.3邀请公测
新手接入指南
产品简介
产品介绍
功能特性
产品优势
应用场景
基本概念
使用限制
性能指标
产品计费
按量计费
资源包
体验 Demo
下载 SDK 和示例代码
升级指南
快速开始
快速跑通 Sample Code
接入流程
创建应用
开通服务
集成 SDK
实现音视频通话
Token 鉴权
高级 Token 鉴权
基础功能
设置音频属性
设置视频属性
设置视频旋转方向
设置通话音量
屏幕共享
音频共享
监测发言者音量
通话前网络质量探测
通话中质量监测
进阶功能
音频管理
客户端音频录制
原始音频数据
美声变声与混响
耳返
自定义音频采集与渲染
音效与伴音
设置音频订阅优先级
音频裸流传输
媒体补充增强信息SEI
视频管理
视频截图
水印
云信美颜
相芯美颜
自定义视频采集
虚拟背景
视频图像畸变矫正
视频裸流传输
多房间管理
设备管理
视频设备管理
音频设备管理
媒体流管理
跨房间媒体流转发
媒体流加密
视频流回退
云端录制
使用云代理
本地服务端录制
AI 融合功能
AI 超分
AI 降噪
场景实践
1 对 1 娱乐社交
语聊房
PK连麦
在线教育
互联网问诊
最佳实践
音视频参数配置推荐
房间连接状态管理
实现音视频安全检测
轻松构建本土Clubhouse
API 参考
Android API 参考
服务端 API
错误码(V5)
错误码(V4.x)
控制台指南
常见问题处理
FAQ
错题集
获取音频 Dump 文件
音频常见问题排查
视频常见问题排查
服务协议

自定义视频采集

更新时间: 2023/05/17 10:40:07

NERTC SDK 提供自定义视频采集功能,帮助您向 NERTC SDK 提供自定义的视频输入源数据(外部视频输入),并由 NERTC SDK 进行编码推流。本文档为您介绍如何通过 setExternalVideoSourcepushExternalVideoFrame 方法实现自定义视频采集功能。

功能描述

一般情况下,App 采用默认设备采集视频数据,通常是本设备的摄像头模块。但在部分场景下可能需要使用自定义的视频源,例如:

  • 由第三方美颜 SDK 负责视频数据采集和视频数据的前处理,NERTC 负责视频数据编码和云端推流。
  • 某些视频采集设备被系统独占。为避免与其它业务产生冲突,需要灵活的设备管理策略。例如,直播过程中需要录制短视频。
  • 需要使用外部视频源,例如播放本地视频文件、屏幕共享、游戏直播等。

基于以上场景,NERTC SDK 支持使用自定义的视频源,以实现您在实际业务场景中的相关需求。

V5.3.0 及之后版本,子房间支持调用 NERtcChannel#setExternalVideoSourceNERtcChannel#pushExternalVideoFrame 设置外部视频输入。

技术原理

NERTC SDK 目前提供 Push 数据源的方式实现自定义的视频源。Push 方式下,NERTC SDK 会根据设置的 NERtcVideoFrame中的 heightwidth 值,对数据源进行裁剪或缩放。视频的帧率由数据源自身控制。

在 Push 模式下进行视频源自定义时,视频数据的传输过程如下图所示。

自定义视频采集.png

注意事项

  • 自定义视频采集场景中,您需要自行实现视频数据的采集和处理。

  • 若您需要开启外部视频采集,建议在创建外部视频输入源之前调用 enableLocalVideo 方法关闭本地视频设备采集(若未打开则无需关心),再在创建外部视频输入源之后再次调用 enableLocalVideo 方法开启媒体传输通道。

  • 请先开启外部视频输入(setExternalVideoSource),再开启本地视频预览(NERtc#startVideoPreview )或开启媒体传输通道(enableLocalVideo )。

  • 当外部视频源输入作为主流或辅流时,内部引擎为启用状态,在切换房间(switchChannel)、主动离开房间(leaveChannel)、断网重连失败(onDisconnect)或重新加入房间(onReJoinChannel)后仍然有效。如果需要关闭该功能,请在下次通话前调用接口关闭该功能。

  • 视频主流和辅流通道分别只能传输一个视频输入源,例如:

    • 若您已经开启了屏幕共享(使用辅流通道),则外部输入的视频源只能使用主流通道。
    • 若您在 enableLocalVideo 中已通过主流传输本设备的摄像头数据,则外部输入的视频源只能使用辅流通道。

实现方法

API 调用时序

sequenceDiagram
    participant 应用层
    participant NERtcSDK
    应用层->>NERtcSDK: init 初始化 SDK
    应用层->>NERtcSDK: enableLocalVideo(false) 关闭本地视频设备采集
    应用层->>NERtcSDK: setLocalVideoConfig 设置视频参数
    rect rgb(191, 223, 255)
    应用层 ->> NERtcSDK: setExternalVideoSource 开启外部视频源数据输入
    end
    Note over 应用层, NERtcSDK: 请自行实现视频数据采集和处理
    应用层->>NERtcSDK: enableLocalVideo(true) 开启媒体传输通道
    应用层->>NERtcSDK: joinChannel 加入房间
    NERtcSDK-->>应用层: onJoinChannel
    rect rgb(191, 223, 255)
    应用层 ->> NERtcSDK: pushExternalVideoFrame 将视频数据发送给 NERtc SDK
    end

配置步骤

NERTC SDK 提供 Push 数据源的方式实现自定义的视频源。Push 方式下,NERTC SDK 会根据设置的视频 Profile 对数据源进行裁剪或缩放,来达到发送目标分辨率,同时视频的帧率由数据源自身控制。

参考如下步骤,在您的项目中通过 Push 方式实现自定义视频源功能:

  1. 关闭本地视频设备采集。

    调用 enableLocalVideo 方法,设置 enable 参数为 false,并设置 streamTypekNERtcVideoStreamTypeMain(主流) 或 kNERtcVideoStreamTypeSub(辅流)。

  2. 设置基本的视频参数。

    调用setLocalVideoConfig 方法,设置基本的视频参数,特别是 widthheightframeRate 三个重要参数,要与真实的外部输入一致,否则会影响视频质量。

  3. 开启外部视频源数据输入。

    调用 setExternalVideoSource 方法,设置 enable 参数为 true,并设置 streamTypekNERtcVideoStreamTypeMain(主流) 或 kNERtcVideoStreamTypeSub(辅流)。

  4. 开启媒体传输通道。

    调用 enableLocalVideo 方法,设置 enable 参数为 true,并设置 streamTypekNERtcVideoStreamTypeMain(主流) 或 kNERtcVideoStreamTypeSub(辅流)。

  5. 指定外部采集设备后,您需要自行实现视频数据采集和处理,具体实现方法请参考 ExternalVideo 示例项目源码

  6. (可选)设置视频旋转方向。

    当设备方向变化后,您可以通过如下方式实现横竖屏切换:

    在将视频数据发送给 NERTC SDK 前,通过 NERtcVideoFrame 设置视频的方向。例如,设置 rotation 为 90,使视频帧顺时针旋转 90 度。

  7. 将外部视频帧的数据发送给 NERTC SDK。

    完成视频数据处理后,调用 pushExternalVideoFrame 方法将视频数据发送给 NERTC SDK 进行后续操作;调用此方法时,您需要通过 frame 参数传入外部视频帧的数据信息,并设置 streamTypekNERtcVideoStreamTypeMain(主流) 或 kNERtcVideoStreamTypeSub(辅流)。

示例项目源码

网易云信提供 自定义视频采集的示例项目源码 ExternalVideoShare,您可以参考该源码实现自定义视频采集。

示例代码

     //以开启主流外部视频输入为例

        //1. 先关闭之前的视频主流
        NERtcEx.getInstance().enableLocalVideo(kNERtcVideoStreamTypeMain,false);

        //2. 设置视频参数
        NERtcVideoConfig videoConfig  = new NERtcVideoConfig();
        videoConfig.width = sourceWidth;//1280
        videoConfig.height = sourceHeight;//720
        videoConfig.frameRate = NERtcEncodeConfig.NERtcVideoFrameRate.FRAME_RATE_FPS_15;
        NERtcEx.getInstance().setLocalVideoConfig(videoConfig,kNERtcVideoStreamTypeMain);

        //3. 开启外部视频源数据输入
        NERtcEx.getInstance().setExternalVideoSource(kNERtcVideoStreamTypeMain,true);


        //4. 开启媒体传输通道
        NERtcEx.getInstance().enableLocalVideo(kNERtcVideoStreamTypeMain,true);

        //5. 在合适线程将外部视频帧的数据发送给 NERTC SDK , 尽量保证数据推送的稳定性,不要忽慢忽快
        NERtcVideoFrame frame = new NERtcVideoFrame();
        frame.data = xxx;
        frame.width = sourceWidth;//1280
        frame.height = sourceHeight;//720
        frame.format = NERtcVideoFrame.Format.I420;//以I420 为例子,请填写真实数据类型
        frame.rotation = 0 ;
        NERtcEx.getInstance().pushExternalVideoFrame(kNERtcVideoStreamTypeMain,frame);

API 参考

方法 功能描述
enableLocalVideo 开启或关闭媒体传输通道
setLocalVideoConfig 设置视频参数
setExternalVideoSource 开启外部视频源数据输入
pushExternalVideoFrame 推送外部视频数据帧

常见问题

  • 自定义视频源支持哪些数据格式?

    自定义视频源的数据格式支持 I420、NV21、RGBA、TEXTURE_OES 和 TEXTURE_RGB。

  • 自定义视频采集的分辨率和setLocalVideoConfig中设置的视频分辨率不一致时,以哪个分辨率为准?

    pushExternalVideoFrame 输入的视频分辨率和 setLocalVideoConfig 中设置的分辨率、画布比例不一致时,例如pushExternalVideoFrame的分辨率为640 x 480(4:3)、setLocalVideoConfig的分辨率为1280 x 720(16:9),NERTC SDK 的推流视频处理逻辑如下:

    1. 画布比例采用 setLocalVideoConfig 中设置的画布比例,本示例中为 16:9。
    2. 将自定义视频采集的分辨率(本示例中为 640 x 480)按照setLocalVideoConfig 中设置的画布比例(本示例中为 16:9)进行裁剪,得到一个新的分辨率(640 x 360)。
    3. 根据上一步得到的新分辨率和setLocalVideoConfig 中的分辨率,取两者中较小的分辨率作为推流分辨率。因此,本示例中最终的视频分辨率为 640 x 360。
此文档是否对你有帮助?
有帮助
我要吐槽
  • 功能描述
  • 技术原理
  • 注意事项
  • 实现方法
  • API 调用时序
  • 配置步骤
  • 示例项目源码
  • 示例代码
  • API 参考
  • 常见问题