media.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import "./media-polyfill";
  2. class Media {
  3. constructor(videoElement) {
  4. this.videoElement = videoElement;
  5. this.timer = null; //audio frame
  6. this.init();
  7. }
  8. init() {
  9. this.initAudio();
  10. this.initCamera();
  11. }
  12. initAudio() {
  13. // set up forked web audio context, for multiple browsers
  14. // window. is needed otherwise Safari explodes
  15. this.audioCtx = new (window.AudioContext ||
  16. window.webkitAudioContext)();
  17. this.source = null;
  18. this.stream = null;
  19. //set up the different audio nodes we will use for the app
  20. this.analyser = this.audioCtx.createAnalyser();
  21. this.analyser.minDecibels = -90;
  22. this.analyser.maxDecibels = -10;
  23. this.analyser.smoothingTimeConstant = 0.85;
  24. this.distortion = this.audioCtx.createWaveShaper();
  25. this.gainNode = this.audioCtx.createGain();
  26. this.biquadFilter = this.audioCtx.createBiquadFilter();
  27. this.convolver = this.audioCtx.createConvolver();
  28. }
  29. setAudio() {
  30. this.source = this.audioCtx.createMediaStreamSource(this.stream);
  31. this.source.connect(this.distortion);
  32. this.distortion.connect(this.biquadFilter);
  33. this.biquadFilter.connect(this.gainNode);
  34. this.convolver.connect(this.gainNode);
  35. this.gainNode.connect(this.analyser);
  36. this.analyser.connect(this.audioCtx.destination);
  37. this.analyser.fftSize = 256;
  38. this.bufferLengthAlt = this.analyser.frequencyBinCount;
  39. this.dataArrayAlt = new Uint8Array(this.bufferLengthAlt);
  40. this.distortion.oversample = "4x";
  41. this.biquadFilter.disconnect(0);
  42. this.biquadFilter.connect(this.gainNode);
  43. }
  44. initCamera() {
  45. // Get access to the camera!
  46. if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
  47. // Not adding `{ audio: true }` since we only want video now
  48. navigator.mediaDevices
  49. .getUserMedia({
  50. audio: true
  51. // ,
  52. // video: {
  53. // facingMode: "user",
  54. // width: { min: 640, ideal: 1024, max: 1600 },
  55. // height: { min: 480, ideal: 768, max: 1200 }
  56. // }
  57. })
  58. .then(stream => {
  59. // // Older browsers may not have srcObject
  60. // if ("srcObject" in this.videoElement) {
  61. // this.videoElement.srcObject = stream;
  62. // } else {
  63. // // Avoid using this in new browsers, as it is going away.
  64. // this.videoElement.src = window.URL.createObjectURL(
  65. // stream
  66. // );
  67. // }
  68. // this.videoElement.onloadedmetadata = e => {
  69. // this.videoElement.play();
  70. // this.stream = stream;
  71. // this.setAudio();
  72. // this.getDecibel();
  73. // };
  74. this.stream = stream;
  75. this.setAudio();
  76. this.getDecibel();
  77. })
  78. .catch(error => {
  79. console.error("get access to the camera error:" + error.message);
  80. });
  81. } else {
  82. console.error("we can not get access to the camera!");
  83. }
  84. }
  85. getDecibel() {
  86. this.gainNode.gain.setTargetAtTime(0.1, this.audioCtx.currentTime, 0); //播放声音
  87. this.analyser.getByteFrequencyData(this.dataArrayAlt);
  88. let max = 0;
  89. this.dataArrayAlt.forEach(decibel => {
  90. max = Math.max(decibel, max);
  91. });
  92. this.decibel = max;
  93. this.decibelCallbacks && this.decibelCallbacks(this.decibel);
  94. this.timer = requestAnimationFrame(this.getDecibel.bind(this));
  95. }
  96. add(fn) {
  97. this.decibelCallbacks = fn;
  98. }
  99. }
  100. export default Media;