This commit is contained in:
yumoqing 2025-09-28 17:47:37 +08:00
parent 1c67e51755
commit 2fd77ae79b
3 changed files with 111 additions and 33 deletions

View File

@ -3,6 +3,7 @@ bricks.Camera = class extends bricks.Popup {
/* /*
{ {
fps:60 fps:60
type: picture or recorder
} }
*/ */
constructor(opts){ constructor(opts){
@ -20,12 +21,23 @@ bricks.Camera = class extends bricks.Popup {
this.cur_camera_id = 0; this.cur_camera_id = 0;
this.add_widget(filler); this.add_widget(filler);
this.add_widget(hbox); this.add_widget(hbox);
var shot_btn = new bricks.Svg({ this.record_status == '';
url:bricks_resource('imgs/camera.svg'), if (this.opts.type == 'recorder'){
margin: '10px', this.record_status == 'standby';
tip:'Take a picture', var shot_btn = new bricks.Svg({
rate:2.5 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({ var switch_btn = new bricks.Svg({
url:bricks_resource('imgs/switch-camera.svg'), url:bricks_resource('imgs/switch-camera.svg'),
tip:'switch camera', tip:'switch camera',
@ -33,13 +45,17 @@ bricks.Camera = class extends bricks.Popup {
rate:1.5 rate:1.5
}); });
var del_btn = new bricks.Svg({ var del_btn = new bricks.Svg({
url:bricks_resource('imgs/delete.Svg'), url:bricks_resource('imgs/delete.svg'),
tip:'canel it', tip:'canel it',
margin: '10px', margin: '10px',
rate:1.5 rate:1.5
}) })
del_btn.bind('click', this.dismiss.bind(this)); 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)); switch_btn.bind('click', this.switch_camera.bind(this, switch_btn));
this.imgw = new bricks.Image({ this.imgw = new bricks.Image({
width:'100%' 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.task = schedule_once(this.show_picture.bind(this), this.task_period);
this.show_cnt += 1; 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(){ videorecorder_start(){
if (!this.stream) { if (!this.stream) {
throw new Error('Media stream is not initialized. Call init() first.'); 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 blob = new Blob(this.recordedChunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
resolve({ blob, url }); resolve({ blob, url });
this.dispatch('recorded', url);
}; };
this.mediaRecorder.stop(); this.mediaRecorder.stop();
this.mediaRecorder = null; this.mediaRecorder = null;

View File

@ -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 { bricks.UiImage =class extends bricks.UiFile {
constructor(opts){ constructor(opts){
opts.name = opts.name || 'image'; opts.name = opts.name || 'image';
@ -1126,31 +1196,6 @@ bricks.UiAudio =class extends bricks.UiFile {
this.player.toggle_play(); 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(); var Input = new bricks._Input();
Input.register('UiAudioRecorder', 'audiorecorder', bricks.UiAudioRecorder); Input.register('UiAudioRecorder', 'audiorecorder', bricks.UiAudioRecorder);
Input.register('UiStr', 'str', bricks.UiStr); Input.register('UiStr', 'str', bricks.UiStr);

View File

@ -140,6 +140,11 @@
"label":"Image", "label":"Image",
"required":true "required":true
}, },
{
"uitype":"video",
"name":"video_file",
"label":"Video"
},
{ {
"uitype":"text", "uitype":"text",
"name":"text", "name":"text",