SOP TRTC SDK 仪表盘 Android TRTC 发送自定义采集的视频数据 Android TRTC 发送自定义采集音频解决方案 Android TRTC 实现横屏视频通话 iOS端 TRTC 发送自定义采集视频解决方案 iOS端 TRTC 发送自定义采集音频解决方案 APNS推送 脏字过滤 TXLiteAVSDK中使用 AVAudioSession 问题总结 AndroidStudio编译SDK报错 RoomService部署验证 Xcode编译SDK报错 iOS编译库冲突问题 iOS端移动直播自定义采集实现 iOS端TXLiteAVSDK与IMSDK 3.x集成冲突报错问题 Android端TXLiteAVSDK与IMSDK 3.x集成冲突报错问题 Android端LiteIM sdk升级IM4.x版本报错问题 移动直播iOS 12兼容问题 如何实现好的画质 如何计算PCM音量大小 使用播放器播放视频有黑边 直播拉流播放失败 直播拉流端卡顿现象 短视频上传失败 移动直播SDK对接第三方美颜库 移动直播连麦解决方案 Android移动直播推自定义采集的视频数据 Android移动直播推自定义采集的声音数据 Android直播播放如何获取YUV数据 Android直播播放如何自定义渲染 实时音视频画面黑屏 实时音视频订阅流显示 iOS 12默认新编译系统下文件名冲突问题 TXLiteAVSDK指标监控 进阶:小程序实时音视频参数透传 移动直播 Android 9.0 无法拉流问题 移动直播推流事件回调 移动直播拉流事件回调 短视频实现视频缩略图列表转GIF功能 roomService加入群组时报错invalid group id NTP时间戳转换 提示Role not exists 角色不存在 如何播放背景音乐 iOS端短视频添音频相关问题总结 Web同步终端离线推送TIMOfflinePushInfo说明文档 web端自定义消息发送 web端同步终端的已读回执 web端对群组内用户禁言操作 TRTC v2混流接口setMixTranscodingConfig使用指引

Android TRTC 推自定义采集的视频数据

发布时间:2019年3月13日 更新时间:2019年3月13日 贡献者:yyuanchen

如果开发者想在 TRTC 中集成第三方美颜库来实现美颜、滤镜等功能,第三方库的美颜功能输入数据格式支持有 camera 的原始数据(YUV 数据)、纹理数据(Textureid)。开发者想实现该功能,需要采用自定义采集视频数据接口,然后复用 LiteAVSDK 的编码和推流功能。

1.初始化

1)先定义个内部类,然后继承 TRTCCloudListener 抽象类并重写你需要监听的事件(eg:用户加入房间、用户退出房间、警告信息、错误信息等)。

2)获取 TRTCCloud 单例对象,调用 setListener 方法设置 TRTCCloudListener 回调。

public class TRTCMainActivity extends Activity {

    private TRTCCloudDef.TRTCParams trtcParams;     /// TRTC SDK 视频通话房间进入所必须的参数
    private TRTCCloud trtcCloud;              /// TRTC SDK 实例对象
    private TRTCCloudListener trtcListener;    /// TRTC SDK 回调监听

    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //应用运行时,保持屏幕高亮,不锁屏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN);

        //创建 TRTC SDK 实例
        trtcListener = new TRTCCloudListenerImpl(this);
        trtcCloud = TRTCCloud.sharedInstance(this);
        trtcCloud.setListener(trtcListener);

        trtcCloud.setLogLevel(TRTCCloudDef.TRTC_LOG_LEVEL_DEBUG);
        trtcCloud.setConsoleEnabled(true);
    }


    /**
     * SDK内部状态回调
     */
    static class TRTCCloudListenerImpl extends TRTCCloudListener {
        private WeakReference<TRTCMainActivity> mContext;
        public TRTCCloudListenerImpl(TRTCMainActivity activity) {
            super();
            mContext = new WeakReference<>(activity);
        }

        /**
         * 加入房间
         */
        @Override
        public void onEnterRoom(long elapsed) {
            TRTCMainActivity activity = mContext.get();
            if (activity != null) {
                Toast.makeText(activity, "加入房间成功", Toast.LENGTH_SHORT).show();
                activity.mVideoViewLayout.onRoomEnter();
                isPush = true;
            }
        }

        /**
         * 离开房间
         */
        @Override
        public void onExitRoom(int reason) {
            TRTCMainActivity activity = mContext.get();
            if (activity != null) {
                Toast.makeText(activity, "退出房间", Toast.LENGTH_SHORT).show();
                activity.finishActivity();
                isPush = false;
            }
        }
}

2.组装进视频通话房间的参数

TRTCParams 是 SDK 最关键的一个参数,它包含如下四个必填的字段 sdkAppIduserIduserSigroomId

Android

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ....
    //创建 TRTC SDK 实例
    trtcListener = new TRTCCloudListenerImpl(this);
    trtcCloud = TRTCCloud.sharedInstance(this);
    trtcCloud.setListener(trtcListener);

    // TRTC SDK 视频通话房间进入所必须的参数
    Intent intent       = getIntent();
    int sdkAppId        = intent.getIntExtra("sdkAppId", 0);
    int roomId          = intent.getIntExtra("roomId", 0);
    String selfUserId   = intent.getStringExtra("userId");
    String userSig      = intent.getStringExtra("userSig");

    trtcParams = new TRTCCloudDef.TRTCParams(sdkAppId, selfUserId, userSig, roomId, "", "");
}

3. 大小画面编码器参数设置

设置本地大画面(上行)、远端小画面(远端观众、下行)的编码参数

Android

private void setTRTCCloudParam() {
    // 大画面的编码器参数设置
    // 设置视频编码参数,包括分辨率、帧率、码率等等,这些编码参数来自于 TRTCSettingDialog 的设置
    // 注意(1):不要在码率很低的情况下设置很高的分辨率,会出现较大的马赛克
    // 注意(2):不要设置超过25FPS以上的帧率,因为电影才使用24FPS,我们一般推荐15FPS,这样能将更多的码率分配给画质
    TRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();
    encParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_640_480;
    encParam.videoFps = 15;
    encParam.videoBitrate = 600;
    encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT; 
    trtcCloud.setVideoEncoderParam(encParam);

    TRTCCloudDef.TRTCNetworkQosParam qosParam = new TRTCCloudDef.TRTCNetworkQosParam();
    qosParam.controlMode    = TRTCCloudDef.VIDEO_QOS_CONTROL_SERVER;
    qosParam.preference     = TRTCCloudDef.TRTC_VIDEO_QOS_PREFERENCE_CLEAR;
    trtcCloud.setNetworkQosParam(qosParam);

    //小画面的编码器参数设置
    //TRTC SDK 支持大小两路画面的同时编码和传输,这样网速不理想的用户可以选择观看小画面
    //注意:iPhone & Android 不要开启大小双路画面,非常浪费流量,大小路画面适合 Windows 和 MAC 这样的有线网络环境
    TRTCCloudDef.TRTCVideoEncParam smallParam = new TRTCCloudDef.TRTCVideoEncParam();
    smallParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_160_90;
    smallParam.videoFps = 15;
    smallParam.videoBitrate = 100;
    smallParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;  
    trtcCloud.enableEncSmallVideoStream(false, smallParam);

    trtcCloud.setPriorRemoteVideoStreamType(settingDlg.priorSmall?TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SMALL:TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
}

4 . 开启自定义采集配置,加入房间

设置 enableCustomVideoCapture 值为 true,告知 TRTC SDK 使用自定义采集数据。然后使用步骤3组装的 TRTCCloudParam 进入房间。

private void enterRoom() {
    // 预览前配置默认参数
    setTRTCCloudParam();
    // 【重要】设置自定义采集数据方法【一定要开启】
    trtcCloud.enableCustomVideoCapture(true);
    //进房
    trtcCloud.enterRoom(trtcParams, TRTCCloudDef.TRTC_APP_SCENE_VIDEOCALL);
}

5. 发送自定义采集数据

根据数据类型,构造自定义数据 TRTCVideoFrame 对象,然后调用发送自定义数据接口 trtcCloud.sendCustomVideoData(trtcVideoFrame) 将数据塞给 TRTC SDK。

// 这里以发送摄像头回调数据为例子
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
    if (!isPush) {
//            Log.i(TAG, "length of data === " + data.length);
    } else {
        // 开始自定义推流

        // 一般前置摄像头有270度的旋转,后置摄像头有90的旋转。所以要对YUV数据进行一定旋转操作
        // 这里使用到前置摄像头, 所以旋转 270 度
        // 如果使用到后置摄像头, 请自行处理
        byte[] ratateBuffer = new byte[data.length];
        ratateBuffer = rotateYUVDegree270(data, mPreviewWidth, mPreviewHeight);

        Log.i(TAG, "previewSize:width: " + mPreviewWidth + " height: " + mPreviewHeight);

        TRTCCloudDef.TRTCVideoFrame trtcVideoFrame = new TRTCCloudDef.TRTCVideoFrame();
        trtcVideoFrame.data = data;
        trtcVideoFrame.bufferType = TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_BYTE_ARRAY;
        trtcVideoFrame.pixelFormat = TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_NV21;
        trtcVideoFrame.height = mPreviewWidth;
        trtcVideoFrame.width = mPreviewHeight;
        trtcCloud.sendCustomVideoData(trtcVideoFrame);
    }
}

/**
 * 对前置摄像头采集到的数据做 270 度的旋转
 * @param data
 * @param imageWidth
 * @param imageHeight
 * @return
 */
private byte[] rotateYUVDegree270(byte[] data, int imageWidth, int imageHeight) {
    byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
    // Rotate the Y luma
    int i = 0;
    for (int x = imageWidth - 1; x >= 0; x--) {
        for (int y = 0; y < imageHeight; y++) {
            yuv[i] = data[y * imageWidth + x];
            i++;
        }
    }// Rotate the U and V color components
    i = imageWidth * imageHeight;
    for (int x = imageWidth - 1; x > 0; x = x - 2) {
        for (int y = 0; y < imageHeight / 2; y++) {
            yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
            i++;
            yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
            i++;
        }
    }
    return yuv;
}

注意事项

  1. 什么时候调用发送自定义数据接口呢?
    最好是确保用户进入房间成功,再调用 sendCustomVideoData() 接口。因此,例子中使用到变量 isPush 作为标记。定义该变量值为 false,当 trtcCloud 收到用户进入收到用户成功回调时,将其设置为 true 即可(具体见步骤1)。

  2. 使用自定义采集数据,哪些 SDK 接口方法无须使用?
    使用自定义采集接口,就不需要开始本地摄像头预览接口,即 startLocalPreview(true, localTXCloudVideoView)。另外,您自定义采集视频数据,SDK 还是会采集音频数据。

  3. TRTCVideoFrame 对象说明

名称 类型 描述
buffer ByteBuffer 视频数据(BUFFER)
bufferType int 数据缓冲区类型
TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_BYTE_ARRAY
TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_BYTE_BUFFER
data byte[] 视频数据(ARRAY)
height int 视频高度
pixelFormat int 视频类型
TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_I420
TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_Texture_2D
TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_TEXTURE_EXTERNAL_OES
TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_NV21
rotation int 视频角度
textureId int 纹理id(pixelFormat为Texture_2D 或 TEXTURE_EXTERNAL_OES)
width int 视频宽度
  1. TRTCSDK 支持发送那些数据格式类型 目前 Android 系统只支持TRTC_VIDEO_PIXEL_FORMAT_I420TRTC_VIDEO_PIXEL_FORMAT_NV21数据格式,后续版本支持其他两种格式。

相关参考文档:


results matching ""

    No results matching ""