乐趣区

关于前端:保姆级教程基于声网-Web-SDK实现音视频通话及屏幕共享

前言

大家好,我是 @小曾同学,小伙伴们也能够叫我小曾~

如果你想 实现一对一音视频通话和屏幕共享性能,无妨来看看这篇文章,保姆级教程,不须要从零实现,间接集成声网 SDK 即可轻松上手。

本文也分享了我在实际过程中遇到的一些问题,帮忙小伙伴们避坑。如果文章知识点有谬误的中央,还请大家斧正,让咱们一起学习,一起提高~


01 背景介绍

声网提供了各端丰盛的音视频 SDK,本文将要应用的是 Web 端 SDK。

本篇文章次要给小伙伴们分享如何应用声网 SDK 实现 Web 端音视频通话及屏幕共享性能,其中也会涵盖在实际过程中遇到的一些问题,以此记录避免小伙伴们踩坑,同时也心愿通过从 0 到 1 实战的分享,可能帮忙更多的小伙伴。

02 后期筹备

在实战之前,须要有以下筹备条件:

• Npm & Node.js
• 前端开发根底,如 html & CSS & JavaScript
• 注册声网账号,申请声网 APPID、长期 Token,详见开始应用声网平台。

如果你还没有声网账号,能够通过这里收费注册,每个账户每月都有 10000 分钟收费额度。如果是集体学习 / 调试,时长齐全够用。

我集体的开发环境,具体信息如下:

• MacBook Pro
• Visual Studio Code:v1.75.1
• Npm:v8.19.3
• Node.js:v16.19.0
• 声网 SDK:v4.2.1,sdk 的下载可查看这里。
• Google Chrome:v110.0.5481.177

03 实战环节

通过[后期筹备],咱们曾经实现了相干配置,曾经领有了 App ID、Channel、长期 Token、声网 SDK,在本次实战中,次要具体解说两个 demo,别离是音视频通话及屏幕共享连麦。

3.1 实现音视频通话

在开始实战之前,先申明下 Demo 组成架构,

创立一个文件夹名为 Agora_VideoCall,文件夹中蕴含五个文件,别离是:

• index.html:用于设计 Web 利用的用户界面
• index.css:用于设计网页款式
• basicVideoCall.js:实现音视频通话逻辑代码,次要通过 AgoraRTCClient 实现
• AgoraRTC_N-4.2.1.js:声网音视频 SDK
• assets:第三方库,次要用于设计用户界面

在 index.html 文件中导入声网 SDK,具体内容可查看具体代码,接下来次要具体解说音视频通话及屏幕共享实现逻辑。

<script src="./AgoraRTC-N-4.2.1.js"></script>

3.1.1 实现音视频通话逻辑

以下代码均在 basicVideoCall.js 文本中写入

1)首先调用 AgoraRTC.createClient 办法创立一个 client 对象,也就是创立客户端对象

var client = AgoraRTC.createClient({mode: "rtc", codec: "vp8"});

2)定义变量 App ID,Token、Channel、User ID,并应用箭头函数实现当页面被调用时用于退出音视频通话通道。

var options = {
  appid: null,
  channel: null,
  uid: null,
  token: null
};

$(() => {var urlParams = new URL(location.href).searchParams;
  options.appid = urlParams.get("appid");
  options.channel = urlParams.get("channel");
  options.token = urlParams.get("token");
  options.uid = urlParams.get("uid");
  if (options.appid && options.channel) {$("#uid").val(options.uid);
    $("#appid").val(options.appid);
    $("#token").val(options.token);
    $("#channel").val(options.channel);
    $("#join-form").submit();}
})

3)退出频道

定义 join 函数次要是将本地音视频 track 退出一个 RTC 频道,此时须要在函数中传入 App ID,Token、Channel、User ID。退出房间后,须要公布音视频 track,所以还须要创立音视频 track,并调用 publish 办法将这些本地音视频 track 对象当作参数公布到频道中。

留神留神,在创立音视频 track 时须要先调用 createMicrophoneAudioTrack:通过麦克风采集的音频创立本地音频轨道对象;再调用 createCameraVideoTrack:通过摄像头采集的视频创立本地视频轨道对象。(如果先调用 createCameraVideoTrack,那么页面中将不会显示本地视频预览画面)

创立之后即可调用 play 办法展现本地预览,并调用 publish 办法公布到 RTC 频道中。留神 play 和 publish 办法的应用没有先后顺序,谁在前在后没有什么影响。

async function join() {[ options.uid, localTracks.audioTrack, localTracks.videoTrack] = await Promise.all([
    // 退出频道
    client.join(options.appid, options.channel, options.token || null, options.uid || null),
    // 创立本地音视频 track
    //AgoraRTC.createCameraVideoTrack(),
    AgoraRTC.createMicrophoneAudioTrack(),
    AgoraRTC.createCameraVideoTrack()]);

  localTracks.videoTrack.play("local-player");
  $("#local-player-name").text(`localVideo(${options.uid})`);

  await client.publish(Object.values(localTracks));
  console.log("publish success");
}

4)在频道中增加或移除远端用户逻辑

实现将同频道的远端用户增加到本地接口,当远端用户勾销公布时,则从本地将用户移除。

function handleUserPublished(user, mediaType) {
  const id = user.uid;
  remoteUsers[id] = user;
  subscribe(user, mediaType);
}

function handleUserUnpublished(user, mediaType) {if (mediaType === 'video') {
    const id = user.uid;
    delete remoteUsers[id];
    $(`#player-wrapper-${id}`).remove();}
}

5)订阅远端音视频逻辑

当远端用户公布音视频时,本地用户须要对其订阅,从而实现音视频通话,在 subscribe 函数中须要传入两个参数,别离是同频道远端用户 user id 和远端 mediaType,并调用 play 办法,播放远端用户音视频,从而实现一对一连麦。

async function subscribe(user, mediaType) {
  const uid = user.uid;
  // 订阅远端用户
  await client.subscribe(user, mediaType);
  console.log("subscribe success");
  if (mediaType === 'video') {
    const player = $(`
      <div id="player-wrapper-${uid}">
        <p class="player-name">remoteUser(${uid})</p>
        <div id="player-${uid}" class="player"></div>
      </div>
    `);
    $("#remote-playerlist").append(player);
    user.videoTrack.play(`player-${uid}`);
  }
  if (mediaType === 'audio') {user.audioTrack.play();
  }
}

6)监听事件

当远端用户公布或者勾销公布音视频 track 时,本地还须要对其监听,在 join 函数中,监听 client.on(“user-published”, handleUserPublished) 事件和 client.on(“user-unpublished”, handleUserUnpublished) 事件,具体如下

client.on("user-published", handleUserPublished);
client.on("user-unpublished", handleUserUnpublished);

7)来到频道

当用户点击 leave 按钮时,则将 stop 本地和远端音视频 track。

async function leave() {for (trackName in localTracks) {var track = localTracks[trackName];
    if(track) {track.stop();
      track.close();
      localTracks[trackName] = undefined;
    }
  }

3.1.2 Demo 展现

接下来能够运行咱们的 Demo 啦,输出 APPID、Token、Channel、Userid,点击 join,即可看到本人本地的画面,如果想和他人连麦,能够再复制一下网址,输出雷同的 APPID、Token、Channel,即可实现连麦,赶快试试吧。

3.2 屏幕共享连麦

屏幕共享就是将本地用户的屏幕内容,以视频画面的形式分享给其余远端用户观看。其工作原理实际上是通过 createScreenVideoTrack 创立一个屏幕共享的视频轨道对象来实现。采集屏幕的过程中浏览器会询问须要共享哪些屏幕,依据终端用户的抉择去获取屏幕信息。

在上述音视频 demo 的根底上实现屏幕共享性能。

3.2.1 增加屏幕共享 UI

在 index.html 页面中增加屏幕共享(ScreenShare)button

3.2.2 屏幕共享实现逻辑

以下代码均在 basicVideoCall.js 文本中写入

1)实现 share 函数

和上述 join 函数性能相似,次要用于开启屏幕共享,应用 createScreenVideoTrack 创立屏幕共享的视频轨道对象,同时也能够对视频编码进行一些简略的配置。函数中同样也须要增加监听事件。

async function share() {client.on("user-published", handleUserPublished);
  client.on("user-unpublished", handleUserUnpublished);
  let screenTrack;

      [options.uid, localTracks.audioTrack, screenTrack] = await Promise.all([client.join(options.appid, options.channel, options.token || null, options.uid || null),
    AgoraRTC.createMicrophoneAudioTrack(),
    AgoraRTC.createScreenVideoTrack({
      encoderConfig: {
        framerate: 15,
        height: 720,
        width: 1280
      }
    }, "auto")
  ]);

2)增加屏幕共享音视频轨道,并调用 play 办法播放本地屏幕共享的视频。

if(screenTrack instanceof Array){localTracks.screenVideoTrack = screenTrack[0]
    localTracks.screenAudioTrack = screenTrack[1]
  }
  else{localTracks.screenVideoTrack = screenTrack}

  localTracks.screenVideoTrack.play("local-player");
  $("#local-player-name").text(`localVideo(${options.uid})`);

3)公布屏幕共享

公布本地音频和屏幕共享画面至 RTC 频道中。

if(localTracks.screenAudioTrack == null){await client.publish([localTracks.screenVideoTrack, localTracks.audioTrack]);
  }
  else{await client.publish([localTracks.screenVideoTrack, localTracks.audioTrack, localTracks.screenAudioTrack]);
  }

4)在 share 函数实现逻辑中须要绑定 “track-ended” 事件,当屏幕共享进行时,会有一个警报告诉最终用户。

localTracks.screenVideoTrack.on("track-ended", () => {alert(`Screen-share track ended, stop sharing screen ` + localTracks.screenVideoTrack.getTrackId());
    localTracks.screenVideoTrack && localTracks.screenVideoTrack.close();
    localTracks.screenAudioTrack && localTracks.screenAudioTrack.close();
    localTracks.audioTrack && localTracks.audioTrack.close();});

3.2.3 Demo 展现

当点击 ScreenShare 时,会提醒用户抉择哪一个 page 进行分享,同时也有一个默认音频选项,点击分享之后,即可公布屏幕共享。

04 小结

如果你想实现音视频和屏幕共享的 Web 利用,齐全能够借鉴本篇文章 + 声网 SDK,如果不是很相熟的话,能够先看声网给出的「疾速开始 – 实现音视频通话」。

在实际过程中须要留神的是:在创立音视频 track 时须要先调用 createMicrophoneAudioTrack,再调用 createCameraVideoTrack,如果先调用 createCameraVideoTrack 那么页面中将不会显示本地视频预览画面。

Generally,本篇文章给出的 demo 比较简单,如果想要增加其余的性能比方,虚构背景、AI 降噪等,能够在此基础上持续增加性能。

(注释完)

参考资料

• 注册声网账号

• 相干 SDK 下载
• 疾速开始 – 实现音视频通话

退出移动版