123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- 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;
|