UNPKG

@e10in/videojs-record

Version:

A video.js plugin for recording audio/video/image files.

8 lines 17.3 kB
/*! * vmsg plugin for @e10in/videojs-record * @version 4.4.4 * @see https://github.com/collab-project/videojs-record * @copyright 2014-2021 Collab * @license MIT */ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("video.js")):"function"==typeof define&&define.amd?define("VideojsRecord",["video.js"],t):"object"==typeof exports?exports.VideojsRecord=t(require("video.js")):(e.VideojsRecord=e.VideojsRecord||{},e.VideojsRecord.vmsg=t(e.videojs))}(self,(function(e){return(()=>{var t={1506:e=>{e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},4575:e=>{e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},3913:e=>{function t(e,t){for(var i=0;i<t.length;i++){var r=t[i];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}e.exports=function(e,i,r){return i&&t(e.prototype,i),r&&t(e,r),e}},9754:e=>{function t(i){return e.exports=t=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},t(i)}e.exports=t},2205:(e,t,i)=>{var r=i(9489);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&r(e,t)}},5318:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}}},8585:(e,t,i)=>{var r=i(8),n=i(1506);e.exports=function(e,t){return!t||"object"!==r(t)&&"function"!=typeof t?n(e):t}},9489:e=>{function t(i,r){return e.exports=t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},t(i,r)}e.exports=t},8:e=>{function t(i){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?e.exports=t=function(e){return typeof e}:e.exports=t=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t(i)}e.exports=t},9077:(e,t,i)=>{"use strict";var r=i(5318);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=r(i(4575)),s=r(i(3913)),o=r(i(2205)),a=r(i(8585)),c=r(i(9754)),l=r(i(4390)),d=i(1049);function u(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}();return function(){var i,r=(0,c.default)(e);if(t){var n=(0,c.default)(this).constructor;i=Reflect.construct(r,arguments,n)}else i=r.apply(this,arguments);return(0,a.default)(this,i)}}var h=function(e){(0,o.default)(i,e);var t=u(i);function i(e,r){var s;return(0,n.default)(this,i),(s=t.call(this,e,r)).debug=!1,s.audioWebAssemblyURL="vmsg.wasm",s.pluginLibraryOptions={},s}return(0,s.default)(i,[{key:"setup",value:function(e,t,i){var r=this;this.inputStream=e,this.mediaType=t,this.debug=i,this.config={wasmURL:this.audioWebAssemblyURL},this.config=Object.assign(this.config,this.pluginLibraryOptions),this.engine=new d.Recorder(this.config,this.onRecordingAvailable.bind(this)),this.engine.stream=this.inputStream;var n=window.AudioContext||window.webkitAudioContext;this.audioContext=new n,this.audioSourceNode=this.audioContext.createMediaStreamSource(this.inputStream),this.processor=this.audioContext.createScriptProcessor(0,1,1),this.audioSourceNode.connect(this.processor),this.engine.initWorker().catch((function(e){r.player().trigger("error",e)}))}},{key:"start",value:function(){this.engine.blob=null,this.engine.blobURL&&URL.revokeObjectURL(this.engine.blobURL),this.engine.blobURL=null,this.engine.worker.postMessage({type:"start",data:this.audioContext.sampleRate}),this.processor.onaudioprocess=this.onAudioProcess.bind(this),this.processor.connect(this.audioContext.destination)}},{key:"stop",value:function(){this.processor&&(this.processor.disconnect(),this.processor.onaudioprocess=null),this.engine&&void 0!==this.engine.worker&&this.engine.worker.postMessage({type:"stop",data:null})}},{key:"destroy",value:function(){this.engine&&"function"==typeof this.engine.close&&this.engine.close()}},{key:"onAudioProcess",value:function(e){var t=e.inputBuffer.getChannelData(0);this.engine.worker.postMessage({type:"data",data:t})}},{key:"onRecordingAvailable",value:function(){this.onStopRecording(this.engine.blob)}}]),i}(l.default.getComponent("RecordEngine"));l.default.VmsgEngine=h;var p=h;t.default=p,e.exports=t.default},1049:(e,t,i)=>{"use strict";function r(e){return(e|=0)<10?`0${e}`:`${Math.min(e,99)}`}function n(){function e(e,t){return new Promise(((i,r)=>{const n=new XMLHttpRequest;n.open("GET",e),n.responseType="arraybuffer",n.onload=()=>{i(WebAssembly.instantiate(n.response,t))},n.onerror=r,n.send()}))}let t=null,i=5242880;function r(e){const t=i;return i+=e,t}function n(e){postMessage({type:"internal-error",data:e})}let s=null,o=null,a=null;onmessage=i=>{const c=i.data;switch(c.type){case"init":const{wasmURL:i,shimURL:d}=c.data;Promise.resolve().then((()=>(self.WebAssembly&&!function(){const e=new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11]),t=new WebAssembly.Module(e);return 0!==new WebAssembly.Instance(t,{}).exports.test(4)}()&&delete self.WebAssembly,self.WebAssembly||importScripts(d),t=new WebAssembly.Memory({initial:256,maximum:256}),{memory:t,pow:Math.pow,exit:n,powf:Math.pow,exp:Math.exp,sqrtf:Math.sqrt,cos:Math.cos,log:Math.log,sin:Math.sin,sbrk:r}))).then((t=>function(t,i){if(!WebAssembly.instantiateStreaming)return e(t,i);const r=fetch(t,{credentials:"same-origin"});return WebAssembly.instantiateStreaming(r,i).catch((r=>{if(r.message&&r.message.indexOf("Argument 0 must be provided and must be a Response")>0)return e(t,i);throw r}))}(i,{env:t}))).then((e=>{s=e.instance.exports,postMessage({type:"init",data:null})})).catch((e=>{postMessage({type:"init-error",data:e.toString()})}));break;case"start":if(!function(e){if(o=s.vmsg_init(e),!o)return!1;const i=new Uint32Array(t.buffer,o,1)[0];return a=new Float32Array(t.buffer,i),!0}(c.data))return postMessage({type:"error",data:"vmsg_init"});break;case"data":if(l=c.data,a.set(l),!(s.vmsg_encode(o,l.length)>=0))return postMessage({type:"error",data:"vmsg_encode"});break;case"stop":const u=function(){if(s.vmsg_flush(o)<0)return null;const e=new Uint32Array(t.buffer,o+4,1)[0],i=new Uint32Array(t.buffer,o+8,1)[0],r=new Uint8Array(t.buffer,e,i),n=new Blob([r],{type:"audio/mpeg"});return s.vmsg_free(o),o=null,a=null,n}();if(!u)return postMessage({type:"error",data:"vmsg_flush"});postMessage({type:"stop",data:u})}var l}}i.r(t),i.d(t,{Recorder:()=>s,Form:()=>o,record:()=>c,default:()=>l});class s{constructor(e={},t=null){this.wasmURL=new URL(e.wasmURL||"/static/js/vmsg.wasm",location).href,this.shimURL=new URL(e.shimURL||"/static/js/wasm-polyfill.js",location).href,this.onStop=t,this.pitch=e.pitch||0,this.stream=null,this.audioCtx=null,this.gainNode=null,this.pitchFX=null,this.encNode=null,this.worker=null,this.workerURL=null,this.blob=null,this.blobURL=null,this.resolve=null,this.reject=null,Object.seal(this)}close(){this.encNode&&this.encNode.disconnect(),this.encNode&&(this.encNode.onaudioprocess=null),this.stream&&this.stopTracks(),this.audioCtx&&this.audioCtx.close(),this.worker&&(this.worker.terminate(),this.worker=null),this.workerURL&&URL.revokeObjectURL(this.workerURL),this.blobURL&&URL.revokeObjectURL(this.blobURL)}initAudio(){return(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia?function(e){return navigator.mediaDevices.getUserMedia(e)}:function(e){const t=navigator.webkitGetUserMedia||navigator.mozGetUserMedia;return t?new Promise((function(i,r){t.call(navigator,e,i,r)})):Promise.reject(new Error("getUserMedia is not implemented in this browser"))})({audio:!0}).then((e=>{this.stream=e;const t=this.audioCtx=new(window.AudioContext||window.webkitAudioContext),i=t.createMediaStreamSource(e),r=this.gainNode=(t.createGain||t.createGainNode).call(t);r.gain.value=1,i.connect(r);const n=this.pitchFX=new p(t);n.setPitchOffset(this.pitch);const s=this.encNode=(t.createScriptProcessor||t.createJavaScriptNode).call(t,0,1,1);n.output.connect(s),r.connect(0===this.pitch?s:n.input)}))}initWorker(){if(this.worker)return Promise.resolve();const e=new Blob(["(",n.toString(),")()"],{type:"application/javascript"}),t=this.workerURL=URL.createObjectURL(e),i=this.worker=new Worker(t),{wasmURL:r,shimURL:s}=this;return i.postMessage({type:"init",data:{wasmURL:r,shimURL:s}}),new Promise(((e,t)=>{i.onmessage=i=>{const r=i.data;switch(r.type){case"init":e();break;case"init-error":this.close(),t(new Error(r.data));break;case"error":case"internal-error":this.close(),console.error("Worker error:",r.data),this.reject&&this.reject(r.data);break;case"stop":this.blob=r.data,this.blobURL=URL.createObjectURL(r.data),this.onStop&&this.onStop(),this.resolve&&this.resolve(this.blob)}}}))}init(){return this.initAudio().then(this.initWorker.bind(this))}startRecording(){if(!this.stream)throw new Error("missing audio initialization");if(!this.worker)throw new Error("missing worker initialization");this.blob=null,this.blobURL&&URL.revokeObjectURL(this.blobURL),this.blobURL=null,this.resolve=null,this.reject=null,this.worker.postMessage({type:"start",data:this.audioCtx.sampleRate}),this.encNode.onaudioprocess=e=>{const t=e.inputBuffer.getChannelData(0);this.worker.postMessage({type:"data",data:t})},this.encNode.connect(this.audioCtx.destination)}stopRecording(){if(!this.stream)throw new Error("missing audio initialization");if(!this.worker)throw new Error("missing worker initialization");return this.encNode.disconnect(),this.encNode.onaudioprocess=null,this.stopTracks(),this.audioCtx.close(),this.worker.postMessage({type:"stop",data:null}),new Promise(((e,t)=>{this.resolve=e,this.reject=t}))}stopTracks(){this.stream.getTracks&&this.stream.getTracks().forEach((e=>e.stop()))}}class o{constructor(e={},t,i){this.recorder=new s(e,this.onStop.bind(this)),this.resolve=t,this.reject=i,this.backdrop=null,this.popup=null,this.recordBtn=null,this.stopBtn=null,this.timer=null,this.audio=null,this.saveBtn=null,this.tid=0,this.start=0,Object.seal(this),this.recorder.initAudio().then((()=>this.drawInit())).then((()=>this.recorder.initWorker())).then((()=>this.drawAll())).catch((e=>this.drawError(e)))}drawInit(){if(this.backdrop)return;const e=this.backdrop=document.createElement("div");e.className="vmsg-backdrop",e.addEventListener("click",(()=>this.close(null)));const t=this.popup=document.createElement("div");t.className="vmsg-popup",t.addEventListener("click",(e=>e.stopPropagation()));const i=document.createElement("div");i.className="vmsg-progress";for(let e=0;e<3;e++){const e=document.createElement("div");e.className="vmsg-progress-dot",i.appendChild(e)}t.appendChild(i),e.appendChild(t),document.body.appendChild(e)}drawTime(e){const t=Math.round(e/1e3);this.timer.textContent=r(t/60)+":"+r(t%60)}drawAll(){this.drawInit(),this.clearAll();const e=document.createElement("div");e.className="vmsg-record-row",this.popup.appendChild(e);const t=this.recordBtn=document.createElement("button");t.className="vmsg-button vmsg-record-button",t.textContent="●",t.title="Start Recording",t.addEventListener("click",(()=>this.startRecording())),e.appendChild(t);const i=this.stopBtn=document.createElement("button");i.className="vmsg-button vmsg-stop-button",i.style.display="none",i.textContent="■",i.title="Stop Recording",i.addEventListener("click",(()=>this.stopRecording())),e.appendChild(i);const r=this.audio=new Audio;r.autoplay=!0;const n=this.timer=document.createElement("span");n.className="vmsg-timer",n.title="Preview Recording",n.addEventListener("click",(()=>{r.paused?this.recorder.blobURL&&(r.src=this.recorder.blobURL):r.pause()})),this.drawTime(0),e.appendChild(n);const s=this.saveBtn=document.createElement("button");s.className="vmsg-button vmsg-save-button",s.textContent="✓",s.title="Save Recording",s.disabled=!0,s.addEventListener("click",(()=>this.close(this.recorder.blob))),e.appendChild(s);const o=document.createElement("div");o.className="vmsg-slider-wrapper vmsg-gain-slider-wrapper";const a=document.createElement("input");a.className="vmsg-slider vmsg-gain-slider",a.setAttribute("type","range"),a.min=0,a.max=2,a.step=.2,a.value=1,a.onchange=()=>{const e=+a.value;this.recorder.gainNode.gain.value=e},o.appendChild(a),this.popup.appendChild(o);const c=document.createElement("div");c.className="vmsg-slider-wrapper vmsg-pitch-slider-wrapper";const l=document.createElement("input");l.className="vmsg-slider vmsg-pitch-slider",l.setAttribute("type","range"),l.min=-1,l.max=1,l.step=.2,l.value=this.recorder.pitch,l.onchange=()=>{const e=+l.value;this.recorder.pitchFX.setPitchOffset(e),this.recorder.gainNode.disconnect(),this.recorder.gainNode.connect(0===e?this.recorder.encNode:this.recorder.pitchFX.input)},c.appendChild(l),this.popup.appendChild(c),t.focus()}drawError(e){console.error(e),this.drawInit(),this.clearAll();const t=document.createElement("div");t.className="vmsg-error",t.textContent=e.toString(),this.popup.appendChild(t)}clearAll(){this.popup&&(this.popup.innerHTML="")}close(e){this.audio&&this.audio.pause(),this.tid&&clearTimeout(this.tid),this.recorder.close(),this.backdrop.remove(),e?this.resolve(e):this.reject(new Error("No record made"))}onStop(){this.recordBtn.style.display="",this.stopBtn.style.display="none",this.stopBtn.disabled=!1,this.saveBtn.disabled=!1}startRecording(){this.audio.pause(),this.start=Date.now(),this.updateTime(),this.recordBtn.style.display="none",this.stopBtn.style.display="",this.saveBtn.disabled=!0,this.stopBtn.focus(),this.recorder.startRecording()}stopRecording(){clearTimeout(this.tid),this.tid=0,this.stopBtn.disabled=!0,this.recordBtn.focus(),this.recorder.stopRecording()}updateTime(){this.drawTime(Date.now()-this.start),this.tid=setTimeout((()=>this.updateTime()),300)}}let a=!1;function c(e){return new Promise(((t,i)=>{if(a)throw new Error("Record form is already opened");a=!0,new o(e,t,i)})).then((e=>(a=!1,e)),(e=>{throw a=!1,e}))}const l={Recorder:s,Form:o,record:c},d=.05,u=.1;function h(e,t,i,r){for(var n=t*e.sampleRate,s=n+(t-2*i)*e.sampleRate,o=e.createBuffer(1,s,e.sampleRate),a=o.getChannelData(0),c=0;c<n;++c)a[c]=r?(n-c)/s:c/n;for(c=n;c<s;++c)a[c]=0;return o}function p(e){this.context=e;var t=(e.createGain||e.createGainNode).call(e),i=(e.createGain||e.createGainNode).call(e);this.input=t,this.output=i;var r=e.createBufferSource(),n=e.createBufferSource(),s=e.createBufferSource(),o=e.createBufferSource();this.shiftDownBuffer=h(e,u,d,!1),this.shiftUpBuffer=h(e,u,d,!0),r.buffer=this.shiftDownBuffer,n.buffer=this.shiftDownBuffer,s.buffer=this.shiftUpBuffer,o.buffer=this.shiftUpBuffer,r.loop=!0,n.loop=!0,s.loop=!0,o.loop=!0;var a=(e.createGain||e.createGainNode).call(e),c=(e.createGain||e.createGainNode).call(e),l=(e.createGain||e.createGainNode).call(e);l.gain.value=0;var p=(e.createGain||e.createGainNode).call(e);p.gain.value=0,r.connect(a),n.connect(c),s.connect(l),o.connect(p);var f=(e.createGain||e.createGainNode).call(e),m=(e.createGain||e.createGainNode).call(e),g=(e.createDelay||e.createDelayNode).call(e),b=(e.createDelay||e.createDelayNode).call(e);a.connect(f),c.connect(m),l.connect(f),p.connect(m),f.connect(g.delayTime),m.connect(b.delayTime);var v=e.createBufferSource(),y=e.createBufferSource(),w=function(e,t,i){for(var r=t*e.sampleRate,n=r+(t-2*i)*e.sampleRate,s=e.createBuffer(1,n,e.sampleRate),o=s.getChannelData(0),a=i*e.sampleRate,c=a,l=r-a,d=0;d<r;++d){var u;u=d<c?Math.sqrt(d/a):d>=l?Math.sqrt(1-(d-l)/a):1,o[d]=u}for(d=r;d<n;++d)o[d]=0;return s}(e,u,d);v.buffer=w,y.buffer=w,v.loop=!0,y.loop=!0;var R=(e.createGain||e.createGainNode).call(e),k=(e.createGain||e.createGainNode).call(e);R.gain.value=0,k.gain.value=0,v.connect(R.gain),y.connect(k.gain),t.connect(g),t.connect(b),g.connect(R),b.connect(k),R.connect(i),k.connect(i);var x=e.currentTime+.05,U=x+u-d;r.start(x),n.start(U),s.start(x),o.start(U),v.start(x),y.start(U),this.mod1=r,this.mod2=n,this.mod1Gain=a,this.mod2Gain=c,this.mod3Gain=l,this.mod4Gain=p,this.modGain1=f,this.modGain2=m,this.fade1=v,this.fade2=y,this.mix1=R,this.mix2=k,this.delay1=g,this.delay2=b,this.setDelay(.1)}p.prototype.setDelay=function(e){this.modGain1.gain.setTargetAtTime(.5*e,0,.01),this.modGain2.gain.setTargetAtTime(.5*e,0,.01)},p.prototype.setPitchOffset=function(e){e>0?(this.mod1Gain.gain.value=0,this.mod2Gain.gain.value=0,this.mod3Gain.gain.value=1,this.mod4Gain.gain.value=1):(this.mod1Gain.gain.value=1,this.mod2Gain.gain.value=1,this.mod3Gain.gain.value=0,this.mod4Gain.gain.value=0),this.setDelay(.1*Math.abs(e))}},4390:t=>{"use strict";t.exports=e}},i={};function r(e){var n=i[e];if(void 0!==n)return n.exports;var s=i[e]={exports:{}};return t[e](s,s.exports,r),s.exports}return r.d=(e,t)=>{for(var i in t)r.o(t,i)&&!r.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r(9077)})()}));