連麥接入
簡要說明
- 在使用直播JS-SDK後,如果需要接入像POYLV直播觀看頁的連麥服務,可在直播JS-SDK中開啟連麥功能,即可快速實現Web端接入Polyv多人視訊通話和音訊通話,在無延遲以及常規直播下通用
- 如果已經使用polyv連麥sdk:https://player.polyv.net/resp/rtc-sdk/latest/polyv-rtc.min.js的使用者也可參考當前文件,更新到當前用法使用,使用上與連麥sdk基本一致,可快速替換
使用前準備
- 確認已經開通連麥功能
- 瀏覽器需為Chrome 58及以上或Firefox、Safari等主流瀏覽器
- 頁面必須在HTTPS協議或者localhost中訪問
連麥流程簡介
- 講師在客戶端點擊開啟學員視訊連線/開啟學員語音連線
OPEN_MICROPHONE事件被觸發- 學員可以透過SDK實例的
joinChannel方法向講師發出連麥請求 - 講師看到申請點擊允許連麥,這時候頁面SDK監聽的
ALLOW_MICROPHONE事件被觸發 - 學員自動加入連麥,開始發起推流,事件
INIT_LOCAL_STREAM_READY被觸發,設定相應參數,進行推流 - 推流成功後如果收到講師掛斷或者學員主動點擊掛斷則退出連麥
參考程式碼
訂閱頻道中其他流簡介
- 學員成功加入連麥後會透過
USER_STREAM_ADDED事件接收到頻道中已存在的使用者(包括講師)、在該學員後加入學員的流 USER_STREAM_ADDED事件觸發呼叫回呼中的evt.subscribe方法對流進行訂閱- 若有使用者期間退出頻道則
USER_PEER_LEAVE事件被觸發
快速開始
// 初始化SDK
var liveSdk = new PolyvLiveSdk({
channelId: channelId,
sign: sign, // 频道验证签名
timestamp: timestamp, // 毫秒级时间戳
appId: appId, // polyv 后台的appId
user: {
userId: userId,
userName: 'polyv-test',
pic: 'https://livestatic.videocc.net/assets/wimages/missing_face.png'
}
});
// 监听频道信息并初始化播放器,并加入rtc参数开启连麦,如果开启了无延迟播放则默认开启连麦
liveSdk.on(PolyvLiveSdk.EVENTS.CHANNEL_DATA_INIT, (event, data) => {
liveSdk.setupPlayer({
pptEl: '#ppt',
el: '#player',
type: 'live',
rtc: true
});
});
// 连麦实例初始化完成,可以进行连麦相关代码调用,无延迟,普通直播并支持连麦的情况下会回调
liveSdk.player.on('rtcInitialized', function(rtc){
// 也可以这样获取实例 liveSdk.player.rtcInstance
console.log('连麦sdk实例', rtc);
// 连麦sdk加载后调用相关代码
initRTC(rtc);
});
// 监听相关事件,进行申请连麦、推流、订阅频道其他用户等操作
function initRTC() {
rtc.on('OPEN_MICROPHONE', (evt) => {
console.log('讲师开启连麦, 可发起申请加入连麦');
});
rtc.on('CLOSE_MICROPHONE', (evt) => {
console.log('讲师关闭连麦,可禁止发起连麦申请');
});
rtc.on('ALLOW_MICROPHONE', (evt) => {
console.log('连麦申请通过, 开始连麦');
});
rtc.on('INIT_LOCAL_STREAM_READY', (evt) => {
console.log('准备开始推流,设置推流参数');
evt.init({
element: document.getElementById('local') // 选择需要显示本地流的节点
});
});
}
連麥實例
實例方法
rtc.on(event: string, eventHandler: Function): void
用於監聽開啟關閉連麥、訂閱、推流狀態等事件
joinChannel(callback?: Function): void
客戶端開啟連麥後可呼叫該方法申請加入 範例程式碼
rtc.on('OPEN_MICROPHONE', (evt) => {
// 也可以通过页面点击申请
rtc.joinChannel(() => {
console.log('申请成功');
});
});
參數
callback?: Function申請失敗的回呼函式
cancelJoinChannel(callback?: Function): void
申請加入連麥後,在還沒有收到允許連麥訊息時可呼叫,用於取消申請
參數
callback?: Function取消申請失敗的回呼函式
disableVideo(): void
推流後用於禁用本地視訊軌道
enableVideo(): void
禁用本地視訊軌道後用於恢復視訊軌道
disableAudio(): void
推流後用於禁用本地音訊軌道
enableAudio(): void
禁用本地視訊軌道後用於恢復音訊軌道
leaveChannel(): void
用於掛斷連麥,退出連麥頻道,停止推流
openDeviceSetting(): void
開啟裝置設定面板,可用於裝置除錯以及更換裝置
closeDeviceSetting(): void
關閉裝置設定面板
openInviting(): void
開啟邀請上麥面板
closeInviting(): void
關閉邀請上麥面板
destroy(): void
銷毀實例,如果正在連麥會退出連麥
事件
rtc.on('OPEN_MICROPHONE', callback: Function): void
客戶端開啟連麥,此時可以申請加入連麥 範例程式碼:
rtc.on('OPEN_MICROPHONE', (evt) => {
console.log(evt.type); // video/audio (视频/音频通话)
});
rtc.on('CLOSE_MICROPHONE', callback: Function): void
客戶端關閉連麥,此時不可以申請加入連麥 範例程式碼:
rtc.on('CLOSE_MICROPHONE', (evt) => {
// 若页面有申请连麦的按钮可以 disable
});
rtc.on('JOIN_CHANNEL_TIMEOUT', callback: Function): void
申請連麥逾時 範例程式碼:
rtc.on('JOIN_CHANNEL_TIMEOUT', (evt) => {
alert('申请连麦超时,请重新申请');
});
rtc.on('ALLOW_MICROPHONE', callback: Function): void
客戶端通過連麥申請,這時會自動初始化本地流並加入連麥頻道 範例程式碼:
rtc.on('ALLOW_MICROPHONE', (evt) => {
console.log(`开始加入连麦,频道为 ${evt.roomId}`);
});
rtc.on('INIT_LOCAL_STREAM_READY', callback: Function): void
已經加入RTC頻道,準備初始化本地流,此時可對本地流進行部分設定 範例程式碼:
rtc.on('INIT_LOCAL_STREAM_READY', (evt) => {
console.log(`准备推流,通话类型为${evt.type}`);
evt.init({
element: document.getElementById('local'),
control: true,
profile: '480p'
});
});
evt.init(config: Object)
開始初始化本地流並推流,必須呼叫此方法,否則無法加入連麥
參數說明element: HTMLElement:Node節點,用於顯示本地流control?: boolean:是否顯示控制欄,預設值為trueprofile?: string:設定視訊屬性,預設值為'240P'
profile 設定
| 視訊屬性 | 解析度 | 碼率(Kbps) |
|---|---|---|
| 240p | 320 × 240 | 200 |
| 240p_1 | 320 × 240 | 200 |
| 240p_4 | 424 × 240 | 220 |
| 480p | 640 × 480 | 500 |
| 480p_1 | 640 × 480 | 500 |
| 480p_8 | 848 × 480 | 610 |
| 720p | 1280 × 720 | 1130 |
| 720p_1 | 1280 × 720 | 1130 |
| 720p_2 | 1280 × 720 | 2080 |
| 720p_5 | 960 × 720 | 910 |
rtc.on('INIT_LOCALSTREAM_SUCCESS', callback: Function): void
初始化本地流成功
範例程式碼:
rtc.on('INIT_LOCALSTREAM_SUCCESS', (evt) => {
console.log('初始化本地流成功');
});
rtc.on('INIT_LOCALSTREAM_ERROR', callback: Function): void
初始化本地流失敗
範例程式碼:
rtc.on('INIT_LOCALSTREAM_ERROR', (evt, error) => {
console.log(evt.message);
console.log(error);
});
rtc.on('PUBLIC_STREAM_SUCCESS', callback: Function): void
推流成功
範例程式碼:
rtc.on('PUBLIC_STREAM_SUCCESS', (evt) => {
console.log('推流成功');
});
rtc.on('PUBLIC_STREAM_ERROR', callback: Function): void
推流失敗
範例程式碼:
rtc.on('PUBLIC_STREAM_ERROR', (evt, error) => {
console.log(error);
});
rtc.on('CLIENT_BANNED', callback: Function): void
被講師掛斷連麥,連麥會退出,無需做其他操作
範例程式碼:
rtc.on('CLIENT_BANNED', (evt) => {
console.log('被讲师挂断连麦');
});
rtc.on('USER_STREAM_ADDED', callback: Function): void
加入連麥頻道後收到老師以及其他連麥者的流,此時需要進行訂閱
無延遲模式下不廣播
範例程式碼:
rtc.on('USER_STREAM_ADDED', (evt) => {
console.log(`是否为讲师:${evt.teacher}`);
console.log(`流Id:${evt.streamId}`);
console.log(`用户昵称:${evt.nick}`);
console.log(`用户头像:${evt.pic}`);
if (evt.teacher) {
evt.subscribe({
element: document.getElementById('teacher')
}, (err) => {
console.log('订阅失败');
});
} else {
evt.subscribe({
element: document.getElementById('student'),
control: true
});
}
});
evt.subscribe(config: Object, failCallback: Function)
subscribe 方法若不呼叫則不會顯示頻道內其他連麥者
參數說明element: HTMLElement: 顯示流的Node節點control?: boolean: 是否顯示控制欄,預設值為true
rtc.on('USER_STREAM_SUBSCRIBED', callback: Function): void
訂閱成功
範例程式碼:
rtc.on('USER_STREAM_SUBSCRIBED', (evt) => {
cons.log('订阅成功');
console.log(`是否为讲师:${evt.teacher}`);
console.log(`流Id:${evt.streamId}`);
console.log(`用户昵称:${evt.nick}`);
console.log(`用户头像:${evt.pic}`);
});
rtc.on('USER_MUTE_VIDEO', callback: Function): void
頻道內其他連麥者關閉視訊推流
範例程式碼:
rtc.on('USER_MUTE_VIDEO', (evt) => {
console.log(evt.streamId);
});
rtc.on('USER_UNMUTE_VIDEO', callback: Function): void
頻道內其他連麥者重新開啟視訊推流
範例程式碼:
rtc.on('USER_UNMUTE_VIDEO', (evt) => {
console.log(evt.streamId);
});
rtc.on('USER_MUTE_AUDIO', callback: Function): void
頻道內其他連麥者關閉音訊推流
範例程式碼:
rtc.on('USER_MUTE_AUDIO', (evt) => {
console.log(evt.streamId);
});
rtc.on('USER_UNMUTE_AUDIO', callback: Function): void
頻道內其他連麥者重新開啟音訊推流
範例程式碼:
rtc.on('USER_UNMUTE_AUDIO', (evt) => {
console.log(evt.streamId);
});
rtc.on('LOCAL_MUTE_VIDEO', callback: Function): void
本地視訊推流關閉,被客戶端禁止或者使用者主動關閉
範例程式碼:
rtc.on('LOCAL_MUTE_VIDEO', (evt) => {
console.log('关闭视频轨道');
});
rtc.on('LOCAL_UNMUTE_VIDEO', callback: Function): void
本地視訊推流重新開啟,被客戶端開啟或者使用者主動開啟
範例程式碼:
rtc.on('LOCAL_UNMUTE_VIDEO', (evt) => {
console.log('关闭视频轨道');
});
rtc.on('LOCAL_MUTE_AUDIO', callback: Function): void
本地音訊推流關閉,被客戶端禁止或者使用者主動關閉
範例程式碼:
rtc.on('LOCAL_MUTE_AUDIO', (evt) => {
console.log('关闭视频轨道');
});
rtc.on('LOCAL_UNMUTE_AUDIO', callback: Function): void
本地音訊推流重新開啟,被客戶端開啟或者使用者主動開啟
範例程式碼:
rtc.on('LOCAL_UNMUTE_AUDIO', (evt) => {
console.log('开启音频轨道');
});
rtc.on('USER_PEER_LEAVE', callback: Function): void
訂閱的流期間掛斷連麥退出頻道觸發
無延遲模式下不廣播
範例程式碼:
rtc.on('USER_PEER_LEAVE', (evt) => {
console.log(`${evt.streamId}退出连麦`);
});
rtc.on('LEAVE_CHANNEL_SUCCESS', callback: Function): void
離開視訊通話成功
範例程式碼:
rtc.on('LEAVE_CHANNEL_SUCCESS', (evt) => {
console.log('离开视频通话成功');
});
rtc.on('STOP', callback: Function): void
主動掛斷視訊通話(點擊預設控制欄的掛斷按鈕觸發),這時可以恢復到未申請連麥的狀態
範例程式碼:
rtc.on('STOP', (evt) => {
console.log('主动挂断通话');
});
rtc.on('SWITCH_MASTER', callback: Function): void
切換主講人事件,這時可將頁面對應連麥者更換位置,建議透過CSS切換位置
無延遲模式下不廣播
範例程式碼:
rtc.on('SWITCH_MASTER', function(evt) {
var currentUser = evt.currentUser;
var previousUser = evt.previousUser;
// 上一个主讲,只在离开的情况为空
var previousElement = previousUser.element;
// 当前需要设置的主讲
var currentElement = currentUser.element;
rtc.remove(currentUser.streamId);
// 上一个是因为离开才切换的
if (previousUser.leave) {
// 设置到主讲位置
rtc.play(currentUser.streamId, {
element: document.getElementById('playerRTC')
});
// 上一个主讲已经离开,不需要原来的位置了,删掉元素
var pn = currentElement.parentNode;
pn && pn.removeChild(currentElement);
} else {
// 设置到上一个主讲位置
rtc.remove(previousUser.streamId);
rtc.play(currentUser.streamId, {
element: previousElement
});
// 不是因为离开才切换的需要重新播放上一个主讲的流到新的位置
rtc.play(previousUser.streamId, {
element: currentElement
});
}
});
rtc.on('NETWORK_QUALITY', callback: Function): void
目前使用者的上下行網路品質,大約一到兩秒觸發一次
uplinkNetworkQuality 為上行品質,downlinkNetworkQuality為下行品質,取值0|1|2|3|4|5|6
- 0 網路品質未知
- 1 網路品質優秀
- 2 網路品質良好
- 3 網路品質一般
- 4 網路品質較差
- 5 網路品質糟糕
- 6 網路品質斷開
範例程式碼:
rtc.on('NETWORK_QUALITY', function(evt) {
console.log('上行质量为:', evt.uplinkNetworkQuality);
console.log('下行质量为:', evt.downlinkNetworkQuality);
});
rtc.on('INVITE_TO_MICROPHONE', callback: Function): void
收到連麥邀請事件,此時可顯示連麥邀請彈窗
範例程式碼:
rtc.on('INVITE_TO_MICROPHONE', function () {
rtc.openInviting();
});
注意
- 在無延遲模式下SDK會自行訂閱使用者流,所以不會廣播'USER_STREAM_ADDED', 'SWITCH_MASTER', 'USER_PEER_LEAVE'事件
- 在普通場景下連麥注意連麥成功後隱藏CDN播放器顯示RTC,離開連麥後做恢復處理
