Skip to content

上节我们了解了 Janus,接下来我们来看看如何将 Janus 应用到我们的实际项目中,并通过实战项目实现我们的第二种会议系统架构。

首先在项目中要使用 Janus,那必不可少的就是要引入对应的调用 API,如果大家翻过官网的话,不难发现在它的文档首页就有对应说明,直接了当地告诉大家 JavaScript API

上面截图第三行中有介绍怎么以 module 引入的,但是对于很多人来说太麻烦,接下来按照我说的步骤,我相信很容易将 Janus 引入项目并初始化看到效果。

下载官方 JS

官方 JS 地址,如果不下载,直接拷贝内容到自己创建的 JS 文件也可以,完成内容拷贝后,在这个文件最后加入一行代码,原因是 Janus 所有的操作包括初始化、销毁、加载插件等都是在官方 JS 文件中封装好的,可直接通过该变量控制,因此对外暴露后便于我们在项目中使用。

// 对外暴露全局变量
export default Janus

看上图就是我创建的 Janus API 对应的 JS 文件。

有了 Janus API 文件,接下来给项目安装以下依赖,最新版本即可。

"webrtc-adapter": "^8.2.0"
---------
npm i webrtc-adapter -S

使用 Janus API 文件并初始化

在页面上,首先引入的就是上面我们准备的两个模块。

import adapter from 'webrtc-adapter';
import Janus from "@/utils/Janus.js";

引入之后,创建初始化 Janus 的 init() 函数。

请注意下面的 Debug参数,如果开启则控制台会打印一系列 Janus 日志,如果不想看到则可以关闭。与此同时,Janus 封装了一套日志,如果我们将 Janus 放置到全局初始化后,则可以使用该套日志。在后续代码中,如果大家想要项目日志全局可控(比如一键开关等),则可使用 Janus 封装好的日志,这样只需要更改Debug参数就可以全局控制日志输出或者隐藏。

initJanus(){
  const that = this;
  Janus.init({
        debug: true,
        dependencies: Janus.useDefaultDependencies({
          adapter: adapter
        }),
        callback: ()=> {
          if(!Janus.isWebrtcSupported()) {
                Janus.log('is not Supported Webrtc!');
                return;
          }
        }
  });
  //客户端唯一标识
  let opaqueId = "videocall-"+Janus.randomString(12);
  console.log("opaqueId",opaqueId)
        // 注册:
  janus = new Janus({
                server: 'http://1.15.172.xx:18088/janus',
                apisecret:'suc119s119',
                success: function() {
                                Janus.log("初始化成功")
                },
                error: function(cause) {
                                // Error, can't go on...
                                Janus.log(cause)
                },
                destroyed: function() {
                                // I should get rid of this
                                Janus.log("destroyed")
                }
          });            
},

刷新页面查看,如果浏览器控制台打印如下内容,则表明初始化无误。

但是如果有红色提示 比如什么跨域或者是 403 等异常提示时,那就说明你的 Janus 配置和自己当前连接的参数不一致。最常见的就是如下错误,你的 Janus 服务配置密钥(我们上一节讲的重点配置 API Secret 参数)和你当前代码中配置的不一致。

Ooops: 403 Unauthorized request (wrong or missing secret/token)

初始化 Janus API 之后,我们就要开始使用它的插件了,Janus 最优也是最灵活的特性就是它的插件了。

即插即拔的插件

为什么说 Janus 的插件 “即插即拔” 呢?因此 Janus 设计的架构就是如此,用到什么则引用什么。

看上图我在官网截的一部分图,红色框框中的全部是它的插件 。

  • VideoCall 代表 P2P 语音视频呼叫插件;
  • SIP 代表 SIP 服务器插件,可以呼叫转移等等;
  • VideoRoom 代表多媒体房间插件;
  • Record&Play 代表视频录制插件。

还有其他几个我们就不细说了,在本小册中,我们的重点核心就是实现会议,会议和前面提到的多媒体房间是不是很类似?是的,因此我们在 Janus 网关应用的核心就是多媒体房间插件,同时如果涉及到房间内画面录制,那么自然少不了视频录制插件。

好了,了解了插件,接下来我们就实战使用 Janus 丰富的插件,先拿最简单的 P2P 媒体呼叫插件来举例子。

插件的初始化

在 Janus JavaScript API 中,所有的插件引入格式基本一致,都是按照插件名称来的,大家先看下面的代码,是 videoCall 插件的一些回调函数详解,在后面正式初始化的时候我会简写。

janus.attach(
    {
        plugin: "janus.plugin.videocall",
        success: function(pluginHandle) {
            //插件初始化成功后 pluginHandle 就是全局句柄,通过 pluginHandle可以操作当前
            //会话的所有功能
        },
        error: function(cause) {
            //插件初始化失败
        },
       
        onmessage: function(msg, jsep) {
            //msg 交互信息包括挂断 接听等事件监听
            // jsep  协商信令
        },
        onlocaltrack: function(track, added) {
            // 本地媒体流发布后可以监听
        },
        onremotetrack: function(track, mid, added) {
            // 远端媒体流
        },
        oncleanup: function() {
            // PeerConnection 关闭监听
            // 同时可以创建信的句柄(旧的可用)重新初始化
        },
        detached: function() {
             // PeerConnection 关闭监听
            // 同时可以创建信的句柄(旧的不可用)重新初始化
        }
    });

看完了插件的详细信息,接下来我们就要初始化了,但前提是 Janus 已经在当前客户端注册成功,然后才能加载并初始化对应的插件,初始化方法的代码回调函数我保留了两个,其余的和前面详解中的一样:

janus = new Janus({
        server: 'http://1.15.xx.xx:18088/janus',
        apisecret:'suc119119',
        success: function() {
            //Janus 这里初始化成功,然后调用初始化插件的方法
            Janus.log("初始化成功")
            //初始化插件
            that.initVideoCallPlugin()
        },
        error: function(cause) {
            // Error, can't go on...
            Janus.log(cause)
        },
        destroyed: function() {
            // I should get rid of this
            Janus.log("destroyed")
        }
});
------------------初始化插件的伪代码---------------------------------
initVideoCallPlugin(){
    const that = this
    janus.attach({
            plugin: "janus.plugin.videocall",
            success: function(pluginHandle) {
                //插件初始化成功后 pluginHandle 就是全局句柄,通过 pluginHandle可以操作当前
                //会话的所有功能
                videoCallPluginHandle = pluginHandle
                // console.log("视频呼叫插件初始化成功",videoCallPluginHandle)
            },
            error: function(cause) {
                //插件初始化失败
            },
        });
},

上面两个图,第一个就是客户端 Janus 初始化成功后并成功初始化 VideoCall 插件,第二个图为服务器上打印的日志,仔细看里面的几个类似时间戳的长数字,是不是一致?

在这里要给大家一个温馨提示,每个客户端每次初始化成功都会返回一个 sessionId ,这个 ID 和服务器是互相关联的,如果你的服务器重启 那么当前客户端的 sessionId 也就没法用了。因此这个初始化过程一定要做全局可控。

插件既然初始化了,那么怎么使用呢?关键就是我们在前面初始化代码中提到的句柄 pluginHandle,这个句柄可以操作所有的会话操作,比如呼叫、接听、挂断、媒体监控、媒体流控制等。

课后题

这节课的课后题就不扩展新的了,大家按照我说的从头下载 Janus 官方 JS,然后封装到自己的项目中,看看有没有什么问题,同时看看初始化过程中有无异常,会不会出现连接失败等现象。