diff --git a/bricks/bricks.js b/bricks/bricks.js index 54fa022..697f1cc 100644 --- a/bricks/bricks.js +++ b/bricks/bricks.js @@ -519,12 +519,33 @@ bricks.App = class extends bricks.Layout { this._Height = this.dom_element.offsetHeight; this.video_stream = null; this.audio_stream = null; + this.video_devices = null + this.vpos = null; document.addEventListener('keydown', this.key_down_action.bind(this)); } - async start_camera() { - if (this.video_stream) return; + async getCameras() { + try { + const devices = await navigator.mediaDevices.enumerateDevices(); + this.video_devices = devices.filter(device => device.kind === 'videoinput'); + } catch (error) { + console.error('获取摄像头数量出错:', error); + } + } + async start_camera(vpos) { + if (typeof(vpos) == 'undefined') vpos = 0; + if (this.video_devices === null){ + await this.getCameras(); + } + if (vpos == this.vpos) return; + this.vpos = vpos; + if (this.video_stream){ + this.video_stream.getTracks().forEach(track => { + track.stop(); + }); + } if (navigator.mediaDevices.getUserMedia) { - this.video_stream = await navigator.mediaDevices.getUserMedia({ video: true }); + var x = { deviceId: this.video_devices[vpos].deviceId }; + this.video_stream = await navigator.mediaDevices.getUserMedia({ video: x }); } else { console.log("Webcam access is not supported in this browser."); } diff --git a/bricks/camera.js b/bricks/camera.js index c4820d1..397c331 100644 --- a/bricks/camera.js +++ b/bricks/camera.js @@ -7,42 +7,73 @@ bricks.Camera = class extends bricks.Popup { */ constructor(opts){ opts.fps = opts.fps || 60; + opts.auto_dismiss = false; super(opts); this.stream = null; this.video = document.createElement('video'); var filler = new bricks.Filler({}); var hbox = new bricks.HBox({ - cheight:2 + cheight:3 }); + this.cur_camera_id = 0; this.add_widget(filler); this.add_widget(hbox); var shot_btn = new bricks.Icon({ url:bricks_resource('imgs/camera.png'), + margin: '10px', + tip:'Take a picture', + rate:2.5 + }); + var switch_btn = new bricks.Icon({ + url:bricks_resource('imgs/switch-camera.png'), + tip:'switch camera', + margin: '10px', rate:1.5 }); var del_btn = new bricks.Icon({ url:bricks_resource('imgs/delete.png'), + tip:'canel it', + margin: '10px', rate:1.5 }) del_btn.bind('click', this.dismiss.bind(this)); shot_btn.bind('click', this.take_picture.bind(this)); + switch_btn.bind('click', this.switch_camera.bind(this, switch_btn)); this.imgw = new bricks.Image({ width:'100%' }); + hbox.add_widget(switch_btn); hbox.add_widget(shot_btn); + hbox.add_widget(new bricks.Filler({})); hbox.add_widget(del_btn); filler.add_widget(this.imgw); this.task_period = 1 / this.fps; - schedule_once(this.startCamera.bind(this), 0.3); + schedule_once(this.startCamera.bind(this), 0.1); } - async startCamera() { - await bricks.app.start_camera(); + async switch_camera(btn, event){ + if (bricks.app.video_devices.length < 2){ + btn.disabled(true); + return; + } + var vpos = bricks.app.vpos; + vpos += 1; + if (vpos >= bricks.app.video_devices.length){ + vpos = 0; + } + this.startCamera(vpos); + } + async startCamera(vpos) { + await bricks.app.start_camera(vpos); this.stream = bricks.app.video_stream; this.video.srcObject = this.stream; this.video.play(); + this.show_cnt = 1; this.task = schedule_once(this.show_picture.bind(this), this.task_period); } show_picture(){ + if (this.task_period == 0){ + return; + } var canvas = document.createElement('canvas'); canvas.height = this.video.videoHeight; canvas.width = this.video.videoWidth; @@ -50,15 +81,18 @@ bricks.Camera = class extends bricks.Popup { context.drawImage(this.video, 0, 0); this.imgw.set_url(canvas.toDataURL('image/jpeg')); this.task = schedule_once(this.show_picture.bind(this), this.task_period); + this.show_cnt += 1; } - take_picture(){ + take_picture(event){ + event.stopPropagation(); if (this.task){ task.cancel(); + this.task = null; } + this.task_period = 0; this.task = null; var d = this.imgw.base64(); this.dispatch('shot', d); - // Create a blob from the canvas data URL } } diff --git a/bricks/image.js b/bricks/image.js index 977a340..0cb21b0 100644 --- a/bricks/image.js +++ b/bricks/image.js @@ -46,7 +46,7 @@ bricks.Image = class extends bricks.JsWidget { // 获取画布数据并转换为 base64 var dataURL = canvas.toDataURL('image/png'); // 可以根据需要修改图像格式 - dataURL = this.removeBase64Header(dataURL); + // dataURL = this.removeBase64Header(dataURL); return dataURL; } set_url(url){ diff --git a/bricks/input.js b/bricks/input.js index 2cbf42e..1baa345 100644 --- a/bricks/input.js +++ b/bricks/input.js @@ -352,7 +352,8 @@ bricks.UiImage =class extends bricks.VBox { this.uitype='image'; this.camera_w = new bricks.Icon({ url:bricks_resource('imgs/camera.png'), - rate:1.5}); + tip:'use cemera to take a picture', + rate:2}); this.add_widget(this.camera_w); this.camera_w.bind('click', this.take_photo.bind(this)); this.bind('drop', this.dropHandle.bind(this)); @@ -365,21 +366,23 @@ bricks.UiImage =class extends bricks.VBox { this.dom_element.appendChild(this.input); this.imgw = null; } - take_photo(){ + take_photo(event){ + event.stopPropagation(); var camera = new bricks.Camera({ "archor":"cc", "auto_open":true, "height":"90%", "width":"90%" }); - camera.bind('shot', this.accept_photo.bind(this)); + camera.bind('shot', this.accept_photo.bind(this, camera)); } - accept_photo(url){ + accept_photo(camera, event){ + camera.dismiss(); if (this.imgw){ this.remove_widget(this.imgw); } this.imgw = new bricks.Image({ - url:url, + url:event.params, width:'100%' }); this.add_widget(this.imgw); @@ -410,8 +413,16 @@ bricks.UiImage =class extends bricks.VBox { }; reader.readAsDataURL(file); } - set_formdata(formdata){ - formdata.append(this.name, this.value); + set_formdata(fd){ + // fd.append(this.name, this.resultValue(), 'test.png'); + fd.append(this.name, this.resultValue()); + } + resultValue(){ + if (this.imgw){ + this.value = this.imgw.base64(); + return this.value; + } + return null; } getValue(){ var ret = {}