StreamingCapturePlugin.js

import CapturePlugin from './CapturePlugin.js'
import {
  BASE_URL,
  DATAURL_JPEG,
  blobToBuffer,
  DEFAULT_CAPTURE_OPT,
  DEPRECATION_01
} from './Common.js'

/**
 * StreamingCapturePlugin
 * @extends CapturePlugin
 * @classdesc Class for invoking streaming-related methods
 */
class StreamingCapturePlugin extends CapturePlugin {
  constructor (plugin, baseUrl = BASE_URL) {
    super(plugin, baseUrl)
  }

  /**
   * Get the CapturePlugin's stream endpoint URL.
   *
   * @description The URL returned from this endpoint can be attached to an
   * img tag's src attribute. The camera's live stream will be started and
   * begin streaming to the img tag as a
   * {@link https://en.wikipedia.org/wiki/Motion_JPEG|Motion JPEG} stream.
   * If the src is changed, the img removed from the DOM, or client disconnected
   * for any reason, the live feed will automatically be stopped.
   *
   * @param {StreamOptions} [streamOpt] - Additional options for the stream.
   *
   * @param {string|object} [deviceOpt] - Get the stream URL from either a
   * specific Device ID or a Device Object. The default is the first available
   * device.
   *
   * @async
   * @method
   * @returns {string} stream endpoint URL
   * @example
   * const img = document.createElement('img')
   * img.src = await camera.streamUrl()
   * document.body.appendChild(img)
   */
  async streamUrl (streamOpt = {}, deviceOpt) {
    const device = await this.setupDevice(deviceOpt)
    return device.streamUrl(streamOpt)
  }

  /**
   * Get the most recent frame from a device's live feed.
   *
   * @description This method will startup the device's live
   * feed if necessary and wait for it to initialize before returning a frame.
   * Subsequent calls will return the next available frame.
   * You must manually stop the live feed if you are using this method.
   *
   * If implementing a real-time preview, it is highly recommended to use the
   * stream endpoint which will stream a Motion JPEG.
   *
   * @see {@link CapturePlugin#streamUrl}
   * @see {@link CapturePlugin#stopFeed}
   *
   * @param {CaptureOptions} [captureOpt] - Additional options for capturing a
   * photo.
   *
   * @param {string|object} [deviceOpt] - Return the frame from either a
   * specific Device ID or a Device Object. The default, if not supplied, is the
   * first available device.
   *
   * @async
   * @method
   * @example
   * // Get the most recent frame from the camera's live feed as an ArrayBuffer
   * // and add it to an img tag appended to the document's body.
   * const img = document.createElement('img')
   * img.src = await camera.getMostRecentFrame()
   * document.body.appendChild(img)
   *
   * // Stop the live feed when done getting frames
   * await camera.stopFeed()
   */
  async getMostRecentFrame (captureOpt = {}, deviceOpt) {
    if (typeof captureOpt === 'string' && DEPRECATION_01) {
      captureOpt = { kind: captureOpt }
      console.warn('CaptureBridge SDK Deprecation Warning: ' +
        '`StreamingCapturePlugin.getMostRecentFrame()` converted the ' +
        '`captureOpt` argument from a string (%s) to an object (%s). This ' +
        'conversion may not be performed in future SDK versions.',
      captureOpt.kind, JSON.stringify(captureOpt))
    }
    const mergedOpt = Object.assign({}, DEFAULT_CAPTURE_OPT, captureOpt)
    const device = await this.setupDevice(mergedOpt)
    switch (mergedOpt.kind) {
      case 'objecturl':
        return URL.createObjectURL(await device.frameAsBlob(mergedOpt))
      case 'blob':
        return await device.frameAsBlob(mergedOpt)
      case 'buffer':
        return await blobToBuffer(await device.frameAsBlob(mergedOpt))
      case 'base64':
        return await device.frameAsBase64(mergedOpt)
      case 'dataurl':
        return DATAURL_JPEG + (await device.frameAsBase64(mergedOpt))
    }
    throw new Error(`Unknown image response kind: ${mergedOpt.kind}`)
  }

  /**
   * Stop the camera's live feed if it is running.
   *
   * @param {string|object} [deviceOpt] - Stop the feed for a specific Device ID
   * or a Device Object. The default, if not supplied, is the first available
   * device.
   *
   * @method
   * @async
   * @returns {object} Status of the stop operation
   * @example
   * // CapturePlugin is now running it's live feed in a background thread
   * const frame = await camera.getMostRecentFrame()
   * // Do some stuff with frame...
   * // Stop the live feed
   * console.log(await camera.stopFeed())
   */
  async stopFeed (deviceOpt) {
    const device = await this.setupDevice(deviceOpt)
    return await device.stopFeed()
  }
}

export default StreamingCapturePlugin