基于XMPP实现WebRTC通讯,实现一个简单的P2P视频通讯

转载:http://blog.gopersist.com/2017/02/22/xmpp-webrtc/index.html

     • WebRTC
  
     • XMPP
  
     • Openfire
  
</p>

基于上一篇安装的Openfire和XMPP的知识,实现一个简单的P2P视频通讯。

创建HTML和JS

ofwebrtc.html

        30行

<html>
<head>
    <script src='//cdn.bootcss.com/jquery/1.9.1/jquery.min.js'></script>
    <script src='//cdn.bootcss.com/strophe.js/1.2.12/strophe.min.js'></script>
    <script src='ofwebrtc.js'></script>
</head>

<body>
<p id="info"></p>
<p>----------------------------------------------------------------</p>

        17行

JID:<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">id=</span><span class="s">"input-jid"</span> <span class="na">value=</span><span class="s">"one@localhost"</span><span class="nt">&gt;</span>
<span class="nt">&lt;br&gt;</span>
密码:<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"password"</span> <span class="na">id=</span><span class="s">"input-pwd"</span> <span class="na">value=</span><span class="s">"111111"</span><span class="nt">&gt;</span>
<span class="nt">&lt;br&gt;</span>
<span class="nt">&lt;button</span> <span class="na">id=</span><span class="s">"btn-login"</span><span class="nt">&gt;</span>登录<span class="nt">&lt;/button&gt;&lt;br&gt;</span>

<span class="nt">&lt;br&gt;</span>
目标JID:
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">id=</span><span class="s">"input-contacts"</span> <span class="na">value=</span><span class="s">"two@localhost"</span><span class="nt">&gt;</span>
<span class="nt">&lt;button</span> <span class="na">id=</span><span class="s">"btn-call"</span><span class="nt">&gt;</span>Call<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;p&gt;</span>----------------------------------------------------------------<span class="nt">&lt;/p&gt;</span>

Local: <span class="nt">&lt;br&gt;</span>
<span class="nt">&lt;video</span> <span class="na">id=</span><span class="s">"localVideo"</span> <span class="na">autoplay</span><span class="nt">&gt;&lt;/video&gt;&lt;br&gt;</span>
Remote: <span class="nt">&lt;br&gt;</span>
<span class="nt">&lt;video</span> <span class="na">id=</span><span class="s">"remoteVideo"</span> <span class="na">autoplay</span><span class="nt">&gt;&lt;/video&gt;</span>

</body>
</html>

 

ofwebrtc.js

        234行

// XMPP帮助类
// boshService: XMPP服务器BOSH地址
function XMPPHelper(boshService) {
    var _this = this;

        83行

<span class="c1">// XMPP服务器BOSH地址</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">boshService</span> <span class="o">=</span> <span class="nx">boshService</span><span class="p">;</span>

<span class="c1">// XMPP连接</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">connection</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>

<span class="c1">// 当前状态是否连接</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">connected</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

<span class="c1">// 当前登录的JID</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">jid</span> <span class="o">=</span> <span class="s2">""</span><span class="p">;</span>

<span class="c1">// 收到消息后的业务回调方法</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">messageCallback</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">setMessageCallback</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messageCallback</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">messageCallback</span> <span class="o">=</span> <span class="nx">messageCallback</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// 接收到&lt;message&gt;</span>
<span class="kd">var</span> <span class="nx">onMessage</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">msg</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'--- msg ---'</span><span class="p">,</span> <span class="nx">msg</span><span class="p">);</span>

    <span class="c1">// 解析出&lt;message&gt;的from、type属性,以及body子元素</span>
    <span class="kd">var</span> <span class="nx">from</span> <span class="o">=</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">getAttribute</span><span class="p">(</span><span class="s1">'from'</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">type</span> <span class="o">=</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">getAttribute</span><span class="p">(</span><span class="s1">'type'</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">elems</span> <span class="o">=</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">'body'</span><span class="p">);</span>

    <span class="kd">var</span> <span class="nx">json</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">elems</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">innerHTML</span><span class="p">);</span>
    <span class="nx">json</span><span class="p">.</span><span class="nx">fromjid</span> <span class="o">=</span> <span class="nx">from</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">'chat'</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">messageCallback</span><span class="p">(</span><span class="nx">json</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// 连接状态改变的事件</span>
<span class="kd">var</span> <span class="nx">onConnect</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">status</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'status: '</span> <span class="o">+</span> <span class="nx">status</span><span class="p">)</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">status</span> <span class="o">==</span> <span class="nx">Strophe</span><span class="p">.</span><span class="nx">Status</span><span class="p">.</span><span class="nx">CONNFAIL</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">$</span><span class="p">(</span><span class="s1">'#info'</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="s2">"连接失败!"</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">status</span> <span class="o">==</span> <span class="nx">Strophe</span><span class="p">.</span><span class="nx">Status</span><span class="p">.</span><span class="nx">AUTHFAIL</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">$</span><span class="p">(</span><span class="s1">'#info'</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="s2">"登录失败!"</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">status</span> <span class="o">==</span> <span class="nx">Strophe</span><span class="p">.</span><span class="nx">Status</span><span class="p">.</span><span class="nx">DISCONNECTED</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">$</span><span class="p">(</span><span class="s1">'#info'</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="s2">"连接断开!"</span><span class="p">);</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">connected</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">status</span> <span class="o">==</span> <span class="nx">Strophe</span><span class="p">.</span><span class="nx">Status</span><span class="p">.</span><span class="nx">CONNECTED</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">$</span><span class="p">(</span><span class="s1">'#info'</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="s2">"连接成功!"</span><span class="p">);</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">connected</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>

        <span class="c1">// 当接收到&lt;message&gt;节,调用onMessage回调函数</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">addHandler</span><span class="p">(</span><span class="nx">onMessage</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s1">'message'</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">);</span>

        <span class="c1">// 首先要发送一个&lt;presence&gt;给服务器(initial presence)</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">$pres</span><span class="p">().</span><span class="nx">tree</span><span class="p">());</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="c1">// 登录</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">login</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">jid</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">connection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Strophe</span><span class="p">.</span><span class="nx">Connection</span><span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">boshService</span><span class="p">);</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="nx">jid</span><span class="p">,</span> <span class="nx">password</span><span class="p">,</span> <span class="nx">onConnect</span><span class="p">);</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">jid</span> <span class="o">=</span> <span class="nx">jid</span><span class="p">;</span>
<span class="p">};</span>

<span class="nx">_this</span><span class="p">.</span><span class="nx">sendMessage</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">tojid</span><span class="p">,</span> <span class="nx">type</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">connected</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">alert</span><span class="p">(</span><span class="s2">"请先登录!!!"</span><span class="p">);</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">$msg</span><span class="p">({</span>
        <span class="na">to</span><span class="p">:</span> <span class="nx">tojid</span><span class="p">,</span>
        <span class="na">from</span><span class="p">:</span> <span class="nx">_this</span><span class="p">.</span><span class="nx">jid</span><span class="p">,</span>
        <span class="na">type</span><span class="p">:</span> <span class="s1">'chat'</span>
    <span class="p">}).</span><span class="nx">c</span><span class="p">(</span><span class="s2">"body"</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
        <span class="na">type</span><span class="p">:</span> <span class="nx">type</span><span class="p">,</span>
        <span class="na">data</span><span class="p">:</span> <span class="nx">data</span>
    <span class="p">}));</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">tree</span><span class="p">());</span>
<span class="p">};</span>

}

// WebRTC帮助类
// xmppHelper:XMPP帮助实例
// localVideo:本地视频显示的DOM
// remoteVideo:远端视频显示的DOM
function WebRTCHelper(xmppHelper, localVideo, remoteVideo) {
var _this = this;

        107行

<span class="c1">// 对方用户</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>

<span class="c1">// 创建PeerConnection实例 (参数为null则没有iceserver,即使没有stunserver和turnserver,仍可在局域网下通讯)</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">webkitRTCPeerConnection</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>

<span class="nx">_this</span><span class="p">.</span><span class="nx">hasBindLocalVideo</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

<span class="c1">// 发送ICE候选到其他客户端</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">onicecandidate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'----------- tojid: '</span> <span class="o">+</span> <span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">candidate</span> <span class="o">!==</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'----------- onicecandidate ------------'</span><span class="p">);</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'candidate'</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">candidate</span><span class="p">);</span>

        <span class="nx">xmppHelper</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span><span class="p">,</span> <span class="s1">'candidate'</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">candidate</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="c1">// 如果检测到媒体流连接到本地,将其绑定到一个video标签上输出</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">onaddstream</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span>
    <span class="nx">remoteVideo</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">URL</span><span class="p">.</span><span class="nx">createObjectURL</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">stream</span><span class="p">);</span>
<span class="p">};</span>

<span class="c1">// 发送offer和answer的函数,发送本地session描述</span>
<span class="kd">var</span> <span class="nx">sendOfferFn</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">desc</span><span class="p">){</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'----------- sendOfferFn ------------'</span><span class="p">);</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'desc'</span><span class="p">,</span> <span class="nx">desc</span><span class="p">);</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">setLocalDescription</span><span class="p">(</span><span class="nx">desc</span><span class="p">);</span>
    
    <span class="nx">xmppHelper</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span><span class="p">,</span> <span class="s1">'offer'</span><span class="p">,</span> <span class="nx">desc</span><span class="p">);</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">sendAnswerFn</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">desc</span><span class="p">){</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'----------- sendAnswerFn ------------'</span><span class="p">);</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'desc'</span><span class="p">,</span> <span class="nx">desc</span><span class="p">);</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">setLocalDescription</span><span class="p">(</span><span class="nx">desc</span><span class="p">);</span>

    <span class="nx">xmppHelper</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span><span class="p">,</span> <span class="s1">'answer'</span><span class="p">,</span> <span class="nx">desc</span><span class="p">);</span>
<span class="p">};</span>

<span class="c1">// 绑定本地视频流</span>
<span class="kd">var</span> <span class="nx">bindLocalVideo</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// 获取本地音频和视频流</span>
    <span class="nx">navigator</span><span class="p">.</span><span class="nx">webkitGetUserMedia</span><span class="p">({</span>
        <span class="s2">"audio"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
        <span class="s2">"video"</span><span class="p">:</span> <span class="kc">true</span>
    <span class="p">},</span> <span class="kd">function</span><span class="p">(</span><span class="nx">stream</span><span class="p">){</span>
        <span class="c1">//绑定本地媒体流到video标签用于输出</span>
        <span class="nx">localVideo</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">URL</span><span class="p">.</span><span class="nx">createObjectURL</span><span class="p">(</span><span class="nx">stream</span><span class="p">);</span>
        <span class="c1">//向PeerConnection中加入需要发送的流</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">addStream</span><span class="p">(</span><span class="nx">stream</span><span class="p">);</span>
        <span class="nx">callback</span><span class="p">();</span>
    <span class="p">},</span> <span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">){</span>
        <span class="c1">//处理媒体流创建失败错误</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'getUserMedia error: '</span> <span class="o">+</span> <span class="nx">error</span><span class="p">);</span>
    <span class="p">});</span>
<span class="p">};</span>

<span class="c1">// 开始视频通讯</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">start</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">tojid</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span> <span class="o">=</span> <span class="nx">tojid</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">hasBindLocalVideo</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">bindLocalVideo</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
            <span class="c1">// 发送一个offer信令</span>
            <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">createOffer</span><span class="p">(</span><span class="nx">sendOfferFn</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Failure callback: '</span> <span class="o">+</span> <span class="nx">error</span><span class="p">);</span>
            <span class="p">});</span>
        <span class="p">});</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">hasBindLocalVideo</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="c1">// 发送一个offer信令</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">createOffer</span><span class="p">(</span><span class="nx">sendOfferFn</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Failure callback: '</span> <span class="o">+</span> <span class="nx">error</span><span class="p">);</span>
        <span class="p">});</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="c1">// 收到对方信息后的处理</span>
<span class="nx">_this</span><span class="p">.</span><span class="nx">onMessage</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">json</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'onMessage: '</span><span class="p">,</span> <span class="nx">json</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">tojid</span> <span class="o">=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">fromjid</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="nx">json</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">'candidate'</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">addIceCandidate</span><span class="p">(</span><span class="k">new</span> <span class="nx">RTCIceCandidate</span><span class="p">(</span><span class="nx">json</span><span class="p">.</span><span class="nx">data</span><span class="p">));</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">setRemoteDescription</span><span class="p">(</span><span class="k">new</span> <span class="nx">RTCSessionDescription</span><span class="p">(</span><span class="nx">json</span><span class="p">.</span><span class="nx">data</span><span class="p">));</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">json</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">'offer'</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">_this</span><span class="p">.</span><span class="nx">hasBindLocalVideo</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">bindLocalVideo</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
                    <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">createAnswer</span><span class="p">(</span><span class="nx">sendAnswerFn</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
                        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Failure callback: '</span> <span class="o">+</span> <span class="nx">error</span><span class="p">);</span>
                    <span class="p">});</span>
                <span class="p">});</span>
                <span class="nx">_this</span><span class="p">.</span><span class="nx">hasBindLocalVideo</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="nx">_this</span><span class="p">.</span><span class="nx">pc</span><span class="p">.</span><span class="nx">createAnswer</span><span class="p">(</span><span class="nx">sendAnswerFn</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Failure callback: '</span> <span class="o">+</span> <span class="nx">error</span><span class="p">);</span>
                <span class="p">});</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

}

$(document).ready(function() {
// 实例化XMPP和WebRTC帮助类
var xmppHelper = new XMPPHelper('/http-bind/');
var webRTCHelper = new WebRTCHelper(xmppHelper, document.getElementById('localVideo'), document.getElementById('remoteVideo'));

        19行

<span class="c1">// XMPP收到消息后转给WebRTC</span>
<span class="nx">xmppHelper</span><span class="p">.</span><span class="nx">setMessageCallback</span><span class="p">(</span><span class="nx">webRTCHelper</span><span class="p">.</span><span class="nx">onMessage</span><span class="p">);</span>

<span class="nx">$</span><span class="p">(</span><span class="s1">'#btn-login'</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'jid: '</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#input-jid"</span><span class="p">).</span><span class="nx">val</span><span class="p">());</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'pwd: '</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#input-pwd"</span><span class="p">).</span><span class="nx">val</span><span class="p">());</span>
    <span class="nx">xmppHelper</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s2">"#input-jid"</span><span class="p">).</span><span class="nx">val</span><span class="p">(),</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#input-pwd"</span><span class="p">).</span><span class="nx">val</span><span class="p">());</span>
<span class="p">});</span>

<span class="nx">$</span><span class="p">(</span><span class="s1">'#btn-call'</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s2">"#input-contacts"</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="o">==</span> <span class="s1">''</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">alert</span><span class="p">(</span><span class="s2">"请输入目标用户!"</span><span class="p">);</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="nx">tojid</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#input-contacts"</span><span class="p">).</span><span class="nx">val</span><span class="p">();</span>

    <span class="nx">webRTCHelper</span><span class="p">.</span><span class="nx">start</span><span class="p">(</span><span class="nx">tojid</span><span class="p">);</span>
<span class="p">});</span>

});

 

测试

打开Chrome,访问ofwebrtc.html页面,如:http://172.16.218.131/ofwebrtc.html。

将JID修改为two@localhost,点击登录。

再打开一个Chrome访问ofwebrtc.html页面,点击登录,然后点击Call呼叫two@localhost。在下面的Local和Remote会出来两个画面。

微信订阅号:

        11行

<script type="text/javascript">
var duoshuoQuery = {short_name:"gopersist"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		 || document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
</script>

        1行

  </div>
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebRTC 简介 WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音通话或视频聊天的技术,是谷歌2010年以6820万美元收购Global IP Solutions公司而获得的一项技术。 WebRTC提供了实时音视频的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:windows,linux,mac,android。 虽然WebRTC的目标是实现跨平台的Web端实时音视频通讯,但因为核心层代码的Native、高品质和内聚性,开发者很容易进行除Web平台外的移殖和应用。很长一段时间内WebRTC是业界能免费得到的唯一高品质实时音视频通讯技术。 为什么需要 WebRTC 开发者教程? 虽然WebRTC技术已经较为成熟,其集成了最佳的音/视频引擎,十分先进的codec,且包含了使用STUN、ICE、TURN、RTP-over-TCP的关键NAT和防火墙穿透等众多门槛并不低的技术。抛开音视频技术本身的复杂性外,要想找到合适的资料、完整的代码和库、配合合适的IDE和辅助工具能正常地实现编译和安装都非常的不容易,而这还只是个开始。没有靠谱的教程,你该怎么开始?那么地坑等在那,难道你打算一个一个趟过去? 本《WebRTC 零基础开发者教程》主要讲了什么 本文中提供下载的《WebRTC 零基础开发者教程》将以一个初学者的角度,从0开始逐步引导你掌握WebRTC开发的方方面面(当然,教程中更多的是操作性的内容,具体到技术原理和实现,显然不是本教程的讨论范畴)。 《WebRTC 零基础开发者教程》目录 1 工具 1.1 depot_tools 1.1.1 目标 1.1.2 Chromium 1.1.3 使用说明在这儿 1.1.4 下载 1.1.5 使用 1.1.6 具体使用例子 1.2 Gyp工具 1.3 Python工具 1.4 本地集成开发环境(IDE ) 1.4.1 Visual studio 1.4.2 Kdevelop 1.4.3 Eclipse 2 Webrtc 2.1 下载、编译 2.1.1 Windows下 2.1.2 ubuntu下编译 2.1.3 编译Android(只能在 linux 下) 3 webrtc开发 3.1 开发P2P视频软件需要处理的问题 3.1.1 用户列的获取、交换、信令的交换 3.1.2 P2P通信 3.1.3 多媒体处理 3.2 webrtc架构 3.2.1 WebRTC架构组件介绍 3.2.2 WebRTC核心模块API介绍 3.2.3 webRTC核心API详解 4 Libjingle详细介绍 4.1 重要组件 4.1.1 信号 4.1.2 线程和消息 4.1.3 名称转换 4.1.4 SSL支持 4.1.5 连接 4.1.6 传输,通道,连接 4.1.7 候选项 4.1.8 数据包 4.2 如何工作 4.2.1 Application模块 4.2.2 XMPP Messaging Component 模块 4.2.3 Session Logic and management commponent 模块 4.2.4 Peer to peer Component 模块 4.2.5 其他 4.3 建立libjingle应用程序 5 代码分析 5.1 音频通道建立过程 5.2 音频接收播放过程 5.3 视频接收播放过程 6 协议 6.1 XMPP协议 6.1.1 原理介绍 6.1.2 XMPP 协议网络架构 6.1.3 XMPP 协议的组成 6.1.4 Xmpp介绍 6.1.5 协议内容 6.2 Stun协议 6.2.1 P2P实现的原理 6.2.2 P2P的常用实现 6.2.3 Stun URI 6.2.4 内容 6.2.5 中文内容 6.2.6 开源服务器 6.2.7 公开的免费STUN服务器 6.3 Turn协议 6.3.1 概念 6.3.2 Turn uri 6.3.3 开源服务器工程 6.3.4 开源库 6.4 交互式连接建立(Interactive Connectivity Establishment) 6.4.1 IETF规格 6.4.2 开源工程 6.5 XEP-0166 Jingle 6.5.1 绪论 6.5.2 需求 6.6 Sctp协议 6.7 Rtp协议 7 附件 7.1 Gyp工具 7.2 Google test程序 7.3 Webrtc库介绍 7.4 webrtc代码相关基础知识 7.5 STUN和TURN技术浅析 7.6 基于ICE的VoIP穿越NAT改进方案 7.7 ubuntu安装使用stuntman 7.8 一个开源的ICE库——libnice介绍 7.9 4种利用TURN穿越对称型NAT方案的设计与实现 7.10 基于ICE方式SIP信令穿透Symmetric_NAT技术研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值