Bladeren bron

Switched Webcam to uppy-thin usage

Harry Hedger 8 jaren geleden
bovenliggende
commit
b4b66adf6c
1 gewijzigde bestanden met toevoegingen van 22 en 336 verwijderingen
  1. 22 336
      src/plugins/Webcam/index.js

+ 22 - 336
src/plugins/Webcam/index.js

@@ -1,10 +1,9 @@
 import Plugin from '../Plugin'
-import {extend, dataURItoFile} from '../../core/Utils'
+import { Webcam as WebcamProvider } from 'uppy-thin'
+import { extend } from '../../core/Utils'
+import WebcamIcon from './WebcamIcon'
 import CameraScreen from './CameraScreen'
 import PermissionsScreen from './PermissionsScreen'
-import WebcamIcon from './WebcamIcon'
-import html from '../../core/html'
-var _userMedia
 
 /**
  * Webcam
@@ -14,7 +13,6 @@ export default class Webcam extends Plugin {
     super(core, opts)
     this.userMedia = true
     this.protocol = location.protocol.match(/https/i) ? 'https' : 'http'
-    this.init()
     this.type = 'acquirer'
     this.id = 'Webcam'
     this.title = 'Webcam'
@@ -54,339 +52,24 @@ export default class Webcam extends Plugin {
 
     // Camera controls
     this.start = this.start.bind(this)
-    this.init = this.init.bind(this)
-    this.stopWebcam = this.stopWebcam.bind(this)
-    this.startRecording = this.startRecording.bind(this)
-    this.stopRecording = this.stopRecording.bind(this)
     this.takeSnapshot = this.takeSnapshot.bind(this)
-    this.generateImage = this.generateImage.bind(this)
-    this.getSWFHTML = this.getSWFHTML.bind(this)
-    this.detectFlash = this.detectFlash.bind(this)
-  }
-
-  /**
-   * Checks for getUserMedia support
-   */
-  init () {
-    // initialize, check for getUserMedia support
-
-    // Setup getUserMedia, with polyfill for older browsers
-    // Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
-    this.mediaDevices = (navigator.mediaDevices && navigator.mediaDevices.getUserMedia)
-      ? navigator.mediaDevices : ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? {
-        getUserMedia: function (c) {
-          return new Promise(function (resolve, reject) {
-            (navigator.mozGetUserMedia ||
-            navigator.webkitGetUserMedia).call(navigator, c, resolve, reject)
-          })
-        }
-      } : null)
 
-    window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL
-    this.userMedia = this.userMedia && !!this.mediaDevices && !!window.URL
-
-    // Older versions of firefox (< 21) apparently claim support but user media does not actually work
-    if (navigator.userAgent.match(/Firefox\D+(\d+)/)) {
-      if (parseInt(RegExp.$1, 10) < 21) this.userMedia = null
-    }
-
-    // Make sure media stream is closed when navigating away from page
-    if (this.userMedia) {
-      window.addEventListener('beforeunload', (event) => {
-        this.reset()
-      })
-    }
+    this.webcam = new WebcamProvider(this.opts, this.params)
   }
 
   start () {
-    this.userMedia = _userMedia === undefined ? this.userMedia : _userMedia
-
-    if (this.userMedia) {
-      // ask user for access to their camera
-      this.mediaDevices.getUserMedia({
-        audio: false,
-        video: true
-      })
-      .then((stream) => {
-        this.updateState({
-          videoStream: stream,
-          cameraReady: true
-        })
-      })
-      .catch((err) => {
-        if (this.opts.enableFlash && this.detectFlash()) {
-          // setTimeout(() => {
-          //   this.opts.forceFlash = 1
-          //   this.attach(elem)
-          // }, 1)
-        } else {
-          console.log('Error:', err)
-        }
-      })
-    } else if (this.opts.enableFlash && this.detectFlash()) {
-      // flash fallback
-      // needed for flash-to-js interface
-      window.Webcam = Webcam
+    this.webcam.start()
+    .then((stream) => {
       this.updateState({
-        useTheFlash: true
+        videoStream: stream,
+        cameraReady: true
       })
-      // elem.appendChild(div)
-    } else {
-      console.log('There was a problem!')
-    }
-  }
-
-  /**
-   * Detects if browser supports flash
-   * Code snippet borrowed from: https://github.com/swfobject/swfobject
-   *
-   * @return {bool} flash supported
-   */
-  detectFlash () {
-    var SHOCKWAVE_FLASH = 'Shockwave Flash'
-    var SHOCKWAVE_FLASH_AX = 'ShockwaveFlash.ShockwaveFlash'
-    var FLASH_MIME_TYPE = 'application/x-shockwave-flash'
-    var win = window
-    var nav = navigator
-    var hasFlash = false
-
-    if (typeof nav.plugins !== 'undefined' && typeof nav.plugins[SHOCKWAVE_FLASH] === 'object') {
-      var desc = nav.plugins[SHOCKWAVE_FLASH].description
-      if (desc && (typeof nav.mimeTypes !== 'undefined' && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
-        hasFlash = true
-      }
-    } else if (typeof win.ActiveXObject !== 'undefined') {
-      try {
-        var ax = new win.ActiveXObject(SHOCKWAVE_FLASH_AX)
-        if (ax) {
-          var ver = ax.GetVariable('$version')
-          if (ver) hasFlash = true
-        }
-      } catch (e) {}
-    }
-
-    return hasFlash
-  }
-
-  reset () {
-    // shutdown camera, reset to potentially attach again
-    if (this.preview_active) this.unfreeze()
-
-    if (this.userMedia) {
-      if (this.stream) {
-        if (this.stream.getVideoTracks) {
-          // get video track to call stop on it
-          var tracks = this.stream.getVideoTracks()
-          if (tracks && tracks[0] && tracks[0].stop) tracks[0].stop()
-        } else if (this.stream.stop) {
-          // deprecated, may be removed in future
-          this.stream.stop()
-        }
-      }
-      delete this.stream
-      delete this.video
-    }
-
-    if (this.userMedia !== true) {
-      // call for turn off camera in flash
-      this.getMovie()._releaseCamera()
-    }
-  }
-
-  getSWFHTML () {
-    // Return HTML for embedding flash based webcam capture movie
-    var swfURL = this.params.swfURL
-
-    // make sure we aren't running locally (flash doesn't work)
-    if (location.protocol.match(/file/)) {
-      return '<h3 style="color:red">ERROR: the Webcam.js Flash fallback does not work from local disk.  Please run it from a web server.</h3>'
-    }
-
-    // make sure we have flash
-    if (!this.detectFlash()) {
-      return '<h3 style="color:red">No flash</h3>'
-    }
-
-    // set default swfURL if not explicitly set
-    if (!swfURL) {
-      // find our script tag, and use that base URL
-      var base_url = ''
-      var scpts = document.getElementsByTagName('script')
-      for (var idx = 0, len = scpts.length; idx < len; idx++) {
-        var src = scpts[idx].getAttribute('src')
-        if (src && src.match(/\/webcam(\.min)?\.js/)) {
-          base_url = src.replace(/\/webcam(\.min)?\.js.*$/, '')
-          idx = len
-        }
-      }
-      if (base_url) swfURL = base_url + '/webcam.swf'
-      else swfURL = 'webcam.swf'
-    }
-
-    // // if this is the user's first visit, set flashvar so flash privacy settings panel is shown first
-    // if (window.localStorage && !localStorage.getItem('visited')) {
-    //   // this.params.new_user = 1
-    //   localStorage.setItem('visited', 1)
-    // }
-    // this.params.new_user = 1
-    // construct flashvars string
-    var flashvars = ''
-    for (var key in this.params) {
-      if (flashvars) flashvars += '&'
-      flashvars += key + '=' + escape(this.params[key])
-    }
-
-    // construct object/embed tag
-
-    return html`<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" type="application/x-shockwave-flash" codebase="${this.protocol}://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="${this.params.width}" height="${this.params.height}" id="webcam_movie_obj" align="middle"><param name="wmode" value="opaque" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="${swfURL}" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="${flashvars}"/><embed id="webcam_movie_embed" src="${swfURL}" wmode="opaque" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="${this.params.width}" height="${this.params.height}" name="webcam_movie_embed" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="${flashvars}"></embed></object>`
-  }
-
-  getMovie () {
-    // get reference to movie object/embed in DOM
-    var movie = document.getElementById('webcam_movie_obj')
-    if (!movie || !movie._snap) movie = document.getElementById('webcam_movie_embed')
-    if (!movie) console.log('getMovie error')
-    return movie
-  }
-
-  /**
-   * Stops the webcam capture and video playback.
-   */
-  stopWebcam () {
-    let { video, videoStream } = this
-
-    this.updateState({
-      cameraReady: false
-    })
-
-    if (videoStream) {
-      if (videoStream.stop) {
-        videoStream.stop()
-      } else if (videoStream.msStop) {
-        videoStream.msStop()
-      }
-
-      videoStream.onended = null
-      videoStream = null
-    }
-
-    if (video) {
-      video.onerror = null
-      video.pause()
-
-      if (video.mozSrcObject) {
-        video.mozSrcObject = null
-      }
-
-      video.src = ''
-    }
-
-    this.video = document.querySelector('.UppyWebcam-video')
-    this.canvas = document.querySelector('.UppyWebcam-canvas')
-  }
-
-  flashNotify (type, msg) {
-    // receive notification from flash about event
-    switch (type) {
-      case 'flashLoadComplete':
-        // movie loaded successfully
-        break
-
-      case 'cameraLive':
-        // camera is live and ready to snap
-        this.live = true
-        break
-
-      case 'error':
-        // Flash error
-        console.log('There was a flash error', msg)
-        break
-
-      default:
-        // catch-all event, just in case
-        console.log('webcam flash_notify: ' + type + ': ' + msg)
-        break
-    }
-  }
-
-  configure (panel) {
-    // open flash configuration panel -- specify tab name:
-    // 'camera', 'privacy', 'default', 'localStorage', 'microphone', 'settingsManager'
-    if (!panel) panel = 'camera'
-    this.getMovie()._configure(panel)
-  }
-
-  /**
-   * Begins recording the webcam stream and handles the media
-   * after recording ends.
-   */
-  startRecording () {
-    if (!this.videoStream) {
-      console.log('Error: no video stream available')
-      return
-    }
-
-    if (!this.mediaRecorder) {
-      this.mediaRecorder = new window.MediaRecorder(this.videoStream)
-    }
-
-    let chunks = []
-
-    this.mediaRecorder.onstop = (e) => {
-      var blob = new Blob(chunks, {type: 'video/webm'})
-      chunks = []
-      const clip = window.URL.createObjectURL(blob)
-      this.video.src = clip
-    }
-
-    this.mediaRecorder.ondataavailable = (e) => {
-      chunks.push(e.data)
-    }
-
-    this.mediaRecorder.start()
-
-    this.updateState({
-      recording: true
-    })
-
-    console.log('recorder started')
-  }
-
-  /**
-   * Ends media recording
-   */
-  stopRecording () {
-    if (!this.mediaRecorder) {
-      console.log('no media recorder exists')
-      return
-    }
-
-    this.updateState({
-      recording: false
     })
-
-    this.mediaRecorder.stop()
-  }
-
-  /**
-   * Takes a snapshot and displays it in a canvas.
-   */
-  generateImage (video, canvas, opts) {
-    canvas.width = video.videoWidth
-    canvas.height = video.videoHeight
-    canvas.getContext('2d').drawImage(video, 0, 0)
-
-    var dataUrl = canvas.toDataURL(opts.mimeType)
-
-    var file = dataURItoFile(dataUrl, {
-      name: opts.name
+    .catch((err) => {
+      this.updateState({
+        cameraError: err
+      })
     })
-
-    return {
-      dataUrl: dataUrl,
-      data: file,
-      type: opts.mimeType
-    }
   }
 
   takeSnapshot () {
@@ -396,15 +79,14 @@ export default class Webcam extends Plugin {
     }
 
     const video = document.querySelector('.UppyWebcam-video')
-    const canvas = document.querySelector('.UppyWebcam-canvas')
 
-    const image = this.generateImage(video, canvas, opts)
+    const image = this.webcam.getImage(video, opts)
 
     const tagFile = {
       source: this.id,
       name: opts.name,
       data: image.data,
-      type: opts.type
+      type: opts.mimeType
     }
 
     this.core.emitter.emit('file-add', tagFile)
@@ -419,7 +101,7 @@ export default class Webcam extends Plugin {
 
     return CameraScreen(extend(state.webcam, {
       onSnapshot: this.takeSnapshot,
-      getSWFHTML: this.getSWFHTML,
+      getSWFHTML: this.webcam.getSWFHTML,
       src: stream
     }))
   }
@@ -428,9 +110,12 @@ export default class Webcam extends Plugin {
     const firstInput = document.querySelector(`${this.target} .UppyDummy-firstInput`)
     // only works for the first time if wrapped in setTimeout for some reason
     // firstInput.focus()
-    setTimeout(function () {
-      firstInput.focus()
-    }, 10)
+    if (firstInput) {
+      setTimeout(function () {
+        firstInput.focus()
+      }, 10)
+    }
+
     this.start()
 
     setTimeout(() => {
@@ -440,6 +125,7 @@ export default class Webcam extends Plugin {
   }
 
   install () {
+    this.webcam.init()
     this.core.setState({
       webcam: {
         cameraReady: false