webrtc实现局域网网页视频聊天

  由于项目有视频聊天的需求,在网上了解到谷歌开源的webrtc可以实现p2p的视频通信,参考了很多网上的资料,最终还是硬着头皮去webrtc官网,找到基于webrtc官网的demo,demo本身是基于本机的,源代码是模拟了两个pc来通信,要实现局域网两台设备建立webrtc连接,前提是双方拿到对方的sdp和icecandidate,彼此交换对方的这两个信息,就可以视频聊天了。webrtc使用了大量的异步函数,所以在需要获取同步等待结果返回的时候,需要在调用webrtc异步函数的时候,声明自己的方法也为异步的,使用关键字async,然后在需要等待webrtc异步函数返回的地方才能使用await.比如一下,被叫方接收到对方的sdp后,需要返回自己的sdp给对方,但是webrtc的createAnswer本身是异步的,不声明async就无法使用await来获取被叫的sdp,也就是answer,

    //接收对方视频
	pc1.addEventListener('track', gotRemoteStream);

 

//sdp信息
 sdp: 'v=0\r\n' +
      'o=- 8052014341169179559 2 IN IP4 127.0.0.1\r\n' +
      's=-\r\n' +
      't=0 0\r\n' +
      'a=group:BUNDLE 0 1\r\n' +
      'a=msid-semantic: WMS 1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5\r\n' +
      'm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 125 104\r\n' +
      'c=IN IP4 0.0.0.0\r\n' +
      'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
      'a=ice-ufrag:j8uE\r\n' +
      'a=ice-pwd:rAhd4UW0wBS+D82R2gXsBAi1\r\n' +
      'a=ice-options:trickle\r\n' +
      'a=fingerprint:sha-256 15:BC:51:0E:B8:68:D4:78:61:BB:C1:34:34:D2:83:CB:0F:C3:BF:81:DC:BE:2F:00:28:39:DA:D5:BA:65:9
1:68\r\n' +
      'a=setup:actpass\r\n' +
      'a=mid:0\r\n' +
      'a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n' +
      'a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n' +
      'a=extmap:4 urn:3gpp:video-orientation\r\n' +
      'a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
      'a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n' +
      'a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n' +
      'a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n' +
      'a=extmap:10 http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07\r\n' +
      'a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\n' +
      'a=sendrecv\r\n' +
      'a=msid:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5 72fa5dde-6030-453e-82a5-bedf547f3087\r\n' +
      'a=rtcp-mux\r\n' +
      'a=rtcp-rsize\r\n' +
      'a=rtpmap:96 H264/90000\r\n' +
      'a=rtcp-fb:96 goog-remb\r\n' +
      'a=rtcp-fb:96 transport-cc\r\n' +
      'a=rtcp-fb:96 ccm fir\r\n' +
      'a=rtcp-fb:96 nack\r\n' +
      'a=rtcp-fb:96 nack pli\r\n' +
      'a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f\r\n' +
      'a=rtpmap:97 rtx/90000\r\n' +
      'a=fmtp:97 apt=96\r\n' +
      'a=rtpmap:98 H264/90000\r\n' +
      'a=rtcp-fb:98 goog-remb\r\n' +
      'a=rtcp-fb:98 transport-cc\r\n' +
      'a=rtcp-fb:98 ccm fir\r\n' +
      'a=rtcp-fb:98 nack\r\n' +
      'a=rtcp-fb:98 nack pli\r\n' +
      'a=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\n' +
      'a=rtpmap:99 rtx/90000\r\n' +
      'a=fmtp:99 apt=98\r\n' +
      'a=rtpmap:100 VP8/90000\r\n' +
      'a=rtcp-fb:100 goog-remb\r\n' +
      'a=rtcp-fb:100 transport-cc\r\n' +
      'a=rtcp-fb:100 ccm fir\r\n' +
      'a=rtcp-fb:100 nack\r\n' +
      'a=rtcp-fb:100 nack pli\r\n' +
      'a=rtpmap:101 rtx/90000\r\n' +
      'a=fmtp:101 apt=100\r\n' +
      'a=rtpmap:127 red/90000\r\n' +
      'a=rtpmap:125 rtx/90000\r\n' +
      'a=fmtp:125 apt=127\r\n' +
      'a=rtpmap:104 ulpfec/90000\r\n' +
      'a=ssrc-group:FID 541097544 3663740680\r\n' +
      'a=ssrc:541097544 cname:bU9nHzB3c/cKfAyq\r\n' +
      'a=ssrc:541097544 msid:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5 72fa5dde-6030-453e-82a5-bedf547f3087\r\n' +
      'a=ssrc:541097544 mslabel:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5\r\n' +
      'a=ssrc:541097544 label:72fa5dde-6030-453e-82a5-bedf547f3087\r\n' +
      'a=ssrc:3663740680 cname:bU9nHzB3c/cKfAyq\r\n' +
      'a=ssrc:3663740680 msid:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5 72fa5dde-6030-453e-82a5-bedf547f3087\r\n' +
      'a=ssrc:3663740680 mslabel:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5\r\n' +
      'a=ssrc:3663740680 label:72fa5dde-6030-453e-82a5-bedf547f3087\r\n' +
      'm=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 102 0 8 105 13 110 113 126\r\n' +
      'c=IN IP4 0.0.0.0\r\n' +
      'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
      'a=ice-ufrag:j8uE\r\n' +
      'a=ice-pwd:rAhd4UW0wBS+D82R2gXsBAi1\r\n' +
      'a=ice-options:trickle\r\n' +
      'a=fingerprint:sha-256 15:BC:51:0E:B8:68:D4:78:61:BB:C1:34:34:D2:83:CB:0F:C3:BF:81:DC:BE:2F:00:28:39:DA:D5:BA:65:9
1:68\r\n' +
      'a=setup:actpass\r\n' +
      'a=mid:1\r\n' +
      'a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n' +
      'a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\n' +
      'a=sendrecv\r\n' +
      'a=msid:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5 b4dd0d48-7de1-4b61-a1f5-d3ef876b4503\r\n' +
      'a=rtcp-mux\r\n' +
      'a=rtpmap:111 opus/48000/2\r\n' +
      'a=rtcp-fb:111 transport-cc\r\n' +
      'a=fmtp:111 minptime=10;useinbandfec=1\r\n' +
      'a=rtpmap:103 ISAC/16000\r\n' +
      'a=rtpmap:9 G722/8000\r\n' +
      'a=rtpmap:102 ILBC/8000\r\n' +
      'a=rtpmap:0 PCMU/8000\r\n' +
      'a=rtpmap:8 PCMA/8000\r\n' +
      'a=rtpmap:105 CN/16000\r\n' +
      'a=rtpmap:13 CN/8000\r\n' +
      'a=rtpmap:110 telephone-event/48000\r\n' +
      'a=rtpmap:113 telephone-event/16000\r\n' +
      'a=rtpmap:126 telephone-event/8000\r\n' +
      'a=ssrc:1812555953 cname:bU9nHzB3c/cKfAyq\r\n' +
      'a=ssrc:1812555953 msid:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5 b4dd0d48-7de1-4b61-a1f5-d3ef876b4503\r\n' +
      'a=ssrc:1812555953 mslabel:1eb10fb2-e3c8-4e4e-9870-1104ec8c18c5\r\n' +
      'a=ssrc:1812555953 label:b4dd0d48-7de1-4b61-a1f5-d3ef876b4503\r\n',
    type: 'offer'
//candidate信息
candidate: 'candidate:829852397 1 udp 2113937151 192.168.1.31 56934 typ host generation 0 ufrag j8uE network-cost 99

由于webrtc需要在安全环境下访问,并且socket.io无法在https环境中启动,所以只能通过Nginx反向代理,实现https访问socket.io

 # HTTPS server
     server {

        listen 443 ssl;  # 1.1版本后这样写
        server_name www.domain.com; #填写绑定证书的域名
        ssl_certificate server.crt;  # 指定证书的位置,绝对路径
        ssl_certificate_key server.key;  # 绝对路径,同上
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
        ssl_prefer_server_ciphers on;
        location / {
            root   html; #站点目录,绝对路径
            index  index.html index.htm;
        }
		
		location /socket.io {
            proxy_pass http://192.168.1.123:3000/socket.io;      
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
        }
		
		
		location /socket.io/socket.io.js {
		    proxy_pass http://192.168.1.123:3000/socket.io/socket.io.js;      
		    proxy_http_version 1.1;
		    proxy_set_header Upgrade $http_upgrade;
		    proxy_set_header Connection "Upgrade";
		    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		    proxy_set_header X-Real-IP $remote_addr;
		    proxy_set_header Host $host;
		}
		

这里有个socket.io的知识点:

socket这样使用,socketio会自动在url中加上/socket.io   

nsps是socket.io的命名空间,类似action2的namespace,path是/socket.io,印证是刚才说的socketio会自动在url中加上/socket.io

,所以这样写,是可以正常工作的

效果图如下:

瞎倒腾了3个星期,终于倒腾出了一个最简单的可用的例子,不容易啊,技术之路,任重而道远。

发布了2 篇原创文章 · 获赞 0 · 访问量 93

猜你喜欢

转载自blog.csdn.net/robingdo/article/details/104812674