1. vue-capture

vue-capture

Vue-Capture

A Vuejs library to record and save audio, video or pictures from your camera or mic.

Install

npm install vue-capture --save

And import it in your app

 import { Camera, Microphone } from 'vue-capture'

To quickly include vue-capture in your projects, use the cdn version

 <script src="https://cdn.jsdelivr.net/npm/vue-capture/dist/vue-capture.umd.min.js"></script>

Usage <camera>

To access a user's camera, you can use the <camera> component as:

 <template>
  <div> 
    <camera :requestAccess="true"></camera>
  </div>
</template>
 import { camera } from 'vue-capture'

export default {
  components: { camera },
}

The requestAccess is required for the browser to ask permission to access the camera.

The above example will stream the camera only. If you want to capture and download an image, then add slots which act like controls as seen here.

 <camera :requestAccess="true">
  <div slot="capture" name="capture"> snap </div>
  <div slot="download" name="download"> save </div>    
</camera>

Slots (controls) are passed as divs of the component. There are total of 10 controls available.

 <camera>
  <div name="snap"> Take a pic </div>
  <div name="download"> Download video/picture </div>
  <div name="record"> Record video </div>
  <div name="stop"> Stop recording </div>
  <div name="pause"> Pause recording </div>
  <div name="resume"> Resume recording </div>
  <div name="reset"> Reset all data (video/picture) </div>
  <div name="close"> Revoke access </div>
  <div name="fullscreen"> Toggle camera in fullscreen </div>
  <div name="flip"> Change camera type (front, back) if available </div> 
</camera>

You are not forced to put an actuall text, you can omit the text and use css class instead, like this:

 <div name='snap' class='fa fa-eye'></div>

If you have font-awesome installed, the above will show an icon which can be clicked on.

You can also use a custom icon.

If you want more flexibility like changing the order of the controls or to hide/show any div dynamially use :slots as explained later on.

Props

The camera component accepts 16 props to give you more selection and control

 <camera
  :name=""  // give custom name to downlodable content (video, picture)
  :slots=""  // object data for custom controls (explained in slots later)
  :audio=""  // whether to enable audio 
  :width=""  // canvas width in px (the video streaming frame)
  :height=""  // canvas height in px
  :autoplay=""  // show the html autoplay attributes
  :controls=""  // show the default html controls
  :imageType=""  // mimetype for the image to download
  :mediaType=""  // mimetype for saving media (video)
  :cavasClass=""  // css class name for image <canvas>
  :videoClass=""  // css class for <video>
  :fullScreen=""  // show camera stream in fullscreen
  :facingMode=""  // which camera to use: front/back
  :constraints=""  // constraints for MediaDevices.getUserMedia()
  :wrapperClass=""  // class of main div wrapper
  :requestAccess=""  // access user device if true
  >
</camera>

Events

Vue-capture also emits events before, during or after certain actions.

Example: if you want to get an event and the data when an image is captured, you can use @image:captured as:

 <camera :requestAccess="true"  @camera:captured="getImage" ></camera>
 export default {
  methods: {
    getImage(data) {
      // 'data' is the image captured in base64 format
    }
  }
}

Other events include: access:granted, access:denied, media:recording, media:paused, media:resume, media:stop ...

Usage <microphone/>

The microphone component works just like the camera, except it accepts less props and has fewer events, because it only deals with audio.

 <microphone :requestAccess="true" :mediaType="'audio/webm'">
  <div slot="record" name="record"> record </div>
  <div slot="save" slot="save"> download </div>
</microphone>

You can pass :mediaType=".." for both components. Make sure to check the supported mime types from Mozilla docs (MDN)

Dynamic controls (slots)

Due to the nature of slots in Vuejs, currently no matter how you position the control divs, they will always appear in the same way, i.e. the 'snap' button will always appear in the top, the 'download' second, 'record' third etc... To avoid this and also give your controls the advantage to hide/unhide any button dynamically based on any prior action, you can use the :slots prop.

 <camera :requestAccess="true" :slots="slots"></camera>
 export default {
  data () {
    slots: [
      { name: 'download', show: true, class: ''},
      { name: 'record', show: true, class: '' },
      { name: 'pause', show: true, class: '' },
      { name: 'stop', show: true, class: '' },
      { name: 'resume', show: true, class: '' },
      { name: 'reset', show: true, class: '' },
      { name: 'close', show: true, class: '' },
      { name: 'fullscreen', show: true, class: '' },
      { name: 'flip', show: true, class: '' },
      { name: 'snap', show: true, class: 'fa fa-save' },
    ]
  }
}

Now the divs will be ordered as seen above and by changing easily the show to true/false you can easily hide/show the controls. For example, you can hide the download button while recording and make it appear after you click 'stop'.