7-1 【基础铺垫,学前有概念】WebRTC录制基本知识





7-2 【来点实战】录制音视频实战
录制完后开始播放。
录制完后也可以单击下载。
<html><meta charset="utf-8"><head><title>WebRTC 获取视频和音频</title><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 input device:</label><select id="audioSource"></select></div><div><label>audio output device:</label><select id="audioOutput"></select></div><div><label>video input device:</label><select id="videoSource"></select></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></section><section><table><!-- <audio autoplay controls id="audioplayer"></audio> --><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="http://webrtc.github.io/adapter/adapter-latest.js"></script><script src="./js/client.js"></script></body></html>
'use strict'//devicesvar audioSource = document.querySelector('select#audioSource');var audioOutput = document.querySelector('select#audioOutput');var videoSource = document.querySelector('select#videoSource');//filtervar filtersSelect = document.querySelector('select#filter');//picturevar snapshot = document.querySelector('button#snapshot');var picture = document.querySelector('canvas#picture');picture.width = 640;picture.height = 480;//videoplayvar videoplay = document.querySelector('video#player');//var audioplay = document.querySelector('audio#audioplayer');//divvar divConstraints = document.querySelector('div#constraints');//recordvar 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;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!');}else{var deviceId = videoSource.value;var constraints = {video : {width: 640,height: 480,frameRate: 15,facingMode: 'environment' ,deviceId : deviceId ? {exact:deviceId} : undefined},audio : false//{//noiseSuppression: true,//echoCancellation: true//}}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();}
7-3 【来点实战】WebRTC采集屏幕数据

打开谷歌浏览器,输入 chrome://flags 查看支持的选项
打开下面链接,启动某个功能。
chrome://flags/#enable-experimental-web-platform-features
代码实现,主要将上一节的
getUserMedia修改为getDisplayMedia。
代码实现
<html><meta charset="utf-8"><head><title>WebRTC 获取视频和音频</title><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 input device:</label><select id="audioSource"></select></div><div><label>audio output device:</label><select id="audioOutput"></select></div><div><label>video input device:</label><select id="videoSource"></select></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></section><section><table><!-- <audio autoplay controls id="audioplayer"></audio> --><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="http://webrtc.github.io/adapter/adapter-latest.js"></script><script src="./js/client.js"></script></body></html>
'use strict'//devicesvar audioSource = document.querySelector('select#audioSource');var audioOutput = document.querySelector('select#audioOutput');var videoSource = document.querySelector('select#videoSource');//filtervar filtersSelect = document.querySelector('select#filter');//picturevar snapshot = document.querySelector('button#snapshot');var picture = document.querySelector('canvas#picture');picture.width = 640;picture.height = 480;//videoplayvar videoplay = document.querySelector('video#player');//var audioplay = document.querySelector('audio#audioplayer');//divvar divConstraints = document.querySelector('div#constraints');//recordvar 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;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('getDisplayMedia error:', err);}//匹配视频设备切换function start() {if(!navigator.mediaDevices ||!navigator.mediaDevices.getDisplayMedia){console.log('getDisplayMedia is not supported!');}else{var deviceId = videoSource.value;var constraints = {// video : {// width: 640,// height: 480,// frameRate: 15,// facingMode: 'environment' ,// deviceId : deviceId ? {exact:deviceId} : undefined// },video :true,audio : false//{//noiseSuppression: true,//echoCancellation: true//}}navigator.mediaDevices.getDisplayMedia(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();}
