webcam.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <template>
  2. <div ref="main" :style="{ height: height + 'px' }" style="display: flex">
  3. <select @change="startCapture()" v-model="selected_camera">
  4. <option :value="index" v-for="(device, index) in devices">
  5. {{ device.label }}
  6. </option>
  7. </select>
  8. <div style="display: flex; height: 90%; overflow: scroll">
  9. <video ref="video" :height="height-100" :src="this.source"
  10. :autoplay="this.autoplay" ></video>
  11. </div>
  12. </div>
  13. </template>
  14. <script>
  15. export default {
  16. data: function () {
  17. return {
  18. stream: '',
  19. source: '',
  20. canvas: null,
  21. devices: [],
  22. selected_camera: 0,
  23. videoWidth: 1,
  24. videoHeight: 1,
  25. }
  26. },
  27. props: {
  28. maxres: {
  29. type: Number,
  30. default: 5000
  31. },
  32. height: {
  33. type: Number
  34. },
  35. autoplay: {
  36. type: Boolean,
  37. default: true
  38. },
  39. screenshotFormat: {
  40. type: String,
  41. default: 'image/jpeg'
  42. }
  43. },
  44. mounted() {
  45. var self = this
  46. window.a = this
  47. if (!this.hasMedia()) {
  48. this.$emit('notsupported');
  49. return;
  50. }
  51. window.navigator.mediaDevices.enumerateDevices().then(devices => {
  52. self.devices = devices.filter(device => { return device.kind==="videoinput"})
  53. db.getSelectedCameraIndex().then(data => {
  54. self.selected_camera = data.index
  55. self.startCapture()
  56. })
  57. })
  58. this.requestMedia();
  59. this.$refs.video.addEventListener('loadedmetadata', data => {
  60. this.$emit('ready')
  61. })
  62. },
  63. destroyed: function () {
  64. this.stop()
  65. },
  66. methods: {
  67. hasMedia() {
  68. return !!this.getMedia();
  69. },
  70. getMedia() {
  71. return (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia);
  72. },
  73. requestMedia() {
  74. navigator.getUserMedia = this.getMedia();
  75. },
  76. capture() {
  77. if (!this.hasMedia()) {
  78. this.$emit('notsupported');
  79. return null;
  80. }
  81. return this.getCanvas().toDataURL(this.screenshotFormat);
  82. },
  83. getCanvas() {
  84. let video = this.$refs.video;
  85. if (!this.ctx && video.videoHeight) {
  86. let canvas = document.createElement('canvas');
  87. canvas.height = video.videoHeight;
  88. canvas.width = video.videoWidth;
  89. this.canvas = canvas;
  90. this.ctx = canvas.getContext('2d');
  91. }
  92. const { ctx, canvas } = this;
  93. ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  94. return canvas;r
  95. },
  96. stop() {
  97. try {
  98. this.stream.getVideoTracks()[0].stop()
  99. }
  100. catch(err) { console.log(err) }
  101. },
  102. startCapture: function () {
  103. db.setSelectedCameraIndex(this.selected_camera)
  104. this.stop()
  105. if (navigator.getUserMedia) {
  106. var self = this
  107. navigator.getUserMedia({
  108. video: { deviceId: { exact:
  109. self.devices[this.selected_camera].deviceId },
  110. width: {ideal: self.maxres},
  111. height: {ideal: self.maxres}
  112. }
  113. }, stream => {
  114. this.source = window.URL.createObjectURL(stream);
  115. this.stream = stream;
  116. this.$emit('started', stream);
  117. window.stream = stream
  118. }, error => {
  119. this.$emit('error', error);
  120. });
  121. }
  122. }
  123. }
  124. }
  125. </script>