Skip to content

Instantly share code, notes, and snippets.

@sincerefly
Created March 28, 2019 03:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sincerefly/dd69c0c1a274a70a7f66422361bdcc1f to your computer and use it in GitHub Desktop.
Save sincerefly/dd69c0c1a274a70a7f66422361bdcc1f to your computer and use it in GitHub Desktop.
<!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>
/*
* 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