add delay timer

This commit is contained in:
ochibani 2022-11-01 03:14:23 +02:00
parent ad01c74bc6
commit a3dbd2989b
7 changed files with 159 additions and 42 deletions

43
Cargo.lock generated
View File

@ -77,6 +77,7 @@ dependencies = [
"gtk4",
"regex",
"rust-ini",
"secfmt",
"subprocess",
]
@ -102,7 +103,7 @@ dependencies = [
[[package]]
name = "cairo-rs"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"bitflags",
"cairo-sys-rs 0.17.0",
@ -126,7 +127,7 @@ dependencies = [
[[package]]
name = "cairo-sys-rs"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"glib-sys 0.17.0",
"libc",
@ -400,7 +401,7 @@ dependencies = [
[[package]]
name = "gdk-pixbuf"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"bitflags",
"gdk-pixbuf-sys 0.17.0",
@ -438,7 +439,7 @@ dependencies = [
[[package]]
name = "gdk-pixbuf-sys"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"gio-sys 0.17.0",
"glib-sys 0.17.0",
@ -483,7 +484,7 @@ dependencies = [
[[package]]
name = "gdk4"
version = "0.6.0"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#dd4d418dfe8872bacfe210b34b683530548b5d63"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#e47eca402b90322ec9e8c2fcc0f93d6a3a8b037e"
dependencies = [
"bitflags",
"cairo-rs 0.17.0",
@ -515,7 +516,7 @@ dependencies = [
[[package]]
name = "gdk4-sys"
version = "0.6.0"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#dd4d418dfe8872bacfe210b34b683530548b5d63"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#e47eca402b90322ec9e8c2fcc0f93d6a3a8b037e"
dependencies = [
"cairo-sys-rs 0.17.0",
"gdk-pixbuf-sys 0.17.0",
@ -600,7 +601,7 @@ dependencies = [
[[package]]
name = "gio"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"bitflags",
"futures-channel",
@ -645,7 +646,7 @@ dependencies = [
[[package]]
name = "gio-sys"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"glib-sys 0.17.0",
"gobject-sys 0.17.0",
@ -696,7 +697,7 @@ dependencies = [
[[package]]
name = "glib"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"bitflags",
"futures-channel",
@ -748,7 +749,7 @@ dependencies = [
[[package]]
name = "glib-macros"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"anyhow",
"heck 0.4.0",
@ -782,7 +783,7 @@ dependencies = [
[[package]]
name = "glib-sys"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"libc",
"system-deps 6.0.3",
@ -813,7 +814,7 @@ dependencies = [
[[package]]
name = "gobject-sys"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"glib-sys 0.17.0",
"libc",
@ -1024,9 +1025,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.135"
version = "0.2.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
[[package]]
name = "link-cplusplus"
@ -1163,7 +1164,7 @@ dependencies = [
[[package]]
name = "pango"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"bitflags",
"gio 0.17.0",
@ -1188,7 +1189,7 @@ dependencies = [
[[package]]
name = "pango-sys"
version = "0.17.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core#4f5e597590e30183c819c9cf15f74bd87e9ac687"
source = "git+https://github.com/gtk-rs/gtk-rs-core#cc7a2b1de10b1bc65f1841f259b8c118fec4221c"
dependencies = [
"glib-sys 0.17.0",
"gobject-sys 0.17.0",
@ -1220,9 +1221,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.25"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "ppv-lite86"
@ -1393,6 +1394,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
[[package]]
name = "secfmt"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8c73432861711997c5d0a1f61275cb4e875884c820da5ff2cffad3d3577201c"
[[package]]
name = "semver"
version = "0.11.0"

View File

@ -16,6 +16,7 @@ gtk-sys = "0.15"
glib = "0.10.3"
rust-ini = "0.16"
regex = "1.4.3"
secfmt = "0.1.1"
subprocess = "0.2.6"
[dependencies.gio]

View File

@ -103,6 +103,48 @@
</object>
</child>
</object>
<object class="GtkWindow" id="delay_window">
<property name="can-focus">True</property>
<property name="transient-for">main_window</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="default-height">200</property>
<property name="default-width">200</property>
<property name="decorated">False</property>
<property name="deletable">False</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child type="top">
<object class="GtkLabel" id="delay_window_title">
<property name="name">delay_window_title</property>
<property name="visible">True</property>
<property name="label" translatable="yes">Start Recording in…</property>
<property name="margin-top">10</property>
</object>
</child>
<child type="center">
<object class="GtkLabel" id="delay_window_label">
<property name="name">delay_window_label</property>
<property name="vexpand">True</property>
<property name="hexpand">True</property>
<property name="visible">True</property>
</object>
</child>
<child type="bottom">
<object class="GtkButton" id="delay_window_stopbutton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-bottom">10</property>
<property name="label" translatable="yes">Stop</property>
</object>
</child>
</object>
</child>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can-focus">True</property>

View File

@ -1,4 +1,5 @@
extern crate subprocess;
use chrono::prelude::*;
use gettextrs::gettext;
use gtk::prelude::*;
@ -53,7 +54,6 @@ pub struct Ffmpeg {
pub record_mouse: CheckButton,
pub follow_mouse: CheckButton,
pub record_frames: SpinButton,
pub record_delay: SpinButton,
pub command: Entry,
pub video_process_id: Option<u32>,
pub audio_process_id: Option<u32>,
@ -169,8 +169,6 @@ impl Ffmpeg {
ffmpeg_command.arg("1");
ffmpeg_command.arg(self.saved_filename.as_ref().unwrap());
ffmpeg_command.arg("-y");
// Sleep for delay
sleep(Duration::from_secs(self.record_delay.value() as u64));
// Start recording and return the process id
self.video_process_id = Some(ffmpeg_command.spawn().unwrap().id());
return (self.video_process_id, self.audio_process_id);

View File

@ -5,19 +5,22 @@ extern crate gtk;
mod area_capture;
mod config_management;
mod ffmpeg_interface;
mod timer;
use ffmpeg_interface::{Ffmpeg, ProgressWidget};
use gettextrs::{bindtextdomain, gettext, LocaleCategory, setlocale, textdomain};
use gtk::{prelude::*, Application};
use gtk::{AboutDialog, Builder, Button, CheckButton, ComboBoxText, CssProvider, Entry, FileChooserNative, FileChooserAction, Image, Label, MessageDialog, ProgressBar, SpinButton, ToggleButton, Window};
use gtk::{AboutDialog, Application, Builder, Button, CheckButton, ComboBoxText, CssProvider, Entry, FileChooserNative, FileChooserAction, Image, Label, MessageDialog, ProgressBar, SpinButton, ToggleButton, Window};
use gtk::prelude::*;
use gtk::glib;
use std::cell::RefCell;
use std::ops::Add;
use std::path::Path;
use std::process::{Command, Stdio};
use std::rc::Rc;
use timer::{recording_delay};
fn main() {
//Create new application
// Create new application
let application = Application::new(Some("sa.sy.blue-recorder"), Default::default(),);
application.connect_activate(build_ui);
application.run();
@ -70,6 +73,9 @@ pub fn build_ui(application: &Application) {
let command_label: Label = builder.object("command_label").unwrap();
let delay_label: Label = builder.object("delay_label").unwrap();
let delay_spin: SpinButton = builder.object("delay").unwrap();
let delay_window: Window = builder.object("delay_window").unwrap();
let delay_window_label: Label = builder.object("delay_window_label").unwrap();
let delay_window_button: Button = builder.object("delay_window_stopbutton").unwrap();
let filename_entry: Entry = builder.object("filename").unwrap();
let folder_chooser_button: Button = builder.object("folder_chooser").unwrap();
let folder_chooser_image: Image = builder.object("folder_chooser_image").unwrap();
@ -96,13 +102,13 @@ pub fn build_ui(application: &Application) {
// Windows
main_window.set_title(Some(&gettext("Blue Recorder")));
main_window.set_application(Some(application));
area_chooser_window.set_title(Some(&gettext("Area Chooser"))); //title is hidden
area_chooser_window.set_title(Some(&gettext("Area Chooser"))); // Title is hidden
//Hide stop & play buttons
// Hide stop & play buttons
stop_button.hide();
play_button.hide();
//Hide window grab button in Wayland
// Hide window grab button in Wayland
if is_wayland() {
window_grab_button.hide();
}
@ -276,6 +282,18 @@ pub fn build_ui(application: &Application) {
audio_source_label.set_label(&gettext("Audio Input Source:"));
// Spin
frames_spin.set_value(
config_management::get("default", "frame")
.parse::<f64>()
.unwrap(),
);
delay_spin.set_value(
config_management::get("default", "delay")
.parse::<f64>()
.unwrap(),
);
let _frames_spin = frames_spin.to_owned();
frames_spin.connect_value_changed(move |_| {
config_management::set(
@ -375,7 +393,6 @@ pub fn build_ui(application: &Application) {
record_mouse: mouse_switch,
follow_mouse: follow_mouse_switch,
record_frames: frames_spin,
record_delay: delay_spin,
command: command_entry,
video_process_id: None,
audio_process_id: None,
@ -386,30 +403,39 @@ pub fn build_ui(application: &Application) {
overwrite: overwrite_switch,
}));
let _delay_window = delay_window.clone();
let mut _ffmpeg_record_interface = ffmpeg_record_interface.clone();
let _stop_button = stop_button.clone();
let _record_button = record_button.clone();
let _stop_button = stop_button.clone();
record_button.connect_clicked(move |_| {
let _area_capture = area_capture.borrow_mut();
match _ffmpeg_record_interface.borrow_mut().start_record(
_area_capture.x,
_area_capture.y,
_area_capture.width,
_area_capture.height,
) {
(None, None) => {
if delay_spin.value()as u64 > 0 {
recording_delay(delay_spin.clone(), delay_spin.value()as u64, delay_window.clone(), delay_window_label.clone(), _record_button.clone());
}
if delay_spin.value()as u64 == 0 {
let _area_capture = area_capture.borrow_mut();
match _ffmpeg_record_interface.borrow_mut().start_record(
_area_capture.x,
_area_capture.y,
_area_capture.width,
_area_capture.height,
) {
(None, None) => {
// Do nothing if the start_record function return nothing
}
_ => {
_record_button.hide();
_stop_button.show();
_ => {
_record_button.hide();
_stop_button.show();
}
}
}
});
delay_window_button.connect_clicked(move |_| {
});
let mut _ffmpeg_record_interface = ffmpeg_record_interface.clone();
let _stop_button = stop_button.clone();
let _play_button = play_button.clone();
let _stop_button = stop_button.clone();
stop_button.connect_clicked(move |_| {
_ffmpeg_record_interface.borrow_mut().clone().stop_record();
record_button.show();

View File

@ -22,3 +22,13 @@
color: @theme_selected_fg_color;
background: @theme_selected_bg_color;
}
#delay_window_label{
font-size: 350%;
font-weight: 250;
}
#delay_window_title{
font-size: 120%;
font-weight: 50;
}

View File

@ -1 +1,34 @@
// TODO: add timer
extern crate secfmt;
use gtk::glib;
use gtk::{Button, Label, SpinButton, Window};
use gtk::prelude::*;
pub fn recording_delay(delay_spin: SpinButton, mut delay_time: u64, delay_window: Window, delay_window_label: Label, record_button: Button) {
// Keep time label alive and update every 1sec
let default_value = delay_time;
let capture_label = move || {
// Show delay window if delay time is not zero
delay_window.show();
if delay_time > 0 {
delay_window_label.set_text(&current_time(delay_time));
delay_time -= 1;
glib::source::Continue(true)
} else {
// Hide delay window and start recording
delay_window.hide();
delay_spin.set_value(0.0);
record_button.emit_clicked();
// Keep the input value
delay_spin.set_value(default_value as f64);
glib::source::Continue(false)
}
};
// Execute capture_label every 1sec
glib::source::timeout_add_seconds_local(1, capture_label);
}
fn current_time(delay_time: u64) -> String {
let delay = secfmt::from(delay_time);
format!("{}:{}", delay.minutes, delay.seconds)
}