import "./media-polyfill"; class Media { constructor(videoElement) { this.videoElement = videoElement; this.timer = null; //audio frame this.init(); } init() { this.initAudio(); this.initCamera(); } initAudio() { // set up forked web audio context, for multiple browsers // window. is needed otherwise Safari explodes this.audioCtx = new (window.AudioContext || window.webkitAudioContext)(); this.source = null; this.stream = null; //set up the different audio nodes we will use for the app this.analyser = this.audioCtx.createAnalyser(); this.analyser.minDecibels = -90; this.analyser.maxDecibels = -10; this.analyser.smoothingTimeConstant = 0.85; this.distortion = this.audioCtx.createWaveShaper(); this.gainNode = this.audioCtx.createGain(); this.biquadFilter = this.audioCtx.createBiquadFilter(); this.convolver = this.audioCtx.createConvolver(); } setAudio() { this.source = this.audioCtx.createMediaStreamSource(this.stream); this.source.connect(this.distortion); this.distortion.connect(this.biquadFilter); this.biquadFilter.connect(this.gainNode); this.convolver.connect(this.gainNode); this.gainNode.connect(this.analyser); this.analyser.connect(this.audioCtx.destination); this.analyser.fftSize = 256; this.bufferLengthAlt = this.analyser.frequencyBinCount; this.dataArrayAlt = new Uint8Array(this.bufferLengthAlt); this.distortion.oversample = "4x"; this.biquadFilter.disconnect(0); this.biquadFilter.connect(this.gainNode); } initCamera() { // Get access to the camera! if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { // Not adding `{ audio: true }` since we only want video now navigator.mediaDevices .getUserMedia({ audio: true, video: { facingMode: "user", width: { min: 375, ideal: 750, max: 1280 }, height: { min: 800, ideal: 900, max: 1080 } } }) .then(stream => { // Older browsers may not have srcObject if ("srcObject" in this.videoElement) { this.videoElement.srcObject = stream; } else { // Avoid using this in new browsers, as it is going away. this.videoElement.src = window.URL.createObjectURL( stream ); } this.videoElement.onloadedmetadata = e => { this.videoElement.play(); this.stream = stream; this.setAudio(); this.getDecibel(); }; }) .catch(error => { alert("get access to the camera error:" + error.message); }); } else { alert("we can not get access to the camera!"); } } getDecibel() { this.gainNode.gain.setTargetAtTime(0.1, this.audioCtx.currentTime, 0); //播放声音 this.analyser.getByteFrequencyData(this.dataArrayAlt); let max = 0; this.dataArrayAlt.forEach(decibel => { max = Math.max(decibel, max); }); this.decibel = max; this.decibelCallbacks && this.decibelCallbacks(this.decibel); this.timer = requestAnimationFrame(this.getDecibel.bind(this)); } add(fn) { this.decibelCallbacks = fn; } } export default Media;