Created
March 28, 2019 03:08
-
-
Save sincerefly/dd69c0c1a274a70a7f66422361bdcc1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<!-- | |
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | |
* | |
* Use of this source code is governed by a BSD-style license | |
* that can be found in the LICENSE file in the root of the source | |
* tree. | |
--> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="description" content="WebRTC code samples"> | |
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1"> | |
<meta itemprop="description" content="Client-side WebRTC code samples"> | |
<meta itemprop="image" content="images/webrtc-icon-192x192.png"> | |
<meta itemprop="name" content="WebRTC code samples"> | |
<meta name="mobile-web-app-capable" content="yes"> | |
<meta id="theme-color" name="theme-color" content="#ffffff"> | |
<base target="_blank"> | |
<title>Peer connection</title> | |
<link rel="icon" sizes="192x192" href="images/webrtc-icon-192x192.png"> | |
<!-- <link href="//fonts.loli.net/css?family=Roboto:300,400,500,700" rel="stylesheet" type="text/css"> --> | |
<link rel="stylesheet" href="css/main.css"/> | |
<link rel="stylesheet" href="css/peerconn.css"/> | |
<style> | |
body::-webkit-scrollbar { | |
display: none; | |
} | |
body { | |
/* background-color: #d8cbbb; */ | |
padding: 1px; | |
margin: 1px; | |
width: 800px; | |
height: 600px; | |
background-color: #3c4f65; | |
-webkit-app-region: drag; | |
} | |
h1 { | |
color: white; | |
/* -webkit-app-region: drag; */ | |
user-select: none; | |
} | |
p { | |
color: white; | |
user-select: none; | |
} | |
#quit { | |
position: absolute; | |
top: 25px; | |
right: 25px; | |
-webkit-app-region: no-drag; | |
} | |
button { | |
-webkit-app-region: no-drag; | |
user-select: none; | |
} | |
video { | |
width: 320px; | |
height: 240px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="container"> | |
<h1>WebRTC Peer Connection</h1> | |
<!-- <h1>点对点音视频通信</h1> --> | |
<video id="localVideo" poster="images/poster.png" playsinline autoplay muted></video> | |
<video id="remoteVideo" poster="images/poster.png" playsinline autoplay></video> | |
<img id="quit" src="images/close-circular-button.png" width="28px"/> | |
<div class="box"> | |
<button id="startButton" hidden>Start</button> | |
<button id="prepareButton" hidden>Prepare</button> | |
<button id="startButton2">Start</button> | |
<button id="callButton">Call</button> | |
<button id="hangupButton">Hang Up</button> | |
</div> | |
<p>点击Start可以开启本地摄像头并使程序处于准备状态可以接受远程的视频, 点击Call可以发起视频请求, 点击Hang Up可以停止接受远程的视频连接</p> | |
</div> | |
<script> | |
let quitButton = document.getElementById('quit'); | |
quitButton.addEventListener('click', () => { | |
window.close() | |
}) | |
</script> | |
<script src="js/adapter.js"></script> | |
<script src="js/socket.io.js"></script> | |
<script src="js/main.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | |
* | |
* Use of this source code is governed by a BSD-style license | |
* that can be found in the LICENSE file in the root of the source | |
* tree. | |
*/ | |
'use strict'; | |
var socket = io.connect('http://192.168.38.142:8181') | |
// ice_servers | |
var servers = { | |
"iceServers": [ | |
{ | |
urls: "stun:192.168.38.142:3478" | |
}, | |
// { | |
// urls: "stun:stun.l.google.com:19302" | |
// }, | |
// { | |
// urls: "turn:192.168.38.142:3478", | |
// username: "dongdong", // optional | |
// credential: "123456" // optional | |
// }, | |
] | |
} | |
const startButton = document.getElementById('startButton'); | |
const startButton2 = document.getElementById('startButton2'); | |
const prepareButton = document.getElementById('prepareButton'); | |
const callButton = document.getElementById('callButton'); | |
const hangupButton = document.getElementById('hangupButton'); | |
callButton.disabled = true; | |
hangupButton.disabled = true; | |
startButton.addEventListener('click', start); | |
prepareButton.addEventListener('click', prepare); | |
callButton.addEventListener('click', call); | |
hangupButton.addEventListener('click', hangup); | |
startButton2.addEventListener('click', async () => { | |
await start(); | |
await prepare(); | |
}) | |
let startTime; | |
const localVideo = document.getElementById('localVideo'); | |
const remoteVideo = document.getElementById('remoteVideo'); | |
localVideo.addEventListener('loadedmetadata', function() { | |
console.log(`Local video videoWidth: ${this.videoWidth}px, videoHeight: ${this.videoHeight}px`); | |
}); | |
remoteVideo.addEventListener('loadedmetadata', function() { | |
console.log(`Remote video videoWidth: ${this.videoWidth}px, videoHeight: ${this.videoHeight}px`); | |
}); | |
remoteVideo.addEventListener('resize', () => { | |
console.log(`Remote video size changed to ${remoteVideo.videoWidth}x${remoteVideo.videoHeight}`); | |
if (startTime) { | |
const elapsedTime = window.performance.now() - startTime; | |
console.log('Setup time: ' + elapsedTime.toFixed(3) + 'ms'); | |
startTime = null; | |
} | |
}); | |
let localStream; | |
let localPeerConnection; | |
const offerOptions = { | |
offerToReceiveAudio: 1, | |
offerToReceiveVideo: 1 | |
}; | |
function getName(pc) { | |
return (pc === localPeerConnection) ? 'localPeerConnection' : 'remote'; | |
} | |
// 点击开始,启用本地摄像头 | |
async function start() { | |
console.log('Requesting local stream'); | |
startButton.disabled = true; | |
try { | |
const stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); | |
console.log('Received local stream'); | |
localVideo.srcObject = stream; | |
localStream = stream; | |
callButton.disabled = false; | |
} catch (e) { | |
alert(`getUserMedia() error: ${e.name}`); | |
} | |
} | |
// 进入准备阶段,初始化将本地音视频轨道加入到RTCPeerConnection | |
// 并监听获取自己的ICE协商信息 | |
async function prepare() { | |
console.log('Prepare for peer connect'); | |
startButton.disabled = true; | |
prepareButton.disabled = true; | |
startTime = window.performance.now(); | |
const videoTracks = localStream.getVideoTracks(); | |
const audioTracks = localStream.getAudioTracks(); | |
if (videoTracks.length > 0) { | |
console.log(`Using video device: ${videoTracks[0].label}`); | |
} | |
if (audioTracks.length > 0) { | |
console.log(`Using audio device: ${audioTracks[0].label}`); | |
} | |
const configuration = servers; | |
console.log('RTCPeerConnection configuration:', configuration); | |
localPeerConnection = new RTCPeerConnection(configuration); | |
// localPeerConnection = new RTCPeerConnection(); | |
console.log('Created local peer connection object localPeerConnection'); | |
localPeerConnection.addEventListener('icecandidate', e => onIceCandidate(e)); | |
localPeerConnection.addEventListener('iceconnectionstatechange', e => onIceStateChange(localPeerConnection, e)); | |
localPeerConnection.addEventListener('track', gotRemoteStream); | |
localStream.getTracks().forEach(track => localPeerConnection.addTrack(track, localStream)); | |
console.log('Added local stream to localPeerConnection'); | |
} | |
// 发送自己的SDP信息 | |
async function call() { | |
callButton.disabled = true; | |
hangupButton.disabled = false; | |
console.log('Starting call'); | |
try { | |
console.log('localPeerConnection createOffer start'); | |
const offer = await localPeerConnection.createOffer(offerOptions); | |
console.log(offer); | |
localPeerConnection.setLocalDescription(offer) | |
socket.emit('offer', offer); | |
} catch (e) { | |
console.log(`Failed to create session description: ${e.toString()}`); | |
} | |
} | |
// 当收到SDP信息后,生成回复SDP信息 | |
socket.on('offer', (desc) => { | |
console.log("I got offer: "); | |
localPeerConnection.setRemoteDescription(desc); | |
localPeerConnection.createAnswer(function(desc) { | |
localPeerConnection.setLocalDescription(desc) | |
console.log("I will reply a answer") | |
socket.emit('answer', desc) | |
}, function(error){ | |
console.log(error) | |
}); | |
}) | |
// 当收到回复的SDP后,设置到连接中 | |
socket.on('answer', (desc) => { | |
console.log("I got answer: ", desc.sdp); | |
localPeerConnection.setRemoteDescription(desc); | |
}) | |
function gotRemoteStream(e) { | |
if (remoteVideo.srcObject !== e.streams[0]) { | |
remoteVideo.srcObject = e.streams[0]; | |
console.log('received remote stream'); | |
callButton.disabled = true; | |
hangupButton.disabled = false; | |
} | |
} | |
// 获取到其它客户端的ice信息,设置到连接中 | |
socket.on('onicecandidate', (candidate) => { | |
localPeerConnection.addIceCandidate(candidate) | |
}) | |
// 当获得到自己的公网地址后,发送给其它客户端 | |
async function onIceCandidate(event) { | |
console.log('I got my icecandidate info') | |
if (event.candidate) { | |
console.log(event.candidate.candidate) | |
} | |
socket.emit('onicecandidate', event.candidate); | |
} | |
function onIceStateChange(pc, event) { | |
if (pc) { | |
console.log(`${getName(pc)} ICE state: ${pc.iceConnectionState}`); | |
console.log('ICE state change event: ', event); | |
} | |
} | |
function hangup() { | |
console.log('Ending call'); | |
localPeerConnection.close(); | |
localPeerConnection = null; | |
hangupButton.disabled = true; | |
callButton.disabled = false; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment