前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >trtc-electron音视频学习初体验

trtc-electron音视频学习初体验

原创
作者头像
金林学音视频
发布2020-10-31 16:01:55
1.2K0
发布2020-10-31 16:01:55
举报

适用场景

TRTC 支持四种不同的进房模式,其中视频通话(VideoCall)和语音通话(VoiceCall)统称为通话模式,视频互动直播(Live)和语音互动直播(VoiceChatRoom)统称为 直播模式。在学习测试中主要使用到VideoCall和VoiceCall模式 通话模式下的 TRTC,支持单个房间最多300人同时在线,支持最多30人同时发言。适合1对1视频通话、300人视频会议、在线问诊、远程面试、视频客服、在线狼人杀等应用场景

原理解析

TRTC 云服务由两种不同类型的服务器节点组成,分别是“接口机”和“代理机”:

  • 接口机 该类节点都采用最优质的线路和高性能的机器,善于处理端到端的低延时连麦通话,单位时长计费较高。
  • 代理机 该类节点都采用普通的线路和性能一般的机器,善于处理高并发的拉流观看需求,单位时长计费较低。
  • 通话示例

在通话模式下,TRTC 房间中的所有用户都会被分配到接口机上,相当于每个用户都是主播,都可以进行推流。

使用流程

集成使用

代码语言:javascript
复制
npm install trtc-electron-sdk --save
代码语言:javascript
复制
import TRTCCloud from 'trtc-electron-sdk';
let trtcCloud = new TRTCCloud();

此外在从trtc-electron-sdk/liteav/trtc_define中导入进房需要的TRTCParams实例。

vue项目开发

1获取承载DOM的节点

this.videoContainer = document.querySelector('#video-container');

2.计算签名

this.sdkInfo = genTestUserSig(this.userId);

3.实例化一个trtc-electron-sdk

trtcCloud = new TRTCCloud();

4.配置两个监听事件,进房和退房事件,这两个事件必须成对出现,并且在退房exitRoom时使用进房操作会引起不可预计的问题

trtcCloud.on('onEnterRoom', this.onEnterRoom.bind(this));

trtcCloud.on('onExitRoom', this.onExitRoom.bind(this));

5.设置视频编码和美颜以及进房参数

encParam = new TRTCVideoEncParam();

trtcCloud.setBeautyStyle(TRTCBeautyStyle.TRTCBeautyStyleNature, 5, 5, 5);

param = new TRTCParams();

6.执行进房操作

trtcCloud.enterRoom(param, TRTCAppScene.TRTCAppSceneVideoCall);

demo中还将整个trtc-electron-sdk的实例挂在到了全局的windows中

7.当检测到用户id、用户签名等必要条件时便会触发onEnterRoom事件,然后将进入房间的用户添加至承载用户容器的video-container中,下方代码已做相应的注释。这里房间号若不存在则会系统默认创建一个随机的房间号,

代码语言:javascript
复制
startCameraAndMic() {
      //这里将第一次进来的视频作为大画面视频流,相当于是主播
      //TRTCVideoStreamType三个值,0,1,2分别对应大画面小画面和辅流
      let id = `local_video-${this.roomId}-${TRTCVideoStreamType.TRTCVideoStreamTypeBig}`;
      console.log(`startCameraAndMic: ${id}`);
      //这里先判断是否有该用户进房
      let view = document.getElementById(id);
      console.log(view,'line in 417')
      // if (!view) {
        view = document.createElement('div');
        view.id = id;
        view.className = 'local-video-container';
        this.videoContainer.appendChild(view);
      // }
      trtcCloud.startLocalPreview(view);
      trtcCloud.startLocalAudio();
      trtcCloud.setLocalViewFillMode(TRTCVideoFillMode.TRTCVideoFillMode_Fill);
      trtcCloud.setLocalViewRotation(	TRTCVideoRotation.TRTCVideoRotation0 );
      trtcCloud.setLocalViewMirror = true
      // console.log(trtcCloud.setLocalViewMirror)
      //TRTCVideoFillMode_Fill: 图像铺满屏幕,超出显示视窗的视频部分将被截掉,所以画面显示可能不完整
      //TRTCVideoFillMode_Fit: 图像长边填满屏幕,短边区域会被填充黑色,但画面的内容肯定是完整的。
    },

本地视频展示还能设置以下几点:

setRemoteViewRotation,显示视频的旋转方向,支持0、90、180和270度旋转;

setNetworkQosParam,设置网络流控相关。有preference和controlMode两种方式,前者用于弱网下是“保清晰”还是“保流畅”的判断,而后者则用于设置流 控模式,一般走默认的云端控制即可。

setLocalViewMirror,设置显示本地是否显示镜像,默认选择false。但是这个初始时设置好像有点问题。

8.检测远端用户

远端用户id设置形式

id = `${uid}-${this.roomId}-${TRTCVideoStreamType.TRTCVideoStreamTypeSub}`;

创建远端用户承载的view组件并添加到video-container容器中

代码语言:javascript
复制
startCameraAndMic() {
      //这里将第一次进来的视频作为大画面视频流,相当于是主播
      //TRTCVideoStreamType三个值,0,1,2分别对应大画面小画面和辅流
      let id = `local_video-${this.roomId}-${TRTCVideoStreamType.TRTCVideoStreamTypeBig}`;
      console.log(`startCameraAndMic: ${id}`);
      //这里先判断是否有该用户进房
      let view = document.getElementById(id);
      console.log(view,'line in 417')
      // if (!view) {
        view = document.createElement('div');
        view.id = id;
        view.className = 'local-video-container';
        this.videoContainer.appendChild(view);
      // }
      trtcCloud.startLocalPreview(view);
      trtcCloud.startLocalAudio();
      trtcCloud.setLocalViewFillMode(TRTCVideoFillMode.TRTCVideoFillMode_Fill);
      trtcCloud.setLocalViewRotation(	TRTCVideoRotation.TRTCVideoRotation0 );
      trtcCloud.setLocalViewMirror = true
      // console.log(trtcCloud.setLocalViewMirror)
      //TRTCVideoFillMode_Fill: 图像铺满屏幕,超出显示视窗的视频部分将被截掉,所以画面显示可能不完整
      //TRTCVideoFillMode_Fit: 图像长边填满屏幕,短边区域会被填充黑色,但画面的内容肯定是完整的。
    },

将远端用户承载画面使用removeVideos对象进行保存,然后开始渲染远端用户视频并设置视频的渲染模式为fill还是fit

最后是设置远端用户加载的布局样式,其实这个可以通过CSS做

代码语言:javascript
复制
 videoTypeSetting() {
      let marginTop =  80 ;
      let margin = 5;
      let H = this.subStreamHeight;
      let m = 0;
      let topIndex = 0;
      let remoteVideos = this.remoteVideos;
      let typeClassName = '';
      let top = 0;
      let i = 0;
      for (let id in remoteVideos) {
        topIndex = Math.floor( i / 2 );
        typeClassName = i % 2 ===0 ? 'right' : 'left';
        top = (topIndex * H + (topIndex+1) * margin )+ marginTop;
        remoteVideos[id].className = `user-video-container ${typeClassName}`;
        remoteVideos[id].style.top = `${top}px`;
        logger.log(`videoTypeSetting: i:${i}, ti: ${topIndex}, top ${top}, H: ${H}, m: ${m}, id:${id},` );
        console.log(`videoTypeSetting: i:${i}, ti: ${topIndex}, top ${top}, H: ${H}, m: ${m}, id:${id},` );
        i++;
      }
    },

这里主要是将远端用户呈现的方式为左右依次呈现,同时这里也有一个问题,当用户过多时会造成布局混乱。

至此便完成了trtc-electron的音视频通话。

理解分享代码块

1.获取屏幕窗口属性,getScreenCaptureSources,设置当前电脑已经打开可以分享窗口的缩略大小,返回一个TRTCScreenCaptureSourceInfo属性

代码语言:javascript
复制
getScreensList() {
      // 获取窗口快照,这是资源消耗很高的函数,做个防抖,防频繁点击。
      clearTimeout(this.getScreensTaskID);
      let my = this;
      this.getScreensTaskID = setTimeout(()=>{
        console.log('getScreensList');
        my.screensList = trtcCloud.getScreenCaptureSources(200, 160, 10, 10);
        console.log(my.screensList)
        my.screensListVisiable = true;
      }, 200);
    },

2.如果至此不做任何处理,分享是electron返回的是一个白屏界面,我们需要将返回的TRTCScreenCaptureSourceInfo

中的第一帧图片画在对应的位置

代码语言:javascript
复制
for (let i = 0; i < list.length; i++) {
                srcInfos = list[i];
                console.log(srcInfos,'line in 67')
                //获取缩略图内容
                if (srcInfos.thumbBGRA.length===0) continue;
                elId = `screen_${srcInfos.sourceId}`;
                cnvs = document.getElementById(elId);
                cnvs.width = srcInfos.thumbBGRA.width;
                cnvs.height = srcInfos.thumbBGRA.height;
                imgData =  new ImageData(new Uint8ClampedArray(srcInfos.thumbBGRA.buffer), srcInfos.thumbBGRA.width,  srcInfos.thumbBGRA.height );
                cnvs.getContext("2d").putImageData(imgData, 0, 0);
            }

3.触发点击操作,这里需要注意的一个点是,demo是将父组件的一个方法直接传递给子组件,子组件通过this.XXXd的方式直接使用

代码语言:javascript
复制
chooseWindowCapture(event) {
      let source = {
        sourceId: event.currentTarget.dataset.id,
        sourceName: event.currentTarget.dataset.name,
        type: parseInt(event.currentTarget.dataset.type),
      };
      console.log('chooseWindowCapture', source);
      this.startScreenShare(source);
      this.screensListVisiable = false;
      this.isScreenSharing = true;
    },

然后选择需要渲染的目标selectScreenCaptureTarget并开始渲染startScreenCapture

代码语言:javascript
复制
startScreenShare(source) {
      let rect = new Rect();
      rect.top = 0;
      rect.left = 0;
      rect.width = 0;
      rect.height = 0;
      trtcCloud.selectScreenCaptureTarget(source.type, source.sourceId, source.sourceName, rect, true, false);
      trtcCloud.startScreenCapture()
    },

至于停止分享就是一句话

代码语言:javascript
复制
trtcCloud.stopScreenCapture();

4.通过监听事件onUserSubStreamAvailable我们可以将远端流的分享画面展现到我们的布局当中,该方法会传递两个参数uid和available,前者为用户id后者是否开启辅路画面

代码语言:javascript
复制
 showRemoteScreenSharing(uid) {
      let id = `${uid}-${this.roomId}-${TRTCVideoStreamType.TRTCVideoStreamTypeSub}`;
      logger.log(`showRemoteScreenSharing:  uid: ${id}`);
      console.log(`showRemoteScreenSharing:  uid: ${id}`);
      let W = this.subStreamWidth;
      let H = this.subStreamHeight;
      let view = document.getElementById(id);
      if (!view) {
        view = document.createElement('div');
        view.id = id;
        view.style.width = `${W}px`;
        view.style.height = `${H}px`;
        this.videoContainer.appendChild(view);
      }
      this.remoteVideos[id] = view;
      trtcCloud.startRemoteSubStreamView(uid, view);
      trtcCloud.setRemoteSubStreamViewFillMode(uid, TRTCVideoFillMode.TRTCVideoFillMode_Fill);
      // this.videoTypeSetting()
      //trtcCloud.setRemoteSubStreamViewRotation() 设置旋转方向
      //const opt = new TRTCVideoEncParam()
      //opt.videoResolution = TRTCVideoResolution.TRTCVideoResolution_640_360
      //opt.resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape
      //opt.videoFps = 15
      //opt.videoBitrate = 600
      //opt.minVideoBitrate = 360
      //设置辅流输出参数
      //trtcCloud.setSubStreamEncoderParam(opt)
    },

整块代码完成三步,首先创建一个DOM节点,然后开始渲染画面,最后设置渲染画面的方式为fill还是fit。

5.取消屏幕分享

代码语言:javascript
复制
 closeRemoteScreenSharing (uid) {
      let id = `${uid}-${this.roomId}-${TRTCVideoStreamType.TRTCVideoStreamTypeSub}`;
      let view = document.getElementById(id);
      if (view) {
        this.videoContainer.removeChild(view);
      }
      delete this.remoteVideos[id];
    }

注:本文代码全部来自于腾讯云TRTCSimpleDemo,如果需要可以下载对比观看。更多SDK详情请参考官网https://trtc-1252463788.file.myqcloud.com/electron_sdk/docs/TRTCCloud.html#setSubStreamEncoderParam

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 适用场景
  • 原理解析
  • 使用流程
    • 集成使用
      • vue项目开发
      相关产品与服务
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档