本章讲解WebRTC如何实现音视频数据采集,其中包括
1.通过 WebCam 获取视频流,
2.采集音频流,
3.设置Camera分辨率
4.视频渲染。

6-1 【基础铺垫,学前有概念】WebRTC音视频数据采集

图片.png

正确是
var constraints = {
video : true,
audio : true
}

  1. <html>
  2. <meta charset="utf-8">
  3. <head>
  4. <title>WebRTC 获取视频和音频</title>
  5. </head>
  6. <body>
  7. <video autoplay playsinline id="player"></video>
  8. <script src="http://webrtc.github.io/adapter/adapter-latest.js"></script>
  9. <script src="./js/client.js"></script>
  10. </body>
  11. </html>
  1. 'use strict'
  2. var videoplay = document.querySelector('video#player');
  3. function gotMediaStream(stream){
  4. videoplay.srcObject = stream;
  5. return navigator.mediaDevices.enumerateDevices();
  6. }
  7. function handleError(err){
  8. console.log('getUserMedia error:', err);
  9. }
  10. if(!navigator.mediaDevices ||
  11. !navigator.mediaDevices.getUserMedia){
  12. console.log('getUserMedia is not supported!');
  13. }else{
  14. var constraints = {
  15. video : true,
  16. audio : true
  17. }
  18. navigator.mediaDevices.getUserMedia(constraints)
  19. .then(gotMediaStream)
  20. .catch(handleError);
  21. }

6-2 【浏览器适配方法】WebRTCAPI适配

图片.png
图片.png
图片.png

  1. <html>
  2. <meta charset="utf-8">
  3. <head>
  4. <title>WebRTC 获取视频和音频</title>
  5. </head>
  6. <body>
  7. <video autoplay playsinline id="player"></video>
  8. <script src="http://webrtc.github.io/adapter/adapter-latest.js"></script>
  9. <script src="./js/client.js"></script>
  10. </body>
  11. </html>

6-3 【安全管理】获取音视频设备的访问权限

  1. <html>
  2. <meta charset="utf-8">
  3. <head>
  4. <title>WebRTC 获取视频和音频</title>
  5. </head>
  6. <body>
  7. <div>
  8. <label>audio input device:</label>
  9. <select id="audioSource"></select>
  10. </div>
  11. <div>
  12. <label>audio output device:</label>
  13. <select id="audioOutput"></select>
  14. </div>
  15. <div>
  16. <label>video input device:</label>
  17. <select id="videoSource"></select>
  18. </div>
  19. <video autoplay playsinline id="player"></video>
  20. <script src="http://webrtc.github.io/adapter/adapter-latest.js"></script>
  21. <script src="./js/client.js"></script>
  22. </body>
  23. </html>
  1. 'use strict'
  2. //devices
  3. var audioSource = document.querySelector('select#audioSource');
  4. var audioOutput = document.querySelector('select#audioOutput');
  5. var videoSource = document.querySelector('select#videoSource');
  6. var videoplay = document.querySelector('video#player');
  7. function gotDevices(deviceInfos){
  8. deviceInfos.forEach(function(deviceinfo){
  9. var option = document.createElement('option');
  10. option.text = deviceinfo.label;
  11. option.value = deviceinfo.deviceId;
  12. if(deviceinfo.kind === 'audioinput'){
  13. audioSource.appendChild(option);
  14. }else if(deviceinfo.kind === 'audiooutput'){
  15. audioOutput.appendChild(option);
  16. }else if(deviceinfo.kind === 'videoinput'){
  17. videoSource.appendChild(option);
  18. }
  19. })
  20. }
  21. function gotMediaStream(stream){
  22. videoplay.srcObject = stream;
  23. return navigator.mediaDevices.enumerateDevices();
  24. }
  25. function handleError(err){
  26. console.log('getUserMedia error:', err);
  27. }
  28. if(!navigator.mediaDevices ||
  29. !navigator.mediaDevices.getUserMedia){
  30. console.log('getUserMedia is not supported!');
  31. }else{
  32. var constraints = {
  33. video : true,
  34. audio : false
  35. }
  36. navigator.mediaDevices.getUserMedia(constraints)
  37. .then(gotMediaStream)
  38. .then(gotDevices)
  39. .catch(handleError);
  40. }

放在服务器运行使用https访问。
图片.png
本地双击index.html运行访问
图片.png
最后使用vscode,本地服务器运行
图片.png

6-4 【视频参数调整】视频约束

图片.png
aspectRatio一般不设置
图片.png
图片.png

  1. var constraints = {
  2. video : {
  3. width:640,
  4. height:480,
  5. frameRate:30,
  6. facingMode:'environment'
  7. },
  8. audio : false
  9. }

6-5 【音频参数调整】音频约束

图片.png
图片.png
图片.png
图片.png
图片.png

  1. var constraints = {
  2. video : {
  3. width: 640,
  4. height: 480,
  5. frameRate: 30,
  6. facingMode: 'environment' ,
  7. deviceId : deviceId ? {exact:deviceId} : undefined
  8. },
  9. audio : {
  10. noiseSuppression: true,
  11. echoCancellation: true
  12. }
  13. }

6-6 【来点实战】视频特效

图片.png
图片.png
https://www.runoob.com/cssref/css3-pr-filter.html

  1. <html>
  2. <meta charset="utf-8">
  3. <head>
  4. <title>WebRTC 获取视频和音频</title>
  5. <style>
  6. .none {
  7. -webkit-filter: none;
  8. }
  9. .blur {
  10. -webkit-filter: blur(3px);
  11. }
  12. .grayscale {
  13. -webkit-filter: grayscale(1);
  14. }
  15. .invert {
  16. -webkit-filter: invert(1);
  17. }
  18. .sepia {
  19. -webkit-filter: sepia(1);
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div>
  25. <label>audio input device:</label>
  26. <select id="audioSource"></select>
  27. </div>
  28. <div>
  29. <label>audio output device:</label>
  30. <select id="audioOutput"></select>
  31. </div>
  32. <div>
  33. <label>video input device:</label>
  34. <select id="videoSource"></select>
  35. </div>
  36. <div>
  37. <label>Filter:</label>
  38. <select id="filter">
  39. <option value="none">None</option>
  40. <option value="blur">blur</option>
  41. <option value="grayscale">Grayscale</option>
  42. <option value="invert">Invert</option>
  43. <option value="sepia">sepia</option>
  44. </select>
  45. </div>
  46. <div>
  47. <video autoplay playsinline id="player"></video>
  48. </div>
  49. <script src="http://webrtc.github.io/adapter/adapter-latest.js"></script>
  50. <script src="./js/client.js"></script>
  51. </body>
  52. </html>

client.js

  1. 'use strict'
  2. //devices
  3. var audioSource = document.querySelector('select#audioSource');
  4. var audioOutput = document.querySelector('select#audioOutput');
  5. var videoSource = document.querySelector('select#videoSource');
  6. //filter
  7. var filtersSelect = document.querySelector('select#filter');
  8. var videoplay = document.querySelector('video#player');
  9. function gotDevices(deviceInfos){
  10. deviceInfos.forEach(function(deviceinfo){
  11. var option = document.createElement('option');
  12. option.text = deviceinfo.label;
  13. option.value = deviceinfo.deviceId;
  14. if(deviceinfo.kind === 'audioinput'){
  15. audioSource.appendChild(option);
  16. }else if(deviceinfo.kind === 'audiooutput'){
  17. audioOutput.appendChild(option);
  18. }else if(deviceinfo.kind === 'videoinput'){
  19. videoSource.appendChild(option);
  20. }
  21. })
  22. }
  23. function gotMediaStream(stream){
  24. videoplay.srcObject = stream;
  25. return navigator.mediaDevices.enumerateDevices();
  26. }
  27. function handleError(err){
  28. console.log('getUserMedia error:', err);
  29. }
  30. //匹配视频设备切换
  31. function start() {
  32. if(!navigator.mediaDevices ||
  33. !navigator.mediaDevices.getUserMedia){
  34. console.log('getUserMedia is not supported!');
  35. }else{
  36. var deviceId = videoSource.value;
  37. var constraints = {
  38. video : {
  39. width: 640,
  40. height: 480,
  41. frameRate: 30,
  42. facingMode: 'environment' ,
  43. deviceId : deviceId ? {exact:deviceId} : undefined
  44. },
  45. audio : {
  46. noiseSuppression: true,
  47. echoCancellation: true
  48. }
  49. }
  50. navigator.mediaDevices.getUserMedia(constraints)
  51. .then(gotMediaStream)
  52. .then(gotDevices)
  53. .catch(handleError);
  54. }
  55. }
  56. start();
  57. videoSource.onchange = start;
  58. filtersSelect.onchange = function(){
  59. videoplay.className = filtersSelect.value;
  60. }

https://coding.imooc.com/learn/questiondetail/pylDvPyrvK2YkBNm.html

6-7 【来点实战】从视频中获取图片

1、先要获取视频流
2、增加摄像按钮,和Canvas显示采集到的图片
效果如下:
图片.png

  1. <html>
  2. <meta charset="utf-8">
  3. <head>
  4. <title>WebRTC 获取视频和音频</title>
  5. <style>
  6. .none {
  7. -webkit-filter: none;
  8. }
  9. .blur {
  10. -webkit-filter: blur(3px);
  11. }
  12. .grayscale {
  13. -webkit-filter: grayscale(1);
  14. }
  15. .invert {
  16. -webkit-filter: invert(1);
  17. }
  18. .sepia {
  19. -webkit-filter: sepia(1);
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div>
  25. <label>audio input device:</label>
  26. <select id="audioSource"></select>
  27. </div>
  28. <div>
  29. <label>audio output device:</label>
  30. <select id="audioOutput"></select>
  31. </div>
  32. <div>
  33. <label>video input device:</label>
  34. <select id="videoSource"></select>
  35. </div>
  36. <div>
  37. <label>Filter:</label>
  38. <select id="filter">
  39. <option value="none">None</option>
  40. <option value="blur">blur</option>
  41. <option value="grayscale">Grayscale</option>
  42. <option value="invert">Invert</option>
  43. <option value="sepia">sepia</option>
  44. </select>
  45. </div>
  46. <div>
  47. <video autoplay playsinline id="player"></video>
  48. </div>
  49. <div>
  50. <button id="snapshot">Take snapshot</button>
  51. </div>
  52. <div>
  53. <canvas id="picture"></canvas>
  54. </div>
  55. <script src="http://webrtc.github.io/adapter/adapter-latest.js"></script>
  56. <script src="./js/client.js"></script>
  57. </body>
  58. </html>
  1. 'use strict'
  2. //devices
  3. var audioSource = document.querySelector('select#audioSource');
  4. var audioOutput = document.querySelector('select#audioOutput');
  5. var videoSource = document.querySelector('select#videoSource');
  6. //filter
  7. var filtersSelect = document.querySelector('select#filter');
  8. //picture
  9. var snapshot = document.querySelector('button#snapshot');
  10. var picture = document.querySelector('canvas#picture');
  11. picture.width = 640;
  12. picture.height = 480;
  13. //videoplay
  14. var videoplay = document.querySelector('video#player');
  15. function gotDevices(deviceInfos){
  16. deviceInfos.forEach(function(deviceinfo){
  17. var option = document.createElement('option');
  18. option.text = deviceinfo.label;
  19. option.value = deviceinfo.deviceId;
  20. if(deviceinfo.kind === 'audioinput'){
  21. audioSource.appendChild(option);
  22. }else if(deviceinfo.kind === 'audiooutput'){
  23. audioOutput.appendChild(option);
  24. }else if(deviceinfo.kind === 'videoinput'){
  25. videoSource.appendChild(option);
  26. }
  27. })
  28. }
  29. function gotMediaStream(stream){
  30. videoplay.srcObject = stream;
  31. return navigator.mediaDevices.enumerateDevices();
  32. }
  33. function handleError(err){
  34. console.log('getUserMedia error:', err);
  35. }
  36. //匹配视频设备切换
  37. function start() {
  38. if(!navigator.mediaDevices ||
  39. !navigator.mediaDevices.getUserMedia){
  40. console.log('getUserMedia is not supported!');
  41. }else{
  42. var deviceId = videoSource.value;
  43. var constraints = {
  44. video : {
  45. width: 640,
  46. height: 480,
  47. frameRate: 30,
  48. facingMode: 'environment' ,
  49. deviceId : deviceId ? {exact:deviceId} : undefined
  50. },
  51. audio : {
  52. noiseSuppression: true,
  53. echoCancellation: true
  54. }
  55. }
  56. navigator.mediaDevices.getUserMedia(constraints)
  57. .then(gotMediaStream)
  58. .then(gotDevices)
  59. .catch(handleError);
  60. }
  61. }
  62. start();
  63. videoSource.onchange = start;
  64. filtersSelect.onchange = function(){
  65. videoplay.className = filtersSelect.value;
  66. }
  67. snapshot.onclick = function() {
  68. picture.className = filtersSelect.value; //如果先前使用了滤镜,则在截图后,也会使用滤镜
  69. picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
  70. }

注意,这时候的图片,保存的是原始截图的图片。

6-8 【来点实战】WebRTC只采集音频数据

图片.png

  1. <html>
  2. <meta charset="utf-8">
  3. <head>
  4. <title>WebRTC 获取视频和音频</title>
  5. <style>
  6. .none {
  7. -webkit-filter: none;
  8. }
  9. .blur {
  10. -webkit-filter: blur(3px);
  11. }
  12. .grayscale {
  13. -webkit-filter: grayscale(1);
  14. }
  15. .invert {
  16. -webkit-filter: invert(1);
  17. }
  18. .sepia {
  19. -webkit-filter: sepia(1);
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div>
  25. <label>audio input device:</label>
  26. <select id="audioSource"></select>
  27. </div>
  28. <div>
  29. <label>audio output device:</label>
  30. <select id="audioOutput"></select>
  31. </div>
  32. <div>
  33. <label>video input device:</label>
  34. <select id="videoSource"></select>
  35. </div>
  36. <div>
  37. <label>Filter:</label>
  38. <select id="filter">
  39. <option value="none">None</option>
  40. <option value="blur">blur</option>
  41. <option value="grayscale">Grayscale</option>
  42. <option value="invert">Invert</option>
  43. <option value="sepia">sepia</option>
  44. </select>
  45. </div>
  46. <div>
  47. <audio autoplay controls id="audioplayer"></audio>
  48. <!-- <video autoplay playsinline id="player"></video> -->
  49. </div>
  50. <div>
  51. <button id="snapshot">Take snapshot</button>
  52. </div>
  53. <div>
  54. <canvas id="picture"></canvas>
  55. </div>
  56. <script src="http://webrtc.github.io/adapter/adapter-latest.js"></script>
  57. <script src="./js/client.js"></script>
  58. </body>
  59. </html>
  1. 'use strict'
  2. //devices
  3. var audioSource = document.querySelector('select#audioSource');
  4. var audioOutput = document.querySelector('select#audioOutput');
  5. var videoSource = document.querySelector('select#videoSource');
  6. //filter
  7. var filtersSelect = document.querySelector('select#filter');
  8. //picture
  9. var snapshot = document.querySelector('button#snapshot');
  10. var picture = document.querySelector('canvas#picture');
  11. picture.width = 640;
  12. picture.height = 480;
  13. //videoplay
  14. //var videoplay = document.querySelector('video#player');
  15. var audioplay = document.querySelector('audio#audioplayer');
  16. function gotDevices(deviceInfos){
  17. deviceInfos.forEach(function(deviceinfo){
  18. var option = document.createElement('option');
  19. option.text = deviceinfo.label;
  20. option.value = deviceinfo.deviceId;
  21. if(deviceinfo.kind === 'audioinput'){
  22. audioSource.appendChild(option);
  23. }else if(deviceinfo.kind === 'audiooutput'){
  24. audioOutput.appendChild(option);
  25. }else if(deviceinfo.kind === 'videoinput'){
  26. videoSource.appendChild(option);
  27. }
  28. })
  29. }
  30. function gotMediaStream(stream){
  31. //videoplay.srcObject = stream;
  32. audioplay.srcObject = stream;
  33. return navigator.mediaDevices.enumerateDevices();
  34. }
  35. function handleError(err){
  36. console.log('getUserMedia error:', err);
  37. }
  38. //匹配视频设备切换
  39. function start() {
  40. if(!navigator.mediaDevices ||
  41. !navigator.mediaDevices.getUserMedia){
  42. console.log('getUserMedia is not supported!');
  43. }else{
  44. var deviceId = videoSource.value;
  45. /* var constraints = {
  46. video : {
  47. width: 640,
  48. height: 480,
  49. frameRate: 30,
  50. facingMode: 'environment' ,
  51. deviceId : deviceId ? {exact:deviceId} : undefined
  52. },
  53. audio : {
  54. noiseSuppression: true,
  55. echoCancellation: true
  56. }
  57. } */
  58. var constraints = {
  59. video : false,
  60. audio : true
  61. }
  62. navigator.mediaDevices.getUserMedia(constraints)
  63. .then(gotMediaStream)
  64. .then(gotDevices)
  65. .catch(handleError);
  66. }
  67. }
  68. start();
  69. videoSource.onchange = start;
  70. filtersSelect.onchange = function(){
  71. videoplay.className = filtersSelect.value;
  72. }
  73. snapshot.onclick = function() {
  74. picture.className = filtersSelect.value; //如果先前使用了滤镜,则在截图后,也会使用滤镜
  75. picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
  76. }

6-9 【来点实战】MediaStreamAPI及获取视频约束

图片.png
图片.png
图片.png

  1. <html>
  2. <meta charset="utf-8">
  3. <head>
  4. <title>WebRTC 获取视频和音频</title>
  5. <style>
  6. .none {
  7. -webkit-filter: none;
  8. }
  9. .blur {
  10. -webkit-filter: blur(3px);
  11. }
  12. .grayscale {
  13. -webkit-filter: grayscale(1);
  14. }
  15. .invert {
  16. -webkit-filter: invert(1);
  17. }
  18. .sepia {
  19. -webkit-filter: sepia(1);
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <section>
  25. <div>
  26. <label>audio input device:</label>
  27. <select id="audioSource"></select>
  28. </div>
  29. <div>
  30. <label>audio output device:</label>
  31. <select id="audioOutput"></select>
  32. </div>
  33. <div>
  34. <label>video input device:</label>
  35. <select id="videoSource"></select>
  36. </div>
  37. </section>
  38. <section>
  39. <div>
  40. <label>Filter:</label>
  41. <select id="filter">
  42. <option value="none">None</option>
  43. <option value="blur">blur</option>
  44. <option value="grayscale">Grayscale</option>
  45. <option value="invert">Invert</option>
  46. <option value="sepia">sepia</option>
  47. </select>
  48. </div>
  49. </section>
  50. <section>
  51. <table>
  52. <!-- <audio autoplay controls id="audioplayer"></audio> -->
  53. <tr>
  54. <td><video autoplay playsinline id="player"></video> </td>
  55. <td><div id='constraints' class='output'></div></td>
  56. </tr>
  57. </table>
  58. </section>
  59. <section>
  60. <div>
  61. <button id="snapshot">Take snapshot</button>
  62. </div>
  63. <div>
  64. <canvas id="picture"></canvas>
  65. </div>
  66. </section>
  67. <script src="http://webrtc.github.io/adapter/adapter-latest.js"></script>
  68. <script src="./js/client.js"></script>
  69. </body>
  70. </html>
  1. 'use strict'
  2. //devices
  3. var audioSource = document.querySelector('select#audioSource');
  4. var audioOutput = document.querySelector('select#audioOutput');
  5. var videoSource = document.querySelector('select#videoSource');
  6. //filter
  7. var filtersSelect = document.querySelector('select#filter');
  8. //picture
  9. var snapshot = document.querySelector('button#snapshot');
  10. var picture = document.querySelector('canvas#picture');
  11. picture.width = 640;
  12. picture.height = 480;
  13. //videoplay
  14. var videoplay = document.querySelector('video#player');
  15. //var audioplay = document.querySelector('audio#audioplayer');
  16. //div
  17. var divConstraints = document.querySelector('div#constraints');
  18. function gotDevices(deviceInfos){
  19. deviceInfos.forEach(function(deviceinfo){
  20. var option = document.createElement('option');
  21. option.text = deviceinfo.label;
  22. option.value = deviceinfo.deviceId;
  23. if(deviceinfo.kind === 'audioinput'){
  24. audioSource.appendChild(option);
  25. }else if(deviceinfo.kind === 'audiooutput'){
  26. audioOutput.appendChild(option);
  27. }else if(deviceinfo.kind === 'videoinput'){
  28. videoSource.appendChild(option);
  29. }
  30. })
  31. }
  32. function gotMediaStream(stream){
  33. var videoTrack = stream.getVideoTracks()[0];
  34. var videoConstraints = videoTrack.getSettings();
  35. divConstraints.textContent = JSON.stringify(videoConstraints, null, 2);
  36. window.stream = stream;
  37. videoplay.srcObject = stream;
  38. //audioplay.srcObject = stream;
  39. return navigator.mediaDevices.enumerateDevices();
  40. }
  41. function handleError(err){
  42. console.log('getUserMedia error:', err);
  43. }
  44. //匹配视频设备切换
  45. function start() {
  46. if(!navigator.mediaDevices ||
  47. !navigator.mediaDevices.getUserMedia){
  48. console.log('getUserMedia is not supported!');
  49. }else{
  50. var deviceId = videoSource.value;
  51. var constraints = {
  52. video : {
  53. width: 640,
  54. height: 480,
  55. frameRate: 15,
  56. facingMode: 'environment' ,
  57. deviceId : deviceId ? {exact:deviceId} : undefined
  58. },
  59. audio : false
  60. //{
  61. //noiseSuppression: true,
  62. //echoCancellation: true
  63. //}
  64. }
  65. navigator.mediaDevices.getUserMedia(constraints)
  66. .then(gotMediaStream)
  67. .then(gotDevices)
  68. .catch(handleError);
  69. }
  70. }
  71. start();
  72. videoSource.onchange = start;
  73. filtersSelect.onchange = function(){
  74. videoplay.className = filtersSelect.value;
  75. }
  76. snapshot.onclick = function() {
  77. picture.className = filtersSelect.value; //如果先前使用了滤镜,则在截图后,也会使用滤镜
  78. picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
  79. }

6-10 相关资料

代码手写.zip