From 2fd77ae79b95811b728b77972b88c4916b37c6c7 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Sun, 28 Sep 2025 17:47:37 +0800 Subject: [PATCH] bugfix --- bricks/camera.js | 44 ++++++++++++++++++---- bricks/input.js | 95 +++++++++++++++++++++++++++++++++++------------- examples/form.ui | 5 +++ 3 files changed, 111 insertions(+), 33 deletions(-) diff --git a/bricks/camera.js b/bricks/camera.js index 8da2ad2..fcc2f09 100644 --- a/bricks/camera.js +++ b/bricks/camera.js @@ -3,6 +3,7 @@ bricks.Camera = class extends bricks.Popup { /* { fps:60 + type: picture or recorder } */ constructor(opts){ @@ -20,12 +21,23 @@ bricks.Camera = class extends bricks.Popup { this.cur_camera_id = 0; this.add_widget(filler); this.add_widget(hbox); - var shot_btn = new bricks.Svg({ - url:bricks_resource('imgs/camera.svg'), - margin: '10px', - tip:'Take a picture', - rate:2.5 - }); + this.record_status == ''; + if (this.opts.type == 'recorder'){ + this.record_status == 'standby'; + var shot_btn = new bricks.Svg({ + url: bricks_resource('imgs/start_recording.svg'), + tip: 'Start record video', + margin: '10px', + rate: 2.5 + }); + } else { + var shot_btn = new bricks.Svg({ + url:bricks_resource('imgs/camera.svg'), + margin: '10px', + tip:'Take a picture', + rate:2.5 + }); + } var switch_btn = new bricks.Svg({ url:bricks_resource('imgs/switch-camera.svg'), tip:'switch camera', @@ -33,13 +45,17 @@ bricks.Camera = class extends bricks.Popup { rate:1.5 }); var del_btn = new bricks.Svg({ - url:bricks_resource('imgs/delete.Svg'), + url:bricks_resource('imgs/delete.svg'), 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)); + if (this.opts.type == 'recorder'){ + shot_btn.bind('click', this.start_recording.bind(this)); + } else { + 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%' @@ -86,6 +102,17 @@ bricks.Camera = class extends bricks.Popup { this.task = schedule_once(this.show_picture.bind(this), this.task_period); this.show_cnt += 1; } + switch_recording(){ + if (this.record_status == 'recording'){ + this.record_status == 'standby'; + this.shot_btn.set_url(bricks_resource('imgs/start_recording.svg')); + this.viderecorder_stop(); + } else { + this.record_status == 'recording'; + this.shot_btn.set_url(bricks_resource('imgs/stop_recording.svg')); + this.videorecorder_start(); + } + } videorecorder_start(){ if (!this.stream) { throw new Error('Media stream is not initialized. Call init() first.'); @@ -105,6 +132,7 @@ bricks.Camera = class extends bricks.Popup { const blob = new Blob(this.recordedChunks, { type: 'video/webm' }); const url = URL.createObjectURL(blob); resolve({ blob, url }); + this.dispatch('recorded', url); }; this.mediaRecorder.stop(); this.mediaRecorder = null; diff --git a/bricks/input.js b/bricks/input.js index a2c0e21..8f67608 100644 --- a/bricks/input.js +++ b/bricks/input.js @@ -551,6 +551,76 @@ bricks.UiFile = class extends bricks.VBox { } } +bricks.UiVideo =class extends bricks.UiFile { + constructor(opts){ + opts.name = opts.name || 'image'; + opts.width = opts.width || '100%'; + opts.accept = 'video/'; + super(opts); + this.uitype='video'; + this.camera_w = new bricks.Svg({ + url:bricks_resource('imgs/camera.svg'), + tip:'use cemera to record video', + rate:2}); + this.set_css('droparea'); + this.add_widget(this.camera_w); + this.camera_w.bind('click', this.open_recorder.bind(this)); + this.preview = new bricks.VBox({width: '100%'}); + this.add_widget(this.preview); + this.bind('changed', this.show_image.bind(this)); + } + open_recorder(event){ + event.stopPropagation(); + var camera = new bricks.Camera({ + "archor":"cc", + "auto_open":true, + "type": "recorder", + "height":"90%", + "width":"90%" + }); + camera.bring_to_top(); + camera.bind('recorded', this.accept_video.bind(this, camera)); + } + accept_video(camera, event){ + camera.dismiss(); + this.value = event.params + this.dispatch('changed', this.value); + } + show_video(event){ + var params = event.params; + if (params instanceof File){ + params = [ params ]; + } + if (typeof params == 'string'){ + params = [ params ]; + } + this.preview.clear_widgets(); + params.forEach( f => { + this._show_video(f); + }); + } + + _show_video(file) { + if (typeof file == 'string'){ + var vw = new bricks.VideoPlayer({ + url:file, + audoplay: true, + width:'100%' + }); + this.preview.add_widget(vw); + } + const reader = new FileReader(); + reader.onload = (e) => { + var imgw = new bricks.VideoPlayer({ + url:e.target.result, + autoplay: true, + width:'100%' + }); + this.preview.add_widget(imgw); + }; + reader.readAsDataURL(file); + } +} bricks.UiImage =class extends bricks.UiFile { constructor(opts){ opts.name = opts.name || 'image'; @@ -1126,31 +1196,6 @@ bricks.UiAudio =class extends bricks.UiFile { this.player.toggle_play(); } } -bricks.UiVideo =class extends bricks.UiStr { - constructor(opts){ - super(opts); - this.uitype = 'video'; - this.autoplay = opts.autoplay; - this.readonly = opts.readonly; - this.icon = new bricks.Svg({ - url: bricks_resource('imgs/right_arrow.svg')}); - this.add_widget(this.icon); - this.icon.bind('click', this.play_vide.bind(this)); - this.player = new bricks.Video({ - url:this.value - }); - if (this.autoplay){ - schedule_once(this.autoplay_video.bind(this), 1); - } - - } - autoplay_vide(){ - this.icon.dispatch('click'); - } - play_vide(){ - this.player.toggle_play(); - } -} var Input = new bricks._Input(); Input.register('UiAudioRecorder', 'audiorecorder', bricks.UiAudioRecorder); Input.register('UiStr', 'str', bricks.UiStr); diff --git a/examples/form.ui b/examples/form.ui index ee87e60..ea2e100 100644 --- a/examples/form.ui +++ b/examples/form.ui @@ -140,6 +140,11 @@ "label":"Image", "required":true }, + { + "uitype":"video", + "name":"video_file", + "label":"Video" + }, { "uitype":"text", "name":"text",