当前位置:   article > 正文

vue获取摄像头视频、拍照_vue获取摄像头视频流

vue获取摄像头视频流
  1. <template>
  2. <div>
  3. <h1>拍照</h1>
  4. <div>
  5. 说明:
  6. <dl>
  7. <dd>navigator.mediaDevices.getUserMedia(constraints);</dd>
  8. <div>constraints 是包含</div>
  9. </dl>
  10. </div>
  11. <div>
  12. <input
  13. type="button"
  14. title="开启摄像头"
  15. value="开启摄像头"
  16. @click="getMedia"
  17. class="media-box"
  18. />
  19. <input
  20. type="button"
  21. title="关闭摄像头"
  22. value="关闭摄像头"
  23. @click="closeMedia"
  24. class="media-box"
  25. />
  26. <input
  27. type="button"
  28. title="暂停摄像头"
  29. value="暂停摄像头"
  30. @click="pauseMedia"
  31. class="media-box"
  32. />
  33. <button id="snap" @click="takePhoto">拍照</button>
  34. <button type="button" @click="downloadPhoto">下载照片</button>
  35. </div>
  36. <div>
  37. <video
  38. id="video"
  39. width="300px"
  40. height="300px"
  41. autoplay="autoplay"
  42. class="photo-area"
  43. ></video>
  44. <span>
  45. <h2>下面是照片</h2>
  46. <canvas id="canvas" width="300px" height="300px"></canvas>
  47. </span>
  48. </div>
  49. </div>
  50. </template>
  51. <script>
  52. export default {
  53. name: "Index",
  54. data() {
  55. return {
  56. photo: ""
  57. };
  58. },
  59. methods: {
  60. getMedia() {
  61. let self=this;
  62. let video = document.getElementById("video");
  63. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
  64. if (navigator.getUserMedia) {
  65. navigator.getUserMedia({video:{ width: 300, height: 300 }},
  66. function(stream) {
  67. console.log('stream:',stream)
  68. var track = stream.getTracks()[0]; // 通过这个关闭摄像头track .stop();
  69. let binaryData = [];
  70. binaryData.push(track);
  71. video.srcObject = stream;
  72. video.onloadedmetadata = function(e) {
  73. video.play();
  74. };
  75. },
  76. function(err) {
  77. alert(err);
  78. }
  79. );
  80. }
  81. this.setTimerSend();
  82. },
  83. getMedia1() {
  84. let constraints = {
  85. // 要开启 视频 video 可以简单的设置为 true ,也可以设置为对象
  86. /**
  87. * video: {
  88. * width: 摄像头像素宽 1920
  89. * height: 摄像头像素高 1080
  90. * 分辨率就是 1920*1080
  91. * width: {
  92. * max: 强制使用 max指定的宽
  93. * min: 强制使用 min 指定的宽
  94. * }
  95. * height: {
  96. * max: 强制使用 max指定的高
  97. * min: 强制使用 min 指定的高
  98. * }
  99. * exact: 表示 max == min
  100. * width: {ideal: 1920} ideal 表示应用最理想值作为像素
  101. * height: {ideal: 1080}
  102. *
  103. * facingMode: "user" 使用前置摄像头--移动端需要设置这个属性
  104. * facingMode: { exact: "environment" } 使用后置摄像头
  105. *
  106. * }
  107. *
  108. */
  109. video: { width: 300, height: 300 },
  110. audio: true
  111. };
  112. //获得video摄像头区域
  113. let video = document.getElementById("video");
  114. video.style.display = "inline-block";
  115. //这里介绍新的方法,返回一个 Promise对象
  116. // 这个Promise对象返回成功后的回调函数带一个 MediaStream 对象作为其参数
  117. // then()是Promise对象里的方法
  118. // then()方法是异步执行,当then()前的方法执行完后再执行then()内部的程序
  119. // 避免数据没有获取到
  120. console.log(navigator.mediaDevices);
  121. let promise = navigator.mediaDevices.getUserMedia(constraints);
  122. promise
  123. .then(function(MediaStream) {
  124. console.log(`MediaStream: -->`);
  125. console.log(MediaStream);
  126. /**
  127. * mediaStream:{
  128. active: true
  129. id: "k6zAanU7ynuXVvHwcfFLGmt5fX2E6OnLReVR"
  130. onactive: null
  131. onaddtrack: null
  132. oninactive: null
  133. onremovetrack: null
  134. * }
  135. *
  136. *
  137. */
  138. video.srcObject = MediaStream;
  139. // 2种方式调用 load
  140. // 使用 addEventListener("loadedmetadata", (event)=> {...})
  141. // 使用 onloadedmetadata = (event)=> {...}
  142. // 都可以
  143. video.onloadedmetadata = event => {
  144. console.info(event);
  145. console.log("媒体加载完毕");
  146. video.play();
  147. };
  148. })
  149. .catch(function(err) {
  150. console.log(err.name + ": " + err.message);
  151. }); // 总是在最后检查错误
  152. // 获取到当前用户设备的 所有的媒体设备 【麦克风,摄像机,耳机设备】等
  153. navigator.mediaDevices
  154. .enumerateDevices()
  155. .then(devices => {
  156. console.log(devices);
  157. devices.forEach(function(device) {
  158. console.log(
  159. device.kind +
  160. ": " +
  161. device.label +
  162. " id = " +
  163. device.deviceId
  164. );
  165. });
  166. })
  167. .catch(err => {
  168. console.log(err.name + ": " + err.message);
  169. });
  170. navigator.mediaDevices.ondevicechange = () => {};
  171. },
  172. // 关闭摄像头
  173. closeMedia() {
  174. let video = (document.querySelector("#video").style.display =
  175. "none");
  176. },
  177. // 暂停
  178. pauseMedia() {
  179. let video = document.querySelector("#video");
  180. video.pause();
  181. },
  182. // 拍照
  183. takePhoto() {
  184. //获得Canvas对象
  185. let video = document.getElementById("video");
  186. let canvas = document.getElementById("canvas");
  187. let ctx = canvas.getContext("2d");
  188. ctx.drawImage(video, 0, 0, video.width, video.height);
  189. // 从 canvas上获取照片数据-- 将 canvas 转换成 base64
  190. this.photo = canvas.toDataURL("image/png")
  191. },
  192. downloadPhoto() {
  193. // 照片名字,用作下载,用时间戳代替
  194. let photoName = new Date().getTime()
  195. // 将 base64转换成 blob- 二进制数据
  196. let blob = this.base64ToBlob(this.photo)
  197. let aLink = document.createElement('a');
  198. // 自定义事件
  199. let evt = document.createEvent("HTMLEvents");
  200. // 事件初始化,定义怎么触发事件, 事件名 click, true阻止事件冒泡,阻止事件默认行为
  201. evt.initEvent("click", true, true);
  202. aLink.download = photoName;
  203. aLink.href = window.URL.createObjectURL(blob);
  204. // 触发事件
  205. aLink.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));//兼容火狐
  206. },
  207. base64ToBlob(base64) {
  208. // 照片数据格式是 data:image/png;base64,base64照片数据
  209. let parts = base64.split(";base64,");
  210. console.log(parts)
  211. // 照片类型
  212. // parts[0] "data:image/png"
  213. // parts[1] 照片的base64字符串
  214. let contentType = parts[0].split(":")[1] // image/png
  215. let raw = window.atob(parts[1])
  216. let rawLength = raw.length;
  217. let uInt8Array = new Uint8Array(rawLength)
  218. for(let i=0; i<rawLength; i++) {
  219. // 将字符串每个字符全部转换成 Unicode 编码
  220. uInt8Array[i] = raw.charCodeAt(i)
  221. }
  222. // Blob 第一个参数接受的是一个数组, 参数2type是一个 MIME类型
  223. // 返回一个 二进制数据
  224. return new Blob([uInt8Array], {type: contentType})
  225. }
  226. }
  227. };
  228. </script>
  229. <style lang="scss" scoped>
  230. .media-box {
  231. border: 1px solid #ff0000;
  232. }
  233. .photo-area {
  234. border: 2px solid yellow;
  235. }
  236. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/714828
推荐阅读
相关标签
  

闽ICP备14008679号