zoukankan      html  css  js  c++  java
  • Android IOS WebRTC 音视频开发总结(七)-- 基于浏览器的开发

    前面写的一系列总结都是讲webrtc如何下载,编译,开发的,有些人可能有点云里雾里了,WEBRTC不是用来搞跨浏览器开发的吗,怎么我讲的这些跟浏览器扯不上任何关系,其实看看下面这个架构图,你就明白了,转载请说明出处(博客园RTC.Blacker)

    我前面讲的这些内容都封装在browser里面了,如音视频的采集,编码,传输,回声消除,丢包重传.所以如果你想将这些功能集成到你的产品里面就必须理解这些东西.

    如果你只想做基于浏览器的视频通话功能,上面这些你可以不理解,更不需要去下载编译WEBRTC代码,因为实现这些功能所需要的JS接口浏览器已经帮你实现了,你只需要简单调用即可,我们先看看实现下面这样一个功能主要涉及哪些步骤?

    1,信令交互:开始视频通话前发起端和接收端需要一些交互,如通知对方开始视频,接收视频,视频参数协商(SDP信息),NAT地址交换,这个过程我们称之为信令交互,WEBRTC没有定义标准信令格式,既可以使用SIP也可以使用XMPP,还可以使用自定义的信令格式,最简单的方式就是使用websocket或XMLHttpRequest,自定义格式完成信令交互过程.

    2,获取本地视频流:navigator.getUserMedia(constraints, successCallback, errorCallback);

    navigator.getUserMedia = navigator.getUserMedia ||
      navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
    // Callback to be called in case of success...
    function successCallback(gotStream) {
    video.src = window.URL.createObjectURL(stream);
      // Start playing video
      video.play();
    }
    
    // Callback to be called in case of failure...
    function errorCallback(error){ console.log("navigator.getUserMedia error: ", error);
    }
    
    // Constraints object for low resolution video
    var qvgaConstraints = { video: {
        mandatory: {
          maxWidth: 320,
          maxHeight: 240
    } }
    };
    
    // Constraints object for standard resolution video
    var vgaConstraints = { video: {
        mandatory: {
          maxWidth: 640,
          maxHeight: 480
    } }
    };
    
    // Constraints object for high resolution video
    var hdConstraints = { video: {
        mandatory: {
          minWidth: 1280,
          minHeight: 960
    } }
    };
    
    function getMedia(constraints){
    if (!!stream) { video.src = null; stream.stop();
    }
      navigator.getUserMedia(constraints, successCallback, errorCallback);
    }

    3,SDP协商:createOffer,createAnswer.

     1 localPeerConnection.createOffer(gotLocalDescription, onSignalingError);
     2 
     3 // Handler to be called when the 'local' SDP becomes available
     4 function gotLocalDescription(description){
     5 // Add the local description to the local PeerConnection 
      localPeerConnection.setLocalDescription(description);
      log("Offer from localPeerConnection: " + description.sdp);
    6 // ...do the same with the 'pseudoremote' PeerConnection 7 // Note: this is the part that will have to be changed if you want // the communicating peers to become remote 8 // (which calls for the setup of a proper signaling channel) remotePeerConnection.setRemoteDescription(description); 9 // Create the Answer to the received Offer based on the 'local' description 10 remotePeerConnection.createAnswer(gotRemoteDescription, onSignalingError); 11 } 12 // Handler to be called when the remote SDP becomes available 13 function gotRemoteDescription(description){ 14 // Set the remote description as the local description of the 15 // remote PeerConnection.
      remotePeerConnection.setLocalDescription(description);
    16 log("Answer from remotePeerConnection: " + description.sdp); 17 // Conversely, set the remote description as the remote description of the // local PeerConnection
      localPeerConnection.setRemoteDescription(description);
    18 }

    4,ICE协商:

     1 // Add a handler associated with ICE protocol events 
     2 localPeerConnection.onicecandidate = gotLocalIceCandidate;
     3 
     4 remotePeerConnection.onicecandidate = gotRemoteIceCandidate;
     5 
     6 // Handler to be called whenever a new local ICE candidate becomes available
     7 function gotLocalIceCandidate(event){ if (event.candidate) {
     8             // Add candidate to the remote PeerConnection
     9        remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    10           log("Local ICE candidate: 
    " + event.candidate.candidate);
    11       }
    12 }
    13 
    14 // Handler to be called whenever a new remote ICE candidate becomes available
    15 function gotRemoteIceCandidate(event){ if (event.candidate) {
    16             // Add candidate to the local PeerConnection
    17       localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    18           log("Remote ICE candidate: 
     " + event.candidate.candidate);
    19       }
    20 }

    5,使用RTCPeerConnection对象在浏览器之间交换媒体流数据.

      1 function call() {
      2   log("Starting call");
      3 
      4   // Note well: getVideoTracks() and getAudioTracks() are not currently supported in Firefox...
      5   // ...just use them with Chrome
      6   if (navigator.webkitGetUserMedia) {
      7       // Log info about video and audio device in use
      8       if (localStream.getVideoTracks().length > 0) {
      9         log('Using video device: ' + localStream.getVideoTracks()[0].label);
     10       }
     11       if (localStream.getAudioTracks().length > 0) {
     12         log('Using audio device: ' + localStream.getAudioTracks()[0].label);
     13       }
     14   }
     15   
     16   // Chrome
     17   if (navigator.webkitGetUserMedia) {
     18       RTCPeerConnection = webkitRTCPeerConnection;
     19   // Firefox
     20   }else if(navigator.mozGetUserMedia){
     21       RTCPeerConnection = mozRTCPeerConnection;
     22       RTCSessionDescription = mozRTCSessionDescription;
     23       RTCIceCandidate = mozRTCIceCandidate;
     24   }
     25   log("RTCPeerConnection object: " + RTCPeerConnection);
     26   
     27   // This is an optional configuration string, associated with NAT traversal setup
     28   var servers = null;
     29 
     30   // Create the local PeerConnection object
     31   localPeerConnection = new RTCPeerConnection(servers);
     32   log("Created local peer connection object localPeerConnection");
     33   // Add a handler associated with ICE protocol events
     34   localPeerConnection.onicecandidate = gotLocalIceCandidate;
     35 
     36   // Create the remote PeerConnection object
     37   remotePeerConnection = new RTCPeerConnection(servers);
     38   log("Created remote peer connection object remotePeerConnection");
     39   // Add a handler associated with ICE protocol events...
     40   remotePeerConnection.onicecandidate = gotRemoteIceCandidate;
     41   // ...and a second handler to be activated as soon as the remote stream becomes available 
     42   remotePeerConnection.onaddstream = gotRemoteStream;
     43 
     44   // Add the local stream (as returned by getUserMedia() to the local PeerConnection
     45   localPeerConnection.addStream(localStream);
     46   log("Added localStream to localPeerConnection");
     47   
     48   // We're all set! Create an Offer to be 'sent' to the callee as soon as the local SDP is ready
     49   localPeerConnection.createOffer(gotLocalDescription, onSignalingError);
     50 }
     51 
     52 function onSignalingError(error) {
     53     console.log('Failed to create signaling message : ' + error.name);
     54 }
     55 
     56 // Handler to be called when the 'local' SDP becomes available
     57 function gotLocalDescription(description){
     58   // Add the local description to the local PeerConnection
     59   localPeerConnection.setLocalDescription(description);
     60   log("Offer from localPeerConnection: 
    " + description.sdp);
     61   
     62   // ...do the same with the 'pseudo-remote' PeerConnection
     63   // Note well: this is the part that will have to be changed if you want the communicating peers to become
     64   // remote (which calls for the setup of a proper signaling channel)
     65   remotePeerConnection.setRemoteDescription(description);
     66   
     67   // Create the Answer to the received Offer based on the 'local' description
     68   remotePeerConnection.createAnswer(gotRemoteDescription, onSignalingError);
     69 }
     70 
     71 // Handler to be called when the 'remote' SDP becomes available
     72 function gotRemoteDescription(description){
     73   // Set the 'remote' description as the local description of the remote PeerConnection
     74   remotePeerConnection.setLocalDescription(description);
     75   log("Answer from remotePeerConnection: 
    " + description.sdp);
     76   // Conversely, set the 'remote' description as the remote description of the local PeerConnection 
     77   localPeerConnection.setRemoteDescription(description);
     78 }
     79 
     80 // Handler to be called as soon as the remote stream becomes available
     81 function gotRemoteStream(event){    
     82   // Associate the remote video element with the retrieved stream
     83   if (window.URL) {
     84       // Chrome
     85       remoteVideo.src = window.URL.createObjectURL(event.stream);
     86   } else {
     87       // Firefox
     88       remoteVideo.src = event.stream;
     89   }  
     90   log("Received remote stream");
     91 }
     92 
     93 // Handler to be called whenever a new local ICE candidate becomes available
     94 function gotLocalIceCandidate(event){
     95   if (event.candidate) {
     96     // Add candidate to the remote PeerConnection 
     97     remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
     98     log("Local ICE candidate: 
    " + event.candidate.candidate);
     99   }
    100 }
    101 
    102 // Handler to be called whenever a new 'remote' ICE candidate becomes available
    103 function gotRemoteIceCandidate(event){
    104   if (event.candidate) {
    105     // Add candidate to the local PeerConnection      
    106     localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    107     log("Remote ICE candidate: 
     " + event.candidate.candidate);
    108   }

    上面基本上就是浏览器上视频通话涉及的主要对象.

    对应到手机端就是webrtc编译成功后的appRTCDemo.apk.

  • 相关阅读:
    CF 118E Bertown roads 桥
    hdu 3917 Road constructions 最大权闭合子图
    hdu 4714 Tree2cycle 树形经典问题
    POJ 2516 Minimum Cost 最小费用流
    POJ 3921 Destroying the bus stations 沿着最短路迭代加深搜索
    POJ 3422 Kaka's Matrix Travels K取方格数
    BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增
    hdu 4010 Query on The Trees LCT
    poj 2455 Secret Milking Machine 二分+最大流 sap
    定制标记---简单标记处理器
  • 原文地址:https://www.cnblogs.com/lingyunhu/p/4004528.html
Copyright © 2011-2022 走看看