- html
<html>
<head>
<title>WebRTC capture video and audio</title>
<link rel="stylesheet" href="css/main.css"/>
<style>
.none {
-webkit-filter: none;
}
.blur {
-webkit-filter: blur(3px);
}
.grayscale {
-webkit-filter: grayscale(1);
}
.invert {
-webkit-filter: invert(1);
}
.sepia {
-webkit-filter: sepia(1);
}
</style>
</head>
<body>
<section>
<div>
<label>audio Source:</label>
<select id="audioSource"></select>
</div>
<div>
<label>audio Output:</label>
<select id="audioOutput"></select>
</div>
<div>
<label>video Source:</label>
<select id="videoSource"></select>
</div>
<div>
<label>Connect Server:</label>
<button id="connect">Connect</button>
<label>Room Name: </label>
<input type="text" id="room" value="aaa"></input>
</div>
<div>
<button id="leave" disabled>Leave</button>
</div>
</section>
<section>
<div>
<label>Filter:</label>
<select id="filter">
<option value="none">None</option>
<option value="blur">blur</option>
<option value="grayscale">Grayscale</option>
<option value="invert">Invert</option>
<option value="sepia">sepia</option>
</select>
</div>
<!--<audio autoplay controls id='audioplayer'></audio>-->
<table>
<tr>
<td><video autoplay playsinline id="player"></video></td>
<td><video playsinline id="recplayer"></video></td>
<td><div id='constraints' class='output'></div></td>
</tr>
<tr>
<td><button id="record">Start Record</button></td>
<td><button id="recplay" disabled>Play</button></td>
<td><button id="download" disabled>Download</button></td>
</tr>
</table>
</section>
<section>
<div>
<button id="snapshot">Take snapshot</button>
</div>
<div>
<canvas id="picture"></canvas>
</div>
</section>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="./js/client.js"></script>
</body>
</html>
客户端js
'use strict'
//devices
var audioSource = document.querySelector('select#audioSource');
var audioOutput = document.querySelector('select#audioOutput');
var videoSource = document.querySelector('select#videoSource');
//filter
var filtersSelect = document.querySelector('select#filter');
//picture
var snapshot = document.querySelector('button#snapshot');
var picture = document.querySelector('canvas#picture');
picture.width = 640;
picture.height = 480;
var videoplay = document.querySelector('video#player');
//var audioplay = document.querySelector('audio#audioplayer');
//div
var divConstraints = document.querySelector('div#constraints');
//record
var recvideo = document.querySelector('video#recplayer');
var btnRecord = document.querySelector('button#record');
var btnPlay = document.querySelector('button#recplay');
var btnDownload = document.querySelector('button#download');
var buffer;
var mediaRecorder;
//socket.io
var btnConnect = document.querySelector('button#connect');
var btnLeave = document.querySelector('button#leave');
var inputRoom = document.querySelector('input#room');
var socket;
var room;
function gotDevices(deviceInfos){
deviceInfos.forEach(function(deviceinfo){
var option = document.createElement('option');
option.text = deviceinfo.label;
option.value = deviceinfo.deviceId;
if(deviceinfo.kind === 'audioinput'){
audioSource.appendChild(option);
}else if(deviceinfo.kind === 'audiooutput'){
audioOutput.appendChild(option);
}else if(deviceinfo.kind === 'videoinput'){
videoSource.appendChild(option);
}
})
}
function gotMediaStream(stream){
var videoTrack = stream.getVideoTracks()[0];
var videoConstraints = videoTrack.getSettings();
divConstraints.textContent = JSON.stringify(videoConstraints, null, 2);
window.stream = stream;
videoplay.srcObject = stream;
//audioplay.srcObject = stream;
return navigator.mediaDevices.enumerateDevices();
}
function handleError(err){
console.log('getUserMedia error:', err);
}
function start() {
if(!navigator.mediaDevices ||
!navigator.mediaDevices.getUserMedia){
console.log('getUserMedia is not supported!');
return;
}else{
var deviceId = videoSource.value;
var constraints = {
video : {
width: 640,
height: 480,
frameRate:15,
facingMode: 'environment',
deviceId : deviceId ? {exact:deviceId} : undefined
},
audio : false
}
navigator.mediaDevices.getUserMedia(constraints)
.then(gotMediaStream)
.then(gotDevices)
.catch(handleError);
}
}
start();
videoSource.onchange = start;
filtersSelect.onchange = function(){
videoplay.className = filtersSelect.value;
}
snapshot.onclick = function() {
picture.className = filtersSelect.value;
picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
}
function handleDataAvailable(e){
if(e && e.data && e.data.size > 0){
buffer.push(e.data);
}
}
function startRecord(){
buffer = [];
var options = {
mimeType: 'video/webm;codecs=vp8'
}
if(!MediaRecorder.isTypeSupported(options.mimeType)){
console.error(`${options.mimeType} is not supported!`);
return;
}
try{
mediaRecorder = new MediaRecorder(window.stream, options);
}catch(e){
console.error('Failed to create MediaRecorder:', e);
return;
}
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(10);
}
function stopRecord(){
mediaRecorder.stop();
}
btnRecord.onclick = ()=>{
if(btnRecord.textContent === 'Start Record'){
startRecord();
btnRecord.textContent = 'Stop Record';
btnPlay.disabled = true;
btnDownload.disabled = true;
}else{
stopRecord();
btnRecord.textContent = 'Start Record';
btnPlay.disabled = false;
btnDownload.disabled = false;
}
}
btnPlay.onclick = ()=> {
var blob = new Blob(buffer, {type: 'video/webm'});
recvideo.src = window.URL.createObjectURL(blob);
recvideo.srcObject = null;
recvideo.controls = true;
recvideo.play();
}
btnDownload.onclick = ()=> {
var blob = new Blob(buffer, {type: 'video/webm'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.style.display = 'none';
a.download = 'aaa.webm';
a.click();
}
function connectServer(){
socket = io.connect();
btnLeave.disabled = false;
btnConnect.disabled = true;
///////
socket.on('joined', function(room, id){
console.log('The User(' + id + ') have joined into ' + room);
});
socket.on('leaved', function(room, id){
console.log('The User(' + id + ') have leaved from ' + room);
});
//join room
room = inputRoom.value;
if(room !== ''){
socket.emit('join', room);
}
}
btnConnect.onclick = ()=> {
connectServer();
}
btnLeave.onclick = ()=> {
if(room !== ''){
socket.emit('leave', room);
btnLeave.disabled = true;
btnConnect.disabled = false;
socket.disconnect();
}
}