文档地址

新手必看文档(内含api服务文档)

一、即时通信(p2p)

目前即时通信最新版本是10,v10是个大版本,下面的其他版本并不兼容,所以如果你的应用有个好几个端(PC、小程序、app等)都在使用,如果想要不同端之间的通讯,请保证大版本上保持一致。
此次由于我的其他端使用的是10以下版本的,所以我使用的是非10版本。目前官网主推v10,v9。 再低版本的文档查看需要查看以下:
在这里插入图片描述
此处可查看不同端的文档:
在这里插入图片描述

1.1 web端

1.1.1 安装sdk

在这里插入图片描述
在这里插入图片描述

通过npm安装,注意版本号选<1才是旧版本,然后import引入,注意目前sdk不支持cdn的形式引入。

import NIMSDK from 'nim-web-sdk-ng/dist/NIM_BROWSER_SDK'

1.1.2 初始化实例

import NIMSDK from 'nim-web-sdk-ng/dist/NIM_BROWSER_SDK'

const nim = NIM.getInstance(
  /**
   * param1: NIMInitializeOptions
   */
  { // 参数请阅读新手必看文档,一般需要调用后端接口查看,而不是写死前端
    appkey: 'YOUR_APPKEY',
    token: 'YOUR_TOKEN',
    account: 'YOUR_ACCOUNT'
  },
  /**
   * param2: NIMOtherOptions
   */
  {
    /**
     * 会话初始化设置
     */
    sessionConfig: {
      /**
       * 用户可以根据应用场景,设置消息是否要计入未读数。
       */
      unreadCountFilterFn: function (msg) {
        return true
      }
    },
    /**
     * 同步初始化设置
     */
    syncOptions: {
      /**
       * 是否同步置顶会话消息
       */
      stickTopSessions: true,
      /**
       * 是否同步用户信息
       */
      myInfo: false
    }
  }
)
const eventList = [
  'logined',
  'multiPortLogin',
  'kicked',
  'willReconnect',
  'disconnect',
  'msg', // 接收到消息,对端发送消息,收到会触发,可在这里将收到的消息,push到本地的消息列表
  'pushEvents', // 对端发布消息,本端订阅,收到会触发
  'updateSession', // 发出的消息,发送后会触发,可在这里将发出的消息,push到本地的消息列表
]

eventList.forEach((key: any) => {
  nim.on(key, (res) => {
    console.log(`Receive ${key} event:`, res ? JSON.parse(JSON.stringify(res)) : res);
  });
})

// then,receive event 'logined'
await nim.connect();

可详细查看相关event说明:
在这里插入图片描述

注意:如果需要多页面共用nim实例,可将实例存储在全局变量,如果实例共享,nim.on回调中涉及到的变量要注意作用域,因为当从别的页面返回nim.on的页面时,如果还复用之前的实例,那么回调中的变量都还是上个实例的,不会随着当前新实例动态响应。解决这种问题有两个方法:

  1. 将回调中的方法放在全局变量中,比如vuex等。
  2. 实例初始化和事件监听,放在单独的js文件中,页面上调用,然后,在回调方法中设置类似event bus, 回调中发送消息,在页面上订阅发送的消息,触发页面上的回调。

1.1.3 各种消息发送方式

在这里插入图片描述

1.1.4 历史记录查询方式

在这里插入图片描述

1.1.5 在线消息发布与订阅

一端发布,另一端订阅,可单独从一端向另一端发送状态消息,而不是通过消息收发的方式,在历史消息中不会查到。
在这里插入图片描述

// 发布
await nim.event.publishEvent({
  type: 1,   //传入1即可。
  value: 10001, 
  ext: 'hello world',
  vaildTime: 60,
  sync: false,
});

// 订阅
await nim.event.subscribeEvent({
  type: 1,
  accounts: ['cs3', 'cs4'],
  subscribeTime: 70,
  sync: true,
})

// 订阅端,收到发布的消息
nim.on('pushEvents', function(obj) {
  // 收到了发布的事件
})

1.2 小程序端(相关注意事项,借鉴web端)

1.2.1 安装sdk

借鉴web端,可使用npm安装,然后import引入NIM_MINIAPP_SDK.js,也可将js放入本地文件夹,不npm安装。
注意如果是小程序,sdk在子包引入的话,在mainfest的mp-weixin的配置中,添加"optimization":{“subPackages”:true},这样分包中存放的js,会被打包到分包,不占主包大小。
注意在小程序公众平台添加以下内容:
在这里插入图片描述

1.2.2 初始化实例

借鉴web端,
在这里插入图片描述

1.2.3 其他

其他步骤借鉴web端

1.3 uniapp端(相关注意事项,借鉴web端和uniapp端)

1.3.1 安装sdk

借鉴web端,可使用npm安装,然后import引入NIM_MINIAPP_SDK.js,也可将js放入本地文件夹,不npm安装。
注意如果是小程序,sdk在子包引入的话,在mainfest的mp-weixin的配置中,添加"optimization":{“subPackages”:true},这样分包中存放的js,会被打包到分包,不占主包大小。

1.3.3 其他

其他步骤借鉴web端和小程序端

二、音视频通话(p2p)

文档地址

2.1 web端

web端注意查看浏览器适配问题

2.1.1 集成

可以npm安装,也可以下载中心,下载下来import引用。
在这里插入图片描述

2.1.2 初始化实例

//创建 client 实例
rtc.client = NERTC.createClient({
  appkey: '<yourAppKey>', //您的 App Key
  debug: true, //是否开启调试日志
});

2.1.3 创建音视频房间(服务端)

创建房间api

2.1.4 创建频道并邀请他人

信令入门
信令邀请机制

let params = {
  type: 1,
  toAccid: 'OTHER_ACCOUNT_ID',
  requestId: 'xxx',
}
try {
  const data = await nim.signaling.callEx(params)
  const channelInfo = data.channelInfo
  console.warn('创建频道成功,data:', data, 'channelId 为', channelInfo.channelId, 'name 为', channelInfo.name)
} catch (error) {
  console.warn('创建频道失败,error:', error)
  if (error.code == 10405) {
    console.warn('频道已存在,请勿重复创建')
  }
}

2.1.5 获取鉴权token(服务端)

token文档

2.1.6 加入房间

//加入房间
rtc.client.join({
    channelName: '房间名称',
    uid: uid,
    token: '' //调试模式下可设置为 null。正式上线前设置为相应的 Token,具体请参考 "Token 鉴权" 章节。
}).then((obj) => {
    console.info('加入房间成功...')
    //初始化本地流,并且发布
    initLocalStream() //后面介绍说明
})
// 加入房间后初始化本地流并且发布
async function initLocalStream() {
  const cameras = await NERTC.getCameras();    //获取可用的视频输入设备
  const microphones = await NERTC.getMicrophones();     //获取可用的麦克风设备
  //创建本端 stream 实例,销毁前无需重复创建
  rtc.localStream = NERTC.createStream({
    uid: uid,                      // 本端的 uid
    audio: true,                   // 是否从麦克风采集音频
    microphoneId: microphones.microphoneId,    // 麦克风设备 deviceId,通过 getMicrophones() 获取
    video: true,                   // 是否从摄像头采集视频
    cameraId: cameras.cameraId             // 摄像头设备 deviceId,通过 getCameras() 获取
})

  //启动本地音视频流,销毁前无需重复初始化
  rtc.localStream.init().then(()=>{
    console.warn('音视频初始化完成,播放本地视频')
    //用于播放视频的 div 元素
    let div = document.getElementById('local-container')
    //开始播放本地视频流
    rtc.localStream.play(div)
    //设置播放的视频容器大小
    rtc.localStream.setLocalRenderMode({
      width: 180,
      height: 150,
      cut: true    // 是否裁剪
    })

    // 将本地音视频流发布至网易云信服务器,加入房间前不用执行此方法。
    rtc.client.publish(rtc.localStream).then(()=>{
      console.warn('本地 publish 成功, 开始发布视频流')
    })
  })
}

2.1.7 信令监听

信令错误码

const signalingEventList = [
  'signalingClose', // 收到频道关闭事件
  'signalingJoin', // 收到成员加入频道事件
  'signalingInvite', // 收到邀请事件
  'signalingCancelInvite', // 收到取消邀请事件
  'signalingReject', // 收到拒绝邀请事件--被拒绝此处需要离开音视频房间rtc.client.leave(),关闭信令nim.signaling.close(params),发送离开房间消息
  'signalingAccept', // 收到接受邀请事件
  'signalingLeave', // 收到退出频道事件
  'signalingCustomCommand', // 收到自定义控制指令事件
  'singalingSyncChannels' // 初始化时同步获取到已加入的频道列表,触发此事件
]

signalingEventList.forEach((key: any) => {
  nim.signaling.on(key, (res) => {
    console.log(`Receive ${key} event:`, res ? JSON.parse(JSON.stringify(res)) : res);
  });
})

2.1.8 音视频监听

//远端用户加入房间通知回调,建议在收到此回调后再进行设置远端视图等的操作
rtc.client.on('peer-online', evt => {
  console.log(`${evt.uid} 加入房间`)
 // 此处可以开启云录制https://doc.yunxin.163.com/nertc/server-apis/DI2OTE0ODI?platform=server
})
//远端用户退出房间通知回调
rtc.client.on('peer-leave', evt => {
  console.log(`${evt.uid} 退出房间`)
  // 对方离开,可以音视频离开房间,关闭信令,发送离开消息
})
//远端用户推流/停止推流通知回调,建议在收到此回调后再进行订阅或取消订阅音视频流的操作
rtc.client.on("stream-added", (evt)=>{
  console.log(`远端${evt.stream.getId()}发布了 ${evt.mediaType}`)
  var remoteStream = evt.stream;
  console.log('收到别人的发布消息: ', remoteStream.streamID, 'mediaType: ', evt.mediaType)
  //设置要订阅音频或者视频
  remoteStream.setSubscribeConfig({
    audio: true,//订阅麦克风音频
    audioSlave: true,//订阅音频辅流
    video: true,//订阅视频
    screenShare: true,//订阅屏幕共享
    highOrLow: NERTC.STREAM_TYPE.HIGH,//订阅大流
  })
  //发起订阅
  rtc.client.subscribe(remoteStream).then(()=>{
    console.log('发起订阅对端成功')
  })
});
rtc.client.on("stream-removed", (evt)=>{
  // 远端流停止,则关闭渲染
  evt.stream.stop(evt.mediaType);
});
// 远端订阅成功后,可进一步在 Client.on("stream-subscribed") 回调中调用 play 方法播放远端视频流。
//播放订阅的对端的音视频流
  rtc.client.on('stream-subscribed', evt => {
      console.warn('订阅别人的流成功的通知')
      var remoteStream = evt.stream;
      let div = document.getElementById('remote-container')
      //开始播放远端音视频流
      remoteStream.play(div).then(()=>{
        console.log('播放对端的流成功')
        remoteStream.setRemoteRenderMode({
          width: 180,
          height: 150,
          cut: true
        })
        // 注意浏览器自动播放受限处理https://doc.yunxin.163.com/nertc/guide/jM3NDE0NTI?platform=web
      })
    })

2.1.9 离开房间

try {
      // 使用 await 等待 leave 方法完成
      await rtc.client.leave();
      console.log('成功离开房间');
    } catch (error) {
      // 处理 leave 方法可能抛出的异常
      console.error('离开房间失败', error);
    }

2.1.10 信令接收端

需要提前初始化好即时通讯和音视频通话实例,并监听信令signalingInvite事件,在事件回调中,打开音视频页面,

点击接听按钮后:
  1. 订阅远端流
client.on('stream-added', ({uid, mediaType, isBigNumber}) => {
    //注意:如果对方开启了音频和视频,SDK 会触发 stream-added 两次,两次的 mediaType 不同分别为'audio''video',需要用户两次都调用 subscribe 方法去服务器订阅,否则服务器会不转发
    // mediaType 可以为 'audio': 音频、'video': 视频、'slaveAudio': 音频辅流、'screenShare':视频辅流,一般为屏幕共享,订阅完成后:audio 和 video 使用相同的 url,slaveAudio 和 screenShare 各自单独一个 url
    //如果对端 uid 超出了 number 精度范围,isBigNumber 值为 true,uid 为 String 类型,否则 isBigNumber 为 false,uid 为 number 类型

    console.log(`${uid} 发布了自己的 ${mediaType} 数据 `)
    client.subscribe(uid, mediaType).then(data => {
        console.log('订阅别人成功,获取到拉流地址: ', data.url)
        //业务层将拉流 url 设置到对应 live-player 组件中

        //注意: 同一个 uid,两次订阅(分别订阅 audio、video)返回的 url 是相同的的,可以重复更新相同 live-player 组件的 url,没有什么影响
        //注意: 同一个 uid,如果对方同时发布了 'audio': 音频、'video': 视频、'slaveAudio': 音频辅流、'screenShare',这 4 中类型的媒体数据,理论上需要 4 次订阅,其中订阅 audio、video 返回的 url 是相同的的,可以重复更新相同 live-player 组件的 url,使用同一个 live-player 组件,slaveAudio 需要单独一个 live-player 组件,screenShare 也需要单独一个 live-player 组件,此时有 3 个 live-player 组件去拉取对端所有类型的媒体

    }).catch(e => {
        console.log('订阅别人失败,原因: ', e)
    })
})
  1. 接受邀请并加入信令频道
let params = {
  channelId: 'YOUR_CHANNELID',
  // 邀请者的账号 ID
  fromAccid: 'THE_INVITOR',
  requestId: 'TARGET_REQURESTID'
}
try {
  let data = await nim.signaling.joinAndAccept(params)
  console.warn('接受邀请并加入成功,data', data)
} catch (error) {
  console.warn('接受邀请并加入失败,error:', error)
  switch (error.code) {
    case 10407:
      console.warn('已经在频道内')
      break
    case 10419:
      console.warn('频道人数超限')
      break
    case 10417:
      console.warn('频道成员uid冲突了')
      break
    case 10420:
      console.warn('当前账号在其他端已经登录,并且已经在频道内')
      break
    case 10404:
      console.warn('频道不存在')
      break
  }
}
  1. 获取鉴权token(服务端)
  2. 加入房间
  3. 发布本地流
let mediaType = ''//也可以设置为'audio'或者'video'。如果是空字符串'',表示同时发布 audio 音频流和 video 视频流
client.publish().then(url => {
    console.log('推流成功, 获取推流地址: ', url);
    // 设置推流player url
    //mediaType 不同分别为'audio''video',目前 SDK 的逻辑是'audio''video'使用相同的推流 url,如果开发分别使用 mediaType 为'audio'或者'video'作为参数,两次调用 publish()接口去推流,得到的 url 是相同的,因此建议用户如果加入房间后就需要同时开启音频和视频时,将 mediaType 设置为'',中途需要单独控制音频和视频的开关时,在设置 mediaType 为具体的参数
    //业务层将推流 url 设置的 live-pusher 组件中
}).catch(e => {
    console.log('推流失败,原因: ', e.message);
})
点击拒绝按钮后:

信令拒绝,并发送拒绝消息

let params = {
  channelId: 'YOUR_CHANNELID',
  fromAccid: 'THE_INVITOR',
  requestId: 'TARGET_REQURESTID',
}
try {
  await nim.signaling.reject(params)
  console.warn('拒绝邀请成功')
} catch (error) {
  console.warn('拒绝邀请失败,error:', error)
  switch (error.code) {
    case 10408:
      console.warn('邀请不存在或已过期')
      break
    case 10409:
      console.warn('邀请已经拒绝')
      break
    case 10410:
      console.warn('邀请已经接受')
      break
    case 10201:
      console.warn('对方不在线')
      break
    case 10404:
      console.warn('频道不存在')
      break
  }
}
点击挂断按钮后:
await rtc.client.leave();
let params = {
  channelId: 'YOUR_CHANNELID',
}
try {
  await nim.signaling.leave(params)
  console.warn('离开频道成功')
} catch (error) {
  console.warn('离开频道成功,error:', error)
}

2.2 小程序端

小程序sdk集成
按照文档配置微信公众平台

引入小程序sdk, 注意分包中sdk文件的打包位置配置。其他参照web端

小程序推流和拉流需要引入小程序组件live-pusher和liver-player
关于推流和拉流的player组件封装,可以交给ai

  1. 发布本地流
    加入房间后,发布本地流
let mediaType = ''//也可以设置为'audio'或者'video'。如果是空字符串'',表示同时发布 audio 音频流和 video 视频流
client.publish().then(url => {
    console.log('推流成功, 获取推流地址: ', url);
    //mediaType 不同分别为'audio''video',目前 SDK 的逻辑是'audio''video'使用相同的推流 url,如果开发分别使用 mediaType 为'audio'或者'video'作为参数,两次调用 publish()接口去推流,得到的 url 是相同的,因此建议用户如果加入房间后就需要同时开启音频和视频时,将 mediaType 设置为'',中途需要单独控制音频和视频的开关时,在设置 mediaType 为具体的参数
    //业务层将推流 url 设置的 live-pusher 组件中
}).catch(e => {
    console.log('推流失败,原因: ', e.message);
})

  1. 订阅远端流:
// 当远端流发布到房间时,会触发 stream-added 事件,您需要通过 client.on 监听该事件并在回调中订阅新加入的远端流,并且使用 live-player 组件去拉流。
client.on('stream-added', ({uid, mediaType, isBigNumber}) => {
    //注意:如果对方开启了音频和视频,SDK 会触发 stream-added 两次,两次的 mediaType 不同分别为'audio''video',需要用户两次都调用 subscribe 方法去服务器订阅,否则服务器会不转发
    // mediaType 可以为 'audio': 音频、'video': 视频、'slaveAudio': 音频辅流、'screenShare':视频辅流,一般为屏幕共享,订阅完成后:audio 和 video 使用相同的 url,slaveAudio 和 screenShare 各自单独一个 url
    //如果对端 uid 超出了 number 精度范围,isBigNumber 值为 true,uid 为 String 类型,否则 isBigNumber 为 false,uid 为 number 类型

    console.log(`${uid} 发布了自己的 ${mediaType} 数据 `)
    client.subscribe(uid, mediaType).then(data => {
        console.log('订阅别人成功,获取到拉流地址: ', data.url)
        //业务层将拉流 url 设置到对应 live-player 组件中

        //注意: 同一个 uid,两次订阅(分别订阅 audio、video)返回的 url 是相同的的,可以重复更新相同 live-player 组件的 url,没有什么影响
        //注意: 同一个 uid,如果对方同时发布了 'audio': 音频、'video': 视频、'slaveAudio': 音频辅流、'screenShare',这 4 中类型的媒体数据,理论上需要 4 次订阅,其中订阅 audio、video 返回的 url 是相同的的,可以重复更新相同 live-player 组件的 url,使用同一个 live-player 组件,slaveAudio 需要单独一个 live-player 组件,screenShare 也需要单独一个 live-player 组件,此时有 3 个 live-player 组件去拉取对端所有类型的媒体

    }).catch(e => {
        console.log('订阅别人失败,原因: ', e)
    })
})

2.3 uniapp端

uniapp sdk集成
注意如果是小程序,需要单独引入小程序sdk,,注意分包中sdk文件的打包位置配置。其他参照web端

Logo

网易智企-云信开发者社区是面向全网开发者的技术交流与服务平台,依托近 29 年 IM、音视频技术积累,提供 IM、RTC、实时对话智能体、云原生、短信等全场景开发资源。

更多推荐