文档反馈
文档反馈

多人音视频通话

本章节介绍多人实时音视频通话的相关功能。多人实时音视频通话顾名思义是支持多个人同时进行实时音视频通话,可以选择纯音频模式,或音视频模式。在这里需要明确几个概念:

房间:房间就是用户进行多人实时音视频通话的地方,房间以房间名称为唯一标识,多人房间需要先创建成功后才能加入,当所有用户都离开房间后,可以复用该房间名重新创建。

互动者:互动者是指在多人通话时可以参与互动,可以发言的人,这些用户可以发送上行的音频或视频数据,也可以接收其他互动者下行的音频或视频数据。

观众:观众是指在多人通话时只可以观看的人,没有发言的权限,这些用户只可以接收互动者下行的音频或视频数据,不可以发送上行音频或视频数据。

其中互动者和观众身份可以随时切换。

多人音视频通话流程图

与点对点通话的流程不同,多人房间暂不支持呼叫、推送和挂断等服务,只提供基本的创建、加入和离开房间接口。目前邀请加入房间可以使用信令或者IM点对点自定义通知来实现。

请开发者自己做好呼叫超时处理

sequenceDiagram 发起者-> 发起者: 1. 创建房间: netcall.createChannel 发起者-> 发起者: 2. 加入房间: netcall.joinChannel 发起者-> 参与者A: 发送IM点对点自定义通知: nim.sendCustomSysMsg 发起者-> 参与者B: 发送IM点对点自定义通知: nim.sendCustomSysMsg 发起者-> 参与者C: 发送IM点对点自定义通知: nim.sendCustomSysMsg 参与者A-> 参与者A: 1. 收到IM自定义通知 参与者A-> 参与者A: 2. 加入房间: netcall.joinChannel 参与者B-> 参与者B: 1. 收到IM自定义通知 参与者B-> 参与者B: 2. 加入房间: netcall.joinChannel 参与者C-> 参与者C: 1. 收到IM自定义通知 参与者C-> 参与者C: 2. 加入房间: netcall.joinChannel

创建房间

var rtmpConf = {
  rtmpTasks: [//推流参数配置
    {
      taskId: 'xxxxxxxxx1', //推流任务ID,string格式。taskId为推流任务的唯一标识,用于过程中增删任务操作
      streamUrl: "xxxxxxxx1", //推流地址
      layoutMode: "M-0",               //连麦方式,见下面注释
      layoutPara: "{\"k1\": \"v1\"}",  //自定义布局 JSON 字符串
      record: true,                    //录制开关
      accid: 'account1'                //选填,指定大画面accid
    },
    {
      taskId: 'xxxxxxxxx2', //推流任务ID,string格式。taskId为推流任务的唯一标识,用于过程中增删任务操作
      streamUrl: "xxxxxxxx2", //推流地址
      layoutMode: "M-0",               //连麦方式,见下面注释
      layoutPara: "{\"k2\": \"v2\"}",  //自定义布局 JSON 字符串
      record: true,                    //录制开关
      accid: 'account2'                //选填,指定大画面accid
    }
    //... 可以配置多个
  ]
}

/*
  连麦方式说明:
  "M-0":底部横排浮窗
  "M-1":顶部横排浮窗
  "M-2":平铺
  "M-3":裁剪平铺
  'M-4':自定义布局
  'M-5':纯音频布局
 */

netcall.createChannel({
  channelName: 'testChannelName', //必填
  custom: '自定义数据', //可选
  webrtcEnable: true, //启动webrtc
  rtmpConf: rtmpConf //如果不需要房间推流,设置'',即可
}).then(function(obj) {
  // 预定房间成功后的上层逻辑操作
  // eg: 初始化房间UI显示
  // eg: 加入房间
})
参数名 类型 说明
channelName string 房间房号,可以任意英文字母和数组的组合
custom string 扩展字段,在通话的创建和加入之间传递自定义的额外信息

加入房间

const sessionConfig = {
  videoQuality: Netcall.CHAT_VIDEO_QUALITY_HIGH,
  videoFrameRate: Netcall.CHAT_VIDEO_FRAME_RATE_15,
  videoEncodeMode: Netcall.CHAT_VIDEO_ENCODEMODE_NORMAL,
  videoBitrate: 0,
  recordVideo: false,
  recordAudio: false,
  highAudio: false,
  bypassRtmp: false,
  rtmpUrl: '',
  rtmpRecord: false,
  splitMode: Netcall.LAYOUT_SPLITLATTICETILE
};
netcall
  .joinChannel({
    channelName: 'testChannelName', //必填
    type: Netcall.NETCALL_TYPE_VIDEO,
    role: 0,//以互动者的身份加入
    sessionConfig: sessionConfig
  })
  .then(function(obj) {
    // 加入房间成功后的上层逻辑操作
    // eg: 开启摄像头
    // eg: 开启麦克风
    // eg: 开启本地流
    // eg: 设置音量采集、播放
    // eg: 设置视频画面尺寸等等,具体请参照p2p呼叫模式
  });
参数名 类型 说明
channelName string 房间房号,可以任意英文字母和数组的组合
role number 加入房间的角色,互动者或观众。具体枚举见此
type number 房间通话类型,音频或视频通话,具体枚举见此
sessionConfig object 通话配置, 每次通话会伴随着一次通话, 可以对此次通话进行一些配置,具体属性见这里)

开启音视频连接

音视频连接(PC Agent)

graph TB A(Start) --> C[netcall.startDevice: 开启本地麦克风] C --> D[netcall.startDevice: 开启本地摄像头] D --> E[netcall.startLocalStream: 开启本地视频预览] E --> F[netcall.startRemoteStream: 开启对端视频预览] F --> G[netcall.setCaptureVolume: 设置己方音频采集音量] G --> H[netcall.setPlayVolume: 设置己方音频播放音量] H --> I[netcall.setVideoViewSize: 设置本地画面大小] I --> J[netcall.on'joinChannel': 监听对方加入通话的通知] J --> K(End)
// 缓存netcall实例
const netcall = this.netcall;
// 开启麦克风
netcall
  .startDevice({
    type: Netcall.DEVICE_TYPE_AUDIO_IN
  })
  .then(function() {
    // 通知对方自己开启了麦克风
    netcall.control({
      command: Netcall.NETCALL_CONTROL_COMMAND_NOTIFY_AUDIO_ON
    });
  })
  .catch(function(err) {
    console.log('启动麦克风失败');
    console.log(err);
  });

// 开启摄像头
netcall
  .startDevice({
    type: Netcall.DEVICE_TYPE_VIDEO,
    width: 640,
    height: 480
  })
  .then(function() {
    // 通知对方自己开启了摄像头
    netcall.control({
      command: Netcall.NETCALL_CONTROL_COMMAND_NOTIFY_VIDEO_ON
    });
  })
  .catch(function(err) {
    // 通知对方自己的摄像头不可用
    netcall.control({
      command: Netcall.NETCALL_CONTROL_COMMAND_SELF_CAMERA_INVALID
    });
    console.log('启动摄像头失败');
    console.error(err);
  });

// 开启本地视频预览
netcall.startLocalStream();

// 设置本地音量采集大小, 该API可以在通话过程中动态调用调整自己的音量采集大小
netcall.setCaptureVolume(255);

// 设置本地音量播放大小, 该API可以在通话过程中动态调用调整自己的音量播放大小(即自己听对端的音量)
netcall.setPlayVolume(255);

// 设置本地视频画面大小
netcall.setVideoViewSize({
  width: 500,
  height: 500,
  cut: true
});

// 在回调里监听对方加入通话,并显示对方的视频画面
netcall.on('joinChannel', function(obj) {
  console.log('user join', obj);
  // 播放对方声音
  netcall
    .startDevice({
      type: Netcall.DEVICE_TYPE_AUDIO_OUT_CHAT
    })
    .catch(function(err) {
      console.log('播放对方的声音失败');
      console.error(err);
    });
  // 预览对方视频画面
  netcall.startRemoteStream({
    account: obj.account,
    node: document.getElementById('remoteContainer')
  });
  // 设置对方预览画面大小
  netcall.setVideoViewRemoteSize({
    account: obj.account,
    width: 500,
    height: 500,
    cut: true
  });
});
返回类型 方法名 说明
promise netcall.startDevice 开启本地麦克风
promise netcall.startDevice 开启本地摄像头
promise netcall.startLocalStream 开启本地视频预览
promise netcall.setCaptureVolume 设置己方音频采集音量
promise netcall.setPlayVolume 设置己方音频播放音量
promise netcall.setVideoViewSize 设置本地画面大小
promise netcall.startDevice 播放对方声音
promise netcall.startRemoteStream 预览对方视频画面
promise netcall.setVideoViewRemoteSize 设置对方画面大小

音视频连接(WebRTC)

graph TB A(Start) --> C[netcall.startRtc: 连接媒体网关] C --> D[netcall.startDevice: 开启本地麦克风,将本地音频发送到对端] D --> E[netcall.startDevice: 开启本地摄像头,将本地视频发送到对端] E --> F[netcall.startLocalStream: 开启本地视频预览] F --> G[netcall.setCaptureVolume: 设置己方音频采集音量] G --> H[netcall.setPlayVolume: 设置己方音频播放音量] H --> I[netcall.setVideoViewSize: 设置本地画面大小] I --> J[netcall.on'joinChannel': 监听对方加入通话的通知] J --> K(End)
const netcall = this.netcall

netcall.startRtc().then(function() {
  // 开启麦克风
  return netcall.startDevice({
    type: Netcall.DEVICE_TYPE_AUDIO_IN
  }).catch(function(err) {
    console.log('启动麦克风失败')
    console.error(err)
  })
})
.then(function() {
  // 设置采集音量
  netcall.setCaptureVolume(255)
  // 开启摄像头
  return netcall.startDevice({
      type: Netcall.DEVICE_TYPE_VIDEO,
      width: 640,
      height: 480
    })
  .catch(function(err) {
    console.log('启动摄像头失败')
    console.error(err)
  })
})
.then(function() {
  //预览本地画面
  netcall.startLocalStream(
    document.getElementById('localContainer')
  )
  // 设置本地预览画面大小
  netcall.setVideoViewSize({
    width: 500,
    height: 500,
    cut:true
  })
})
.then(function() {
  // 设置互动者角色
  netcall.changeRoleToPlayer()
})
.catch(function(err) {
  console.log('发生错误')
  console.log(err)
  netcall.hangup()
})

// 在回调里监听对方加入通话,并显示对方的视频画面
netcall.on('remoteTrack', function(obj) {
  console.log('user join', obj)
  // 播放对方声音
  netcall.startDevice({
    type: Netcall.DEVICE_TYPE_AUDIO_OUT_CHAT
  }).catch(function(err) {
    console.log('播放对方的声音失败')
    console.error(err)
  })
  // 预览对方视频画面
  netcall.startRemoteStream({
    account: obj.account,
    node: document.getElementById('remoteContainer')
  })
  // 设置对方预览画面大小
  netcall.setVideoViewRemoteSize({
    account: obj.account,
    width: 500,
    height: 500,
    cut:true
  })
})
返回类型 方法名 说明
promise netcall.startRtc 连接媒体网关
promise netcall.startDevice 开启本地麦克风,将本地音频发送到对端
promise netcall.startDevice 开启本地摄像头,将本地视频发送到对端
promise netcall.startLocalStream 开启本地视频预览
promise netcall.setCaptureVolume 设置己方音频采集音量
promise netcall.setPlayVolume 设置己方音频播放音量
promise netcall.setVideoViewSize 设置本地画面大小
promise netcall.startDevice 播放对方声音
promise netcall.startRemoteStream 预览对方视频画面
promise netcall.setVideoViewRemoteSize 设置对方画面大小

离开房间

netcall.leaveChannel().then(function(obj) {
  // 离开房间后,开发者自己业务的扫尾工作
});

用户加入房间通知

netcall.on('joinChannel', function(obj) {
  console.log('user joinchannel', obj);
});

obj 为通知消息对象

obj 属性 类型 说明
account string 新加入同伴的 accid
channelId number 加入的房间 id

收到用户媒体流的通知

netcall.on('remoteTrack', function(obj) {
  console.log('收到远程轨道信息', obj);
  // 音频:播放对方的音频
  if (obj.track.kind === 'audio') {
    // 播放对方声音
    netcall
      .startDevice({
        type: Netcall.DEVICE_TYPE_AUDIO_OUT_CHAT
      })
      .catch(function() {
        console.log('播放对方的声音失败');
      });
  }

  // 视频:展示对方的画面
  if (obj.track.kind === 'video') {
    // 预览加入的同学的视频流
    netcall.startRemoteStream({
      account: obj.account,
      node: document.getElementById('remoteContainer')
    });

    // 设置对方预览画面大小
    netcall.setVideoViewRemoteSize({
      uid: 'testUid',
      width: 500,
      height: 500,
      cut: true
    });
  }
});

obj 为通知消息对象

obj 属性 类型 说明
uid string 新加入同伴的 uid
channelId number 加入的房间 id
返回类型 方法名 说明
promise netcall.startDevice 播放对方声音
promise netcall.startRemoteStream 预览对方视频画面
promise netcall.setVideoViewRemoteSize 设置对方画面大小

用户离开房间通知

netcall.on('leaveChannel', function(obj) {
  // sdk内部会做一系列清理工作,此外开发者需要自己做业务逻辑和UI处理
});

obj 为通知消息对象

obj 属性 类型 说明
account string 离开同伴的 accid
channelId number 离开的房间 id
返回类型 方法名 说明
promise netcall.stopRemoteStream 停止预览对方视频画面
×

反馈成功

非常感谢您的反馈,我们会继续努力做得更好。