{"version":3,"file":"msr_plain.min.js","sources":["../src/msr_plain.js"],"sourcesContent":["/* jshint ignore:start */\ndefine(['jquery',\n        'core/log', 'filter_poodll/utils_amd'],\n    function ($, log, utils) {\n\n        \"use strict\"; // jshint ;_;\n\n        log.debug('PoodLL Plain Recorder: initialising');\n\n        return {\n            timeout: 0,\n            mediaRecorder: null,\n            mediaStream: null,\n            audioctx: null, //unused\n            msr: null,\n            mediaType: null,\n            //Firefox fails to calc properly at 128000, and blobs concatenate at about 1/4 the correct length\n            //its a hack to get us over the broken firefox but 12800 works.\n            audioBitsPerSecond: 12800,\n            videoBitsPerSecond: 2500000,\n\n\n            //for making multiple instances\n            clone: function () {\n                return $.extend(true, {}, this);\n            },\n\n            // init the recorder\n            init: function (msr, mediaStream, audioctx, mediaType) {\n                this.msr = msr;\n                this.mediaStream = mediaStream;\n                this.audioctx = audioctx; //unused\n                this.mediaType = mediaType;\n            },\n\n            /**\n             * This method records MediaStream.\n             * @method\n             * @memberof MediaStreamRecorder\n             * @example\n             * recorder.record();\n             */\n            start: function (timeSlice, __disableLogs) {\n                var that = this;\n\n\n                if (this.mediaType === 'audio') {\n                    //this section can probably be removed. I can not see a need for it.\n                    if (this.mediaStream.getVideoTracks().length && this.mediaStream.getAudioTracks().length) {\n                        log.debug('Somehow we got a video stream, paring it down to just audio. ');\n                        var stream;\n                        if (!!navigator.mozGetUserMedia) {\n                            stream = new MediaStream();\n                            stream.addTrack(this.mediaStream.getAudioTracks()[0]);\n                        } else {\n                            // webkitMediaStream\n                            stream = new MediaStream(this.mediaStream.getAudioTracks());\n                        }\n                        this.mediaStream = stream;\n                    }\n                }\n\n                //lets work out our mime type\n                this.mimeType=false;\n                //if audio\n                if(this.mediaType==='audio') {\n                    //if its a mediarecorder and does not support 'isTypeSupported' ..it can only be Safari ..\n                    if (!MediaRecorder.isTypeSupported) {\n                        this.mimeType = \"audio/mp4\";\n                    }else {\n                        var audiotypes = ['ogg', 'webm', 'quicktime', 'mp4', 'm4a', 'wav'];\n                        for (var i = 0; i < audiotypes.length; i++) {\n                            var themimetype = 'audio/' + audiotypes[i];\n                            if (MediaRecorder.isTypeSupported(themimetype)) {\n                                this.mimeType = themimetype;\n                                break;\n                            }\n                        }\n                        //we make an intelligent choice if required to do so\n                        if (this.mimeType === false) {\n                            this.mimeType = utils.is_chrome() ? 'audio/webm' : 'audio/ogg';\n                        }\n                    }\n                    var rec_options = {\n                        //videoBitsPerSecond : this.videoBitsPerSecond,\n                        audioBitsPerSecond: this.audioBitsPerSecond, //Firefox needs this\n                        mimeType: this.mimeType\n                    };\n\n                //else video\n                }else{\n                    //if its a mediarecorder and does not support 'isTypeSupported' ..it can only be Safari ..\n                    if (!MediaRecorder.isTypeSupported) {\n                        this.mimeType = \"video/mp4\";\n                    }else {\n                        var videotypes = ['webm', 'ogv', 'quicktime', 'mp4', 'mpeg'];\n                        for (var i = 0; i < videotypes.length; i++) {\n                            var themimetype = 'video/' + videotypes[i];\n                            if (MediaRecorder.isTypeSupported(themimetype)) {\n                                this.mimeType = themimetype;\n                                break;\n                            }\n                        }\n                        //we make an \"intelligent\" choice if required to do so\n                        if (this.mimeType === false) {\n                            this.mimeType = 'video/webm';\n                        }\n                    }\n\n                    var rec_options = {\n                        //videoBitsPerSecond : this.videoBitsPerSecond,\n                        //audioBitsPerSecond: this.audioBitsPerSecond,\n                        mimeType: this.mimeType\n                    };\n                }\n\n\n                try {\n                    this.mediaRecorder = new MediaRecorder(this.mediaStream, rec_options);\n                } catch (e) {\n                    // if a NON_supported rec_option got us here\n                    // or if Firefox on Android\n                    this.mediaRecorder = new MediaRecorder(this.mediaStream);\n                    log.debug('MediaRecorder API seems unable to record mimeType:' + this.mimeType);\n                }\n                log.debug(\"msr_plain using mime type:\" + this.mimeType);\n\n                // i.e. stop recording when <video> is paused by the user; and auto restart recording\n                // when video is resumed. E.g. yourStream.getVideoTracks()[0].muted = true; // it will auto-stop recording.\n                this.mediaRecorder.ignoreMutedMedia = this.ignoreMutedMedia || false;\n\n\n                // Dispatching OnDataAvailable Handler\n                this.mediaRecorder.ondataavailable = function (e) {\n                    //  log.debug('data available:' + e.data.size );\n                    if (!e.data || !e.data.size) {\n                        return;\n                    }\n\n                    //var blob = new Blob([e.data], {type: that.mimeType});\n                    var blob = e.data; //in firefox this leaves hints about the codec\n                    that.msr.ondataavailable(blob);\n                 //   log.debug('e.data.size:' + e.data);\n                 //   log.debug('abr:' + that.mediaRecorder.audioBitsPerSecond);\n                 //   log.debug('vbr:' + that.mediaRecorder.videoBitsPerSecond);\n\n                };\n\n                this.mediaRecorder.onerror = function (error) {\n                    if (error.name === 'InvalidState') {\n                        log.debug('The MediaRecorder is not in a state in which the proposed operation is allowed to be executed.');\n                    } else if (error.name === 'OutOfMemory') {\n                        log.debug('The UA has exhaused the available memory. User agents SHOULD provide as much additional information as possible in the message attribute.');\n                    } else if (error.name === 'IllegalStreamModification') {\n                        log.debug('A modification to the stream has occurred that makes it impossible to continue recording. An example would be the addition of a Track while recording is occurring. User agents SHOULD provide as much additional information as possible in the message attribute.');\n                    } else if (error.name === 'OtherRecordingError') {\n                        log.debug('Used for an fatal error other than those listed above. User agents SHOULD provide as much additional information as possible in the message attribute.');\n                    } else if (error.name === 'GenericError') {\n                        log.debug('The UA cannot provide the codec or recording option that has been requested.', error);\n                    } else {\n                        log.debug('MediaRecorder Error', error);\n                    }\n\n                    // When the stream is \"ended\" set recording to 'inactive'\n                    // and stop gathering data. Callers should not rely on\n                    // exactness of the timeSlice value, especially\n                    // if the timeSlice value is small. Callers should\n                    // consider timeSlice as a minimum value\n\n                    if (!!that.mediaRecorder && that.mediaRecorder.state !== 'inactive' && that.mediaRecorder.state !== 'stopped') {\n                        that.mediaRecorder.stop();\n                    }\n                };\n\n                //We need a source node to connect the analyser to. The analyser is for visualisations\n                var audioInput = this.audioctx.createMediaStreamSource(this.mediaStream);\n                audioInput.connect(this.msr.audioanalyser.core);\n\n                // void start(optional long mTimeSlice)\n                // The interval of passing encoded data from EncodedBufferCache to onDataAvailable\n                // handler. \"mTimeSlice < 0\" means Session object does not push encoded data to\n                // onDataAvailable, instead, it passive wait the client side pull encoded data\n                // by calling requestData API.\n                try {\n                    that.mediaRecorder.start(timeSlice);\n                } catch (e) {\n                    that.mediaRecorder = null;\n                }\n\n//end of start\n            },\n\n            /**\n             * This method stops recording MediaStream.\n             * @param {function} callback - Callback function, that is used to pass recorded blob back to the callee.\n             * @method\n             * @memberof MediaStreamRecorder\n             * @example\n             * recorder.stop(function(blob) {\n     *     video.src = URL.createObjectURL(blob);\n     * });\n             */\n            stop: function (callback) {\n                if (!this.mediaRecorder) {\n                    return;\n                }\n\n                if (this.mediaRecorder.state === 'recording') {\n                    this.mediaRecorder.stop();\n                }\n            },\n\n            /**\n             * This method pauses the recording process.\n             * @method\n             * @memberof MediaStreamRecorder\n             * @example\n             * recorder.pause();\n             */\n            pause: function () {\n                if (!this.mediaRecorder) {\n                    return;\n                }\n\n                if (this.mediaRecorder.state === 'recording') {\n                    this.mediaRecorder.pause();\n                }\n            },\n\n            /**\n             * This method resumes the recording process.\n             * @method\n             * @memberof MediaStreamRecorder\n             * @example\n             * recorder.resume();\n             */\n            resume: function () {\n                if (!this.mediaRecorder) {\n                    return;\n                }\n                if (this.mediaRecorder.state === 'paused') {\n                    this.mediaRecorder.resume();\n                }\n            },\n\n            /**\n             * This method resets currently recorded data.\n             * @method\n             * @memberof MediaStreamRecorder\n             * @example\n             * recorder.clearRecordedData();\n             */\n            clearRecordedData: function () {\n                if (!this.mediaRecorder) {\n                    return;\n                }\n\n                this.pause();\n\n                this.stop();\n            },\n\n            // Reference to \"MediaRecorder\" object\n            //  var mediaRecorder;\n\n            isMediaStreamActive: function () {\n                if ('active' in this.mediaStream) {\n                    if (!this.mediaStream.active) {\n                        return false;\n                    }\n                } else if ('ended' in this.mediaStream) { // old hack\n                    if (this.mediaStream.ended) {\n                        return false;\n                    }\n                }\n                return true;\n            },\n\n            // this method checks if media stream is stopped\n            // or any track is ended.\n            looper: function () {\n                if (!this.mediaRecorder) {\n                    return;\n                }\n\n                if (this.isMediaStreamActive() === false) {\n                    this.stop();\n                    return;\n                }\n\n                setTimeout(this.looper, 1000); // check every second\n            }\n        };// end of returned object\n    });// total end"],"names":["define","$","log","utils","debug","timeout","mediaRecorder","mediaStream","audioctx","msr","mediaType","audioBitsPerSecond","videoBitsPerSecond","clone","extend","this","init","start","timeSlice","__disableLogs","stream","that","getVideoTracks","length","getAudioTracks","navigator","mozGetUserMedia","MediaStream","addTrack","mimeType","MediaRecorder","isTypeSupported","audiotypes","i","themimetype","is_chrome","rec_options","videotypes","e","ignoreMutedMedia","ondataavailable","data","size","blob","onerror","error","name","state","stop","createMediaStreamSource","connect","audioanalyser","core","callback","pause","resume","clearRecordedData","isMediaStreamActive","active","ended","looper","setTimeout"],"mappings":"AACAA,iCAAO,CAAC,SACA,WAAY,4BAChB,SAAUC,EAAGC,IAAKC,cAIdD,IAAIE,MAAM,uCAEH,CACHC,QAAS,EACTC,cAAe,KACfC,YAAa,KACbC,SAAU,KACVC,IAAK,KACLC,UAAW,KAGXC,mBAAoB,MACpBC,mBAAoB,KAIpBC,MAAO,kBACIZ,EAAEa,QAAO,EAAM,GAAIC,OAI9BC,KAAM,SAAUP,IAAKF,YAAaC,SAAUE,gBACnCD,IAAMA,SACNF,YAAcA,iBACdC,SAAWA,cACXE,UAAYA,WAUrBO,MAAO,SAAUC,UAAWC,mBAQZC,OAPRC,KAAON,KAGY,UAAnBA,KAAKL,YAEDK,KAAKR,YAAYe,iBAAiBC,QAAUR,KAAKR,YAAYiB,iBAAiBD,SAC9ErB,IAAIE,MAAM,iEAEJqB,UAAUC,iBACZN,OAAS,IAAIO,aACNC,SAASb,KAAKR,YAAYiB,iBAAiB,IAGlDJ,OAAS,IAAIO,YAAYZ,KAAKR,YAAYiB,uBAEzCjB,YAAca,iBAKtBS,UAAS,EAEM,UAAjBd,KAAKL,UAAqB,IAEpBoB,cAAcC,gBAEb,SACEC,WAAa,CAAC,MAAO,OAAQ,YAAa,MAAO,MAAO,OACnDC,EAAI,EAAGA,EAAID,WAAWT,OAAQU,IAAK,KACpCC,YAAc,SAAWF,WAAWC,MACpCH,cAAcC,gBAAgBG,aAAc,MACvCL,SAAWK,oBAKF,IAAlBnB,KAAKc,gBACAA,SAAW1B,MAAMgC,YAAc,aAAe,uBAZlDN,SAAW,gBAehBO,YAAc,CAEdzB,mBAAoBI,KAAKJ,mBACzBkB,SAAUd,KAAKc,cAIlB,IAEIC,cAAcC,gBAEb,KACEM,WAAa,CAAC,OAAQ,MAAO,YAAa,MAAO,YAC5CJ,EAAI,EAAGA,EAAII,WAAWd,OAAQU,IAAK,CACpCC,YAAc,SAAWG,WAAWJ,MACpCH,cAAcC,gBAAgBG,aAAc,MACvCL,SAAWK,oBAKF,IAAlBnB,KAAKc,gBACAA,SAAW,wBAZfA,SAAW,YAgBhBO,YAAc,CAGdP,SAAUd,KAAKc,mBAMdvB,cAAgB,IAAIwB,cAAcf,KAAKR,YAAa6B,aAC3D,MAAOE,QAGAhC,cAAgB,IAAIwB,cAAcf,KAAKR,aAC5CL,IAAIE,MAAM,qDAAuDW,KAAKc,UAE1E3B,IAAIE,MAAM,6BAA+BW,KAAKc,eAIzCvB,cAAciC,iBAAmBxB,KAAKwB,mBAAoB,OAI1DjC,cAAckC,gBAAkB,SAAUF,MAEtCA,EAAEG,MAASH,EAAEG,KAAKC,UAKnBC,KAAOL,EAAEG,KACbpB,KAAKZ,IAAI+B,gBAAgBG,aAOxBrC,cAAcsC,QAAU,SAAUC,OAChB,iBAAfA,MAAMC,KACN5C,IAAIE,MAAM,kGACY,gBAAfyC,MAAMC,KACb5C,IAAIE,MAAM,6IACY,8BAAfyC,MAAMC,KACb5C,IAAIE,MAAM,uQACY,wBAAfyC,MAAMC,KACb5C,IAAIE,MAAM,0JACY,iBAAfyC,MAAMC,KACb5C,IAAIE,MAAM,+EAAgFyC,OAE1F3C,IAAIE,MAAM,sBAAuByC,OAS/BxB,KAAKf,eAA8C,aAA7Be,KAAKf,cAAcyC,OAAqD,YAA7B1B,KAAKf,cAAcyC,OACtF1B,KAAKf,cAAc0C,QAKVjC,KAAKP,SAASyC,wBAAwBlC,KAAKR,aACjD2C,QAAQnC,KAAKN,IAAI0C,cAAcC,UAQtC/B,KAAKf,cAAcW,MAAMC,WAC3B,MAAOoB,GACLjB,KAAKf,cAAgB,OAgB7B0C,KAAM,SAAUK,UACPtC,KAAKT,eAIuB,cAA7BS,KAAKT,cAAcyC,YACdzC,cAAc0C,QAW3BM,MAAO,WACEvC,KAAKT,eAIuB,cAA7BS,KAAKT,cAAcyC,YACdzC,cAAcgD,SAW3BC,OAAQ,WACCxC,KAAKT,eAGuB,WAA7BS,KAAKT,cAAcyC,YACdzC,cAAciD,UAW3BC,kBAAmB,WACVzC,KAAKT,qBAILgD,aAEAN,SAMTS,oBAAqB,cACb,WAAY1C,KAAKR,iBACZQ,KAAKR,YAAYmD,cACX,OAER,GAAI,UAAW3C,KAAKR,aACnBQ,KAAKR,YAAYoD,aACV,SAGR,GAKXC,OAAQ,WACC7C,KAAKT,iBAIyB,IAA/BS,KAAK0C,sBAKTI,WAAW9C,KAAK6C,OAAQ,UAJfZ"}