We have a video capture device. Exercise various capturing modes.
@param {MediaStream} mediaStream
433523
function gotMedia(mediaStream) {
  // Extract video track.
  videoDevice = mediaStream.getVideoTracks()[0];
  log('Using camera', videoDevice.label);

  const captureDevice = new ImageCapture(videoDevice, mediaStream);
  interval = setInterval(function () {
    captureDevice.grabFrame().then(processFrame).catch(error => {
      err((new Date()).toISOString(), 'Error while grabbing frame:', error);
    });

    captureDevice.takePhoto().then(processPhoto).catch(error => {
      err((new Date()).toISOString(), 'Error while taking photo:', error);
    });
  }, 300);
}
1202559
function() {
            this.supported = {};
            // Without support, no formats are supported
            if (!Crafty.support.audio) return;
            var audio = this.audioElement(),
                canplay;
            for (var i in this.codecs) {
                canplay = audio.canPlayType(this.codecs[i]);
                if (canplay !== "" && canplay !== "no") {
                    this.supported[i] = true;
                } else {
                    this.supported[i] = false;
                }
            }
        }
332619
function(){
                /*
                 * media_query
                 *   : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
                 *   | expression [ AND S* expression ]*
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    type        = null,
                    ident       = null,
                    token       = null,
                    expressions = [];
                if (tokenStream.match(Tokens.IDENT)){
                    ident = tokenStream.token().value.toLowerCase();

                    //since there's no custom tokens for these, need to manually check
                    if (ident !== "only" && ident !== "not"){
                        tokenStream.unget();
                        ident = null;
                    } else {
                        token = tokenStream.token();
                    }
                }
               
                this._readWhitespace();

                if (tokenStream.peek() === Tokens.IDENT){
                    type = this._media_type();
                    if (token === null){
                        token = tokenStream.token();
                    }
                } else if (tokenStream.peek() === Tokens.LPAREN){
                    if (token === null){
                        token = tokenStream.LT(1);
                    }
                    expressions.push(this._media_expression());
                }

                if (type === null && expressions.length === 0){
                    return null;
                } else {
                    this._readWhitespace();
                    while (tokenStream.match(Tokens.IDENT)){
                        if (tokenStream.token().value.toLowerCase() !== "and"){
                            this._unexpectedToken(tokenStream.token());
                        }
                        this._readWhitespace();
                        expressions.push(this._media_expression());
                    }
                }
                return new MediaQuery(ident, type, expressions, token.startLine, token.startCol);
            }
595109
function (stream, close) {
                this._stream = stream;
                if (typeof close === "function") {
                    this._close = close;
                }
                stream.on("error", this._onError.bind(this));
            }
1057063
function(file) {

      var defer = new $.Deferred(),
        size = file.size,
        $media = file.type === 'VIDEO' ? $('<video>') : $('<audio>'),
        onMediaLoaded = function() {
          log('File Loaded:' + file.source);

          _bytesLoaded += size;

          onElementLoaded(file, $media[0]);

          _files[_currentSegment].splice(0, 1);

          $media.off();
          $media = null;

          updatePercentage();
          defer.resolve();
        };

      // if it is a mobile or an iPad we avoid the media preloading
      if (!_isMobile && !_isTablet) {

        $media.on('loadstart', function() {
          if (this.networkState === 3) {
            onMediaError(file, this);
            onMediaLoaded();
          }
        });

        $media.on('error stalled', function() {
          onMediaError(file, this);
          onMediaLoaded();
        });

        // on Media Progress
        $media.on('loadedmetadata', function() {
          $media.on('progress', function() {
            var bytesTmpLoaded = 0;
            log('loading in progress file:' + file.source);
            if (this.buffered.length > 0) {
              bytesTmpLoaded = (size / this.duration) * this.buffered.end(0);
              size -= bytesTmpLoaded;
              _bytesLoaded += bytesTmpLoaded;
              updatePercentage();
              // Check if the video has been buffered enough to be considered preloaded
              if (1 / size * bytesTmpLoaded > mediaBufferSizeToPreload && !forceMediaPreload)
                onMediaLoaded();
            }
          });
        });

        $media.attr({
          preload: 'auto',
          src: file.source,
          controls: 'controls'
        });

        // let the browser decide when the media file has been buffered enough
        // to be played
        if (forceMediaPreload)
          $media.on('canplaythrough', onMediaLoaded);

      } else {
        //  that means that media is loaded by default
        onMediaLoaded();
      }


      return defer.promise();
    }
524367
function onAudioInputCapture(evt) {
    try {
        if (evt && evt.data) {
            // Increase the debug counter for received data
            totalReceivedData += evt.data.length;

            // Add the chunk to the buffer
            audioDataBuffer = audioDataBuffer.concat(evt.data);
        }
    }
    catch (ex) {
        alert("onAudioInputCapture ex: " + ex);
    }
}
683029
function _buildVideo(videoDescriptor) {
		this.url = videoDescriptor.url;
		this.appData = videoDescriptor.appData;
		descriptor = videoDescriptor;
	}
986418
function WhammyRecorderHelper(mediaStream, root) {
    this.record = function(timeSlice) {
        if (!this.width) {
            this.width = 320;
        }
        if (!this.height) {
            this.height = 240;
        }

        if (this.video && this.video instanceof HTMLVideoElement) {
            if (!this.width) {
                this.width = video.videoWidth || video.clientWidth || 320;
            }
            if (!this.height) {
                this.height = video.videoHeight || video.clientHeight || 240;
            }
        }

        if (!this.video) {
            this.video = {
                width: this.width,
                height: this.height
            };
        }

        if (!this.canvas || !this.canvas.width || !this.canvas.height) {
            this.canvas = {
                width: this.width,
                height: this.height
            };
        }

        canvas.width = this.canvas.width;
        canvas.height = this.canvas.height;

        // setting defaults
        if (this.video && this.video instanceof HTMLVideoElement) {
            this.isHTMLObject = true;
            video = this.video.cloneNode();
        } else {
            video = document.createElement('video');
            video.src = URL.createObjectURL(mediaStream);

            video.width = this.video.width;
            video.height = this.video.height;
        }

        video.muted = true;
        video.play();

        lastTime = new Date().getTime();
        whammy = new Whammy.Video(root.speed, root.quality);

        console.log('canvas resolutions', canvas.width, '*', canvas.height);
        console.log('video width/height', video.width || canvas.width, '*', video.height || canvas.height);

        drawFrames();
    };

    this.clearOldRecordedFrames = function() {
        whammy.frames = [];
    };

    var requestDataInvoked = false;
    this.requestData = function() {
        if (isPaused) {
            return;
        }

        if (!whammy.frames.length) {
            requestDataInvoked = false;
            return;
        }

        requestDataInvoked = true;
        // clone stuff
        var internalFrames = whammy.frames.slice(0);

        // reset the frames for the new recording

        whammy.frames = dropBlackFrames(internalFrames, -1);

        whammy.compile(function(whammyBlob) {
            root.ondataavailable(whammyBlob);
            console.debug('video recorded blob size:', bytesToSize(whammyBlob.size));
        });

        whammy.frames = [];

        requestDataInvoked = false;
    };

    var isOnStartedDrawingNonBlankFramesInvoked = false;

    function drawFrames() {
        if (isPaused) {
            lastTime = new Date().getTime();
            setTimeout(drawFrames, 500);
            return;
        }

        if (isStopDrawing) {
            return;
        }

        if (requestDataInvoked) {
            return setTimeout(drawFrames, 100);
        }

        var duration = new Date().getTime() - lastTime;
        if (!duration) {
            return drawFrames();
        }

        // via webrtc-experiment#206, by Jack i.e. @Seymourr
        lastTime = new Date().getTime();

        if (!self.isHTMLObject && video.paused) {
            video.play(); // Android
        }

        context.drawImage(video, 0, 0, canvas.width, canvas.height);

        if (!isStopDrawing) {
            whammy.frames.push({
                duration: duration,
                image: canvas.toDataURL('image/webp')
            });
        }

        if (!isOnStartedDrawingNonBlankFramesInvoked && !isBlankFrame(whammy.frames[whammy.frames.length - 1])) {
            isOnStartedDrawingNonBlankFramesInvoked = true;
            root.onStartedDrawingNonBlankFrames();
        }

        setTimeout(drawFrames, 10);
    }

    var isStopDrawing = false;

    this.stop = function() {
        isStopDrawing = true;
        this.requestData();
        this.onstop();
    };

    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    var video;
    var lastTime;
    var whammy;

    var self = this;

    function isBlankFrame(frame, _pixTolerance, _frameTolerance) {
        var localCanvas = document.createElement('canvas');
        localCanvas.width = canvas.width;
        localCanvas.height = canvas.height;
        var context2d = localCanvas.getContext('2d');

        var sampleColor = {
            r: 0,
            g: 0,
            b: 0
        };
        var maxColorDifference = Math.sqrt(
            Math.pow(255, 2) +
            Math.pow(255, 2) +
            Math.pow(255, 2)
        );
        var pixTolerance = _pixTolerance && _pixTolerance >= 0 && _pixTolerance <= 1 ? _pixTolerance : 0;
        var frameTolerance = _frameTolerance && _frameTolerance >= 0 && _frameTolerance <= 1 ? _frameTolerance : 0;

        var matchPixCount, endPixCheck, maxPixCount;

        var image = new Image();
        image.src = frame.image;
        context2d.drawImage(image, 0, 0, canvas.width, canvas.height);
        var imageData = context2d.getImageData(0, 0, canvas.width, canvas.height);
        matchPixCount = 0;
        endPixCheck = imageData.data.length;
        maxPixCount = imageData.data.length / 4;

        for (var pix = 0; pix < endPixCheck; pix += 4) {
            var currentColor = {
                r: imageData.data[pix],
                g: imageData.data[pix + 1],
                b: imageData.data[pix + 2]
            };
            var colorDifference = Math.sqrt(
                Math.pow(currentColor.r - sampleColor.r, 2) +
                Math.pow(currentColor.g - sampleColor.g, 2) +
                Math.pow(currentColor.b - sampleColor.b, 2)
            );
            // difference in color it is difference in color vectors (r1,g1,b1) <=> (r2,g2,b2)
            if (colorDifference <= maxColorDifference * pixTolerance) {
                matchPixCount++;
            }
        }

        if (maxPixCount - matchPixCount <= maxPixCount * frameTolerance) {
            return false;
        } else {
            return true;
        }
    }

    function dropBlackFrames(_frames, _framesToCheck, _pixTolerance, _frameTolerance) {
        var localCanvas = document.createElement('canvas');
        localCanvas.width = canvas.width;
        localCanvas.height = canvas.height;
        var context2d = localCanvas.getContext('2d');
        var resultFrames = [];

        var checkUntilNotBlack = _framesToCheck === -1;
        var endCheckFrame = (_framesToCheck && _framesToCheck > 0 && _framesToCheck <= _frames.length) ?
            _framesToCheck : _frames.length;
        var sampleColor = {
            r: 0,
            g: 0,
            b: 0
        };
        var maxColorDifference = Math.sqrt(
            Math.pow(255, 2) +
            Math.pow(255, 2) +
            Math.pow(255, 2)
        );
        var pixTolerance = _pixTolerance && _pixTolerance >= 0 && _pixTolerance <= 1 ? _pixTolerance : 0;
        var frameTolerance = _frameTolerance && _frameTolerance >= 0 && _frameTolerance <= 1 ? _frameTolerance : 0;
        var doNotCheckNext = false;

        for (var f = 0; f < endCheckFrame; f++) {
            var matchPixCount, endPixCheck, maxPixCount;

            if (!doNotCheckNext) {
                var image = new Image();
                image.src = _frames[f].image;
                context2d.drawImage(image, 0, 0, canvas.width, canvas.height);
                var imageData = context2d.getImageData(0, 0, canvas.width, canvas.height);
                matchPixCount = 0;
                endPixCheck = imageData.data.length;
                maxPixCount = imageData.data.length / 4;

                for (var pix = 0; pix < endPixCheck; pix += 4) {
                    var currentColor = {
                        r: imageData.data[pix],
                        g: imageData.data[pix + 1],
                        b: imageData.data[pix + 2]
                    };
                    var colorDifference = Math.sqrt(
                        Math.pow(currentColor.r - sampleColor.r, 2) +
                        Math.pow(currentColor.g - sampleColor.g, 2) +
                        Math.pow(currentColor.b - sampleColor.b, 2)
                    );
                    // difference in color it is difference in color vectors (r1,g1,b1) <=> (r2,g2,b2)
                    if (colorDifference <= maxColorDifference * pixTolerance) {
                        matchPixCount++;
                    }
                }
            }

            if (!doNotCheckNext && maxPixCount - matchPixCount <= maxPixCount * frameTolerance) {
                // console.log('removed black frame : ' + f + ' ; frame duration ' + _frames[f].duration);
            } else {
                // console.log('frame is passed : ' + f);
                if (checkUntilNotBlack) {
                    doNotCheckNext = true;
                }
                resultFrames.push(_frames[f]);
            }
        }

        resultFrames = resultFrames.concat(_frames.slice(endCheckFrame));

        if (resultFrames.length <= 0) {
            // at least one last frame should be available for next manipulation
            // if total duration of all frames will be < 1000 than ffmpeg doesn't work well...
            resultFrames.push(_frames[_frames.length - 1]);
        }

        return resultFrames;
    }

    var isPaused = false;

    this.pause = function() {
        isPaused = true;
    };

    this.resume = function() {
        isPaused = false;
    };

    this.onstop = function() {};
}
906147
function(track, stream) {
    stream.removeTrack(track);
    stream.dispatchEvent(new window.MediaStreamTrackEvent('removetrack',
      {track: track}));
  }
739374
async function setupCamera() {
  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
    throw new Error(
        'Browser API navigator.mediaDevices.getUserMedia not available');
  }

  const video = document.getElementById('video');
  video.width = videoWidth;
  video.height = videoHeight;

  const mobile = isMobile();
  const stream = await navigator.mediaDevices.getUserMedia({
    'audio': false,
    'video': {
      facingMode: 'user',
      width: mobile ? undefined : videoWidth,
      height: mobile ? undefined : videoHeight,
    },
  });
  video.srcObject = stream;

  return new Promise((resolve) => {
    video.onloadedmetadata = () => {
      resolve(video);
    };
  });
}
808483
function MultiStreamRecorder(arrayOfMediaStreams, options) {
    arrayOfMediaStreams = arrayOfMediaStreams || [];

    if (arrayOfMediaStreams instanceof MediaStream) {
        arrayOfMediaStreams = [arrayOfMediaStreams];
    }

    var self = this;

    var mixer;
    var mediaRecorder;

    options = options || {
        mimeType: 'video/webm',
        video: {
            width: 360,
            height: 240
        }
    };

    if (!options.frameInterval) {
        options.frameInterval = 10;
    }

    if (!options.video) {
        options.video = {};
    }

    if (!options.video.width) {
        options.video.width = 360;
    }

    if (!options.video.height) {
        options.video.height = 240;
    }

    this.start = function(timeSlice) {
        // github/muaz-khan/MultiStreamsMixer
        mixer = new MultiStreamsMixer(arrayOfMediaStreams);

        if (getVideoTracks().length) {
            mixer.frameInterval = options.frameInterval || 10;
            mixer.width = options.video.width || 360;
            mixer.height = options.video.height || 240;
            mixer.startDrawingFrames();
        }

        if (typeof self.previewStream === 'function') {
            self.previewStream(mixer.getMixedStream());
        }

        // record using MediaRecorder API
        mediaRecorder = new MediaStreamRecorder(mixer.getMixedStream());

        for (var prop in self) {
            if (typeof self[prop] !== 'function') {
                mediaRecorder[prop] = self[prop];
            }
        }

        mediaRecorder.ondataavailable = function(blob) {
            self.ondataavailable(blob);
        };

        mediaRecorder.onstop = self.onstop;

        mediaRecorder.start(timeSlice);
    };

    function getVideoTracks() {
        var tracks = [];
        arrayOfMediaStreams.forEach(function(stream) {
            stream.getVideoTracks().forEach(function(track) {
                tracks.push(track);
            });
        });
        return tracks;
    }

    this.stop = function(callback) {
        if (!mediaRecorder) {
            return;
        }

        mediaRecorder.stop(function(blob) {
            callback(blob);
        });
    };

    this.pause = function() {
        if (mediaRecorder) {
            mediaRecorder.pause();
        }
    };

    this.resume = function() {
        if (mediaRecorder) {
            mediaRecorder.resume();
        }
    };

    this.clearRecordedData = function() {
        if (mediaRecorder) {
            mediaRecorder.clearRecordedData();
            mediaRecorder = null;
        }

        if (mixer) {
            mixer.releaseStreams();
            mixer = null;
        }
    };

    this.addStreams = this.addStream = function(streams) {
        if (!streams) {
            throw 'First parameter is required.';
        }

        if (!(streams instanceof Array)) {
            streams = [streams];
        }

        arrayOfMediaStreams.concat(streams);

        if (!mediaRecorder || !mixer) {
            return;
        }

        mixer.appendStreams(streams);
    };

    this.resetVideoStreams = function(streams) {
        if (!mixer) {
            return;
        }

        if (streams && !(streams instanceof Array)) {
            streams = [streams];
        }

        mixer.resetVideoStreams(streams);
    };

    this.ondataavailable = function(blob) {
        if (self.disableLogs) {
            return;
        }

        console.log('ondataavailable', blob);
    };

    this.onstop = function() {};

    // for debugging
    this.name = 'MultiStreamRecorder';
    this.toString = function() {
        return this.name;
    };
}
169565
function (frames) {

        this.setFrames(frames);

        if (player.recording != this){
          console.log('recordings changed during load');
          return
        }

        // it would be better to use streamingCount here, but that won't be in until 0.5.0+
        // For now, it just flashes for a moment until the first frame comes through with a hand on it.
        // if (autoPlay && (controller.streamingCount == 0 || pauseOnHand)) {
        if (player.autoPlay) {
          player.play();
          if (player.pauseOnHand) {
            player.setGraphic('connect');
          }
        }

        player.controller.emit('playback.recordingSet', this);
      }
451109
function (videoId, canvaId, outputOptions) {
    let editorVideo;
    const domElement = document.getElementById(videoId);

    if (domElement !== null) {
        editorVideo = new Video(domElement);
    }
    const store = new Store();

    function getCanva() {
        return document.getElementById(canvaId);
    }

    outputOptions = outputOptions || {};

    function setAltCanvas() {
        let domElements = [];
        let altCanvas = outputOptions.altCanvas;
        if (altCanvas.length > 0) {
            for (let i = 0; i < altCanvas.length; i++) {
                domElements.push({
                    el: new Canva(altCanvas[i]),
                    width: altCanvas[i].getAttribute('data-width'),
                    name: altCanvas[i].getAttribute('data-name')
                });
            }
        }
        return domElements;
    }

    return {
        isSupported: function () {
            const elem = document.createElement('canvas');

            return !!document.getElementById(videoId) && document.getElementById(canvaId)
                && !!elem.getContext && !!elem.getContext('2d');
        },
        screenshot: function () {
            const screenshot = new ScreenShot(
                store.getLength() + 1,
                new Canva(getCanva()),
                editorVideo,
                setAltCanvas()
            );

            store.set(screenshot.getId(), screenshot);

            return screenshot;
        },
        store: store,
        copy: function (mainSource, altSources) {

            const elementDomNode = document.createElement('img');
            elementDomNode.src = mainSource;

            const element = new Image(elementDomNode);
            const editorCanva = new Canva(getCanva());
            const altEditorCanva = setAltCanvas();
            editorCanva
                .reset()
                .resize(editorVideo)
                .copy(element);


            // handle alternative canvas:
            if (altEditorCanva.length > 0) {
                for (let i = 0; i < altEditorCanva.length; i++) {

                    let tmpEl = document.createElement('img');
                    tmpEl.src = altSources[i].dataURI;

                    const canvaEl = altEditorCanva[i].el;

                    canvaEl
                        .reset()
                        .resize(editorVideo, altEditorCanva[i].width)
                        .copy(new Image(tmpEl)); // @TODO: should copy the right stored image
                }
            }
        },
        getCanvaImage: function () {
            const canva = new Canva(getCanva());

            return canva.extractImage();
        },
        resetCanva: function () {
            const editorCanva = new Canva(getCanva());
            editorCanva.reset();
        },
        getNbScreenshot: function () {
            return store.getLength();
        }
    };
}
790636
function (evts, callback) {
    this.replayStreamed(function (replay, done) {
      evts.forEach(function (evt) {
        replay(evt);
      });
      done(callback);
    });
  }
631948
function appendStream(streams, s) {
    assert.arrayOfObject(streams, 'streams');
    assert.object(s, 'stream');

    if (s instanceof Stream) {
        streams.push({
            raw: false,
            stream: s
        });
    } else {
        assert.optionalBool(s.raw, 'stream.raw');
        assert.object(s.stream, 'stream.stream');
        streams.push(s);
    }
}
516805
function BufferedStream(opts) {
  opts = opts || {}

  Stream.call(this)

  // up to subclasses to decide what kind of stream we are
  this.writable = false
  this.readable = false

  this.buffers = []
  this.paused = false
  this.concat = !!opts.concat //boolean indicating if we should emit separate buffers or concat buffers into one 'emit' event
}
563136
function initCapture(el) {
  // read the capture instructions
  var configText = el.getAttribute('rtc-capture') || '';
  var res = el.getAttribute('rtc-resolution') || el.getAttribute('rtc-res');
  var fps = el.getAttribute('rtc-fps');

  if (res) {
    configText += ' min:' + res + ' max:' + res;
  }

  if (fps) {
    configText += ' minfps:' + fps + ' maxfps:' + fps;
  }

  // patch in a capture method to the element
  el.capture = enableCapture(el, captureConfig(configText));

  // trigger capture
  el.capture(function(stream) {
    // broadcast the stream through the session manager
    if (sessionMgr) {
      sessionMgr.broadcast(stream, { name: el.id });
    }
  });
}