webrtc服务器janus echotest学习

时间:2024-03-31 08:15:45

webrtc服务器janus echotest学习一

 

Echo测试演示的是发送给服务器网关的音频和视频,服务器会回传给你,效果如下图所示: 
webrtc服务器janus echotest学习

代码分析

webrtc服务器janus echotest学习

创建线程

在janus = new Janus()时,调用Janus(gatewayCallbacks)在其中有函数createSession,并且传入下面的回调函数: 
webrtc服务器janus echotest学习 
createSession创建请求,成功建立一次httpAPICall,输出Created handle: 1747107217737787

Janus.httpAPICall(server, {
    verb: 'POST',
    withCredentials: withCredentials,
    body: request,
    success: function(json) {
    Janus.debug(json);
    if(json["janus"] !== "success") {
        Janus.error("Ooops: " + json["error"].code + " " + json["error"].reason);   // FIXME
        callbacks.error(json["error"].reason);
        return;
    }
    Janus.sessions[sessionId] = that;
    eventHandler();
    callbacks.success();
},

成功回调eventHandler以及echoest的sucesss

创建插件

echoest的sucesss函数如下: 
定义了插值对象及对应的回调函数。 
janus.attach( 


this.attach = function(callbacks) { createHandle(callbacks)} 实际调用createHandle, 
并把对应的回调plugin,succecss等传入,如下图。 
webrtc服务器janus echotest学习

在函数function createHandle(callbacks) 中,定义了插件的各个函数,并且回调echotest.js中的janus.attach中的success函数,并且输出Plugin attached! (janus.plugin.echotest, id=1747107217737787),其函数的主要作用是传入对应的回调函数,并且定义一个插件及其许多许应的函数,并且与服务器进行通信

pluginHandles[handleId] = pluginHandle;
callbacks.success(pluginHandle);

echotest = pluginHandle;定义为插件,其中定义许多函数。包括:

var pluginHandle =
{
        session : that,
        plugin : plugin,
        id : handleId,
        token : handleToken,
        detached : false,
        webrtcStuff : {}
        getId : function() { return handleId; },
        getPlugin : function() { return plugin; },
        getVolume : function() { return getVolume(handleId); },
        isAudioMuted : function() { return isMuted(handleId, false); },
        muteAudio : function() { return mute(handleId, false, true); },
        unmuteAudio : function() { return mute(handleId, false, false); },
        isVideoMuted : function() { return isMuted(handleId, true); },
        muteVideo : function() { return mute(handleId, true, true); },
        unmuteVideo : function() { return mute(handleId, true, false); },
        getBitrate : function() { return getBitrate(handleId); },
        send : function(callbacks) { sendMessage(handleId, callbacks); },
        data : function(callbacks) { sendData(handleId, callbacks); },
        dtmf : function(callbacks) { sendDtmf(handleId, callbacks); },
        consentDialog : callbacks.consentDialog,
        iceState : callbacks.iceState,
        mediaState : callbacks.mediaState,
        webrtcState : callbacks.webrtcState,
        slowLink : callbacks.slowLink,
        onmessage : callbacks.onmessage,
        createOffer : function(callbacks) { prepareWebrtc(handleId, callbacks); },
        createAnswer : function(callbacks) { prepareWebrtc(handleId, callbacks); },
        handleRemoteJsep : function(callbacks) { prepareWebrtcPeer(handleId, callbacks); },
        onlocalstream : callbacks.onlocalstream,
        onremotestream : callbacks.onremotestream,
        ondata : callbacks.ondata,
        ondataopen : callbacks.ondataopen,
        oncleanup : callbacks.oncleanup,
        ondetached : callbacks.ondetached,
        hangup : function(sendRequest) { cleanupWebrtc(handleId, sendRequest === true); },
        detach : function(callbacks) { destroyHandle(handleId, callbacks); }
}

并且向服务器发起一次请求,通信服务器,如果成功时,才回调echotest.js中的janus.attach中的success函数,即

success: function(pluginHandle) {
            $('#details').remove();
            echotest = pluginHandle;
            Janus.log("Plugin attached! (" + echotest.getPlugin() + ", id=" + echotest.getId() + ")");
            // Negotiate WebRTC
            var body = { "audio": true, "video": true };
            Janus.debug("Sending message (" + JSON.stringify(body) + ")");
            echotest.send({"message": body});
            Janus.debug("Trying a createOffer too (audio/video sendrecv)");
            echotest.createOffer(
                {
                    // No media provided: by default, it's sendrecv for audio and video
                    media: { data: true },  // Let's negotiate data channels as well
                    // If you want to test simulcasting (Chrome and Firefox only), then
                    // pass a ?simulcast=true when opening this demo page: it will turn
                    // the following 'simulcast' property to pass to janus.js to true
                    simulcast: doSimulcast,
                    success: function(jsep) {
                        Janus.debug("Got SDP!");
                        Janus.debug(jsep);
                        echotest.send({"message": body, "jsep": jsep});
                    },
                    error: function(error) {
                        Janus.error("WebRTC error:", error);
                        bootbox.alert("WebRTC error... " + JSON.stringify(error));
                    }
                });
            $('#start').removeAttr('disabled').html("Stop")
                .click(function() {
                    $(this).attr('disabled', true);
                    clearInterval(bitrateTimer);
                    janus.destroy();
                });
        },

在这个函数准备向服务器发送相应的信息连接请求。

发送音视频信息

var body = { “audio”: true, “video”: true }; 
echotest.send({“message”: body}); 
echotest.send 实际调用sendMessage 
发送的请求为: 
var request = { “janus”: “message”, “body”: message, “transaction”: transaction };

Sending message to plugin (handle=3650608414117457): 
响应 
webrtc服务器janus echotest学习 
然后调用success函数

后面通过handleEvent 收到信息,调用Onmessage函数。信息如下: 
webrtc服务器janus echotest学习

echotest.createOffer函数,实际调用prepareWebrtc 
Trying a createOffer too (audio/video sendrecv 
打印上面消息,并且调用httpAPICall来进行通信

function eventHandler() 
作用是发出httpAPICall请求,然后请求成功执行handleEvent 
handleEvent 收到信息,调用Onmessage函数。 
webrtc服务器janus echotest学习

创建offer信息

调用echotest.createOffer,实际调用prepareWebrtc函数,其中getUserMedia 
获得本地流,并且调用streamsDone。代码:

navigator.mediaDevices.getUserMedia(gumConstraints)
.then(function(stream) { 
pluginHandle.consentDialog(false); 
streamsDone(handleId, jsep, media, callbacks, stream); })

其中streamsDone 函数建立RTCPeerConnection连接,并且准备本地的sdp,并且调用onlocalstream把本地流显示出来。代码如下:

根据当前条件,选择执行下面功能
config.pc = new RTCPeerConnection(pc_config, pc_constraints);
pluginHandle.onlocalstream(config.myStream);//显示本地流
createOffer(handleId, media, callbacks);//调用函数 createOffe
config.pc.setRemoteDescription//如果已经有sdp信息,远程sdp,调用此处

在函数function createOffer(handleId, media, callbacks)中:

config.pc.createOffer 调用系统的函数,并且成功的话回调。

如果成功回调callbacks.success(jsep);即调用echotest.createOffer里的时,成功回调,准备向服务器发送sdp信息: 
success当,当收到本地sdp信息时,成功回调,准备向服务器发送sdp信息: 
success: function(jsep) { 
Janus.debug(“Got SDP!”); 
Janus.debug(jsep); 
webrtc服务器janus echotest学习 
echotest.send({“message”: body, “jsep”: jsep}); 
调用sendMessage用来发送消息,如果发送成功,会收到ack包。 
webrtc服务器janus echotest学习

收到SDP信息

当服务器处理完成,主动向客户端发这送sdp信息,客户端是通过handleEvent来处理。

else if(json["janus"] === "event") {
    Janus.debug("Got a plugin event on session " + sessionId);
    var callback = pluginHandle.onmessage;
    if(callback !== null && callback !== undefined) {
        Janus.debug("Notifying application...");            
        callback(data, jsep);//实际调用echotest.js中函数onmessage
    } 

收到消息,成功回调函数onmessage。收到远程的SDP信息。 
webrtc服务器janus echotest学习 
并且调用echotest.handleRemoteJsep({jsep: jsep});即执行prepareWebrtcPeer 
prepareWebrtcPeer的作用是设置远程的sdp信息,用来建立p2p连接config.pc.setRemoteDescription。

回调streamsDone里面的以下函数来获得远程流config.pc.ontrack,这个是webrtc自已的函数,可能是回调函数,这样拿来显示远程流。 
config.pc.ontrack = function(event) { 
pluginHandle.onremotestream(config.remoteStream); 
webrtc服务器janus echotest学习

并且回调onremotestream用来显示远程流