mirror of
https://github.com/xlmnxp/blue-recorder.git
synced 2025-04-05 01:04:54 +03:00
bug fixes, force select audio or video to record
This commit is contained in:
parent
86303da319
commit
c5189deaba
124
Cargo.lock
generated
124
Cargo.lock
generated
@ -26,15 +26,6 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ansi_term"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.66"
|
version = "1.0.66"
|
||||||
@ -53,17 +44,6 @@ dependencies = [
|
|||||||
"system-deps 6.0.3",
|
"system-deps 6.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "atty"
|
|
||||||
version = "0.2.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi",
|
|
||||||
"libc",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -95,7 +75,6 @@ dependencies = [
|
|||||||
"glib 0.10.3",
|
"glib 0.10.3",
|
||||||
"gtk-sys",
|
"gtk-sys",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"ksni",
|
|
||||||
"regex",
|
"regex",
|
||||||
"rust-ini",
|
"rust-ini",
|
||||||
"secfmt",
|
"secfmt",
|
||||||
@ -197,21 +176,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap"
|
|
||||||
version = "2.34.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
|
||||||
dependencies = [
|
|
||||||
"ansi_term",
|
|
||||||
"atty",
|
|
||||||
"bitflags",
|
|
||||||
"strsim",
|
|
||||||
"textwrap",
|
|
||||||
"unicode-width",
|
|
||||||
"vec_map",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codespan-reporting"
|
name = "codespan-reporting"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@ -272,37 +236,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dbus"
|
|
||||||
version = "0.9.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"libdbus-sys",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dbus-codegen"
|
|
||||||
version = "0.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a49da9fdfbe872d4841d56605dc42efa5e6ca3291299b87f44e1cde91a28617c"
|
|
||||||
dependencies = [
|
|
||||||
"clap",
|
|
||||||
"dbus",
|
|
||||||
"xml-rs",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dbus-tree"
|
|
||||||
version = "0.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f456e698ae8e54575e19ddb1f9b7bce2298568524f215496b248eb9498b4f508"
|
|
||||||
dependencies = [
|
|
||||||
"dbus",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
@ -1042,15 +975,6 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hermit-abi"
|
|
||||||
version = "0.1.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.53"
|
version = "0.1.53"
|
||||||
@ -1093,18 +1017,6 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ksni"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "48b786146a6b576a000a289d8e1a834a3de60db75973f43ebbfec733270973f0"
|
|
||||||
dependencies = [
|
|
||||||
"dbus",
|
|
||||||
"dbus-codegen",
|
|
||||||
"dbus-tree",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -1117,15 +1029,6 @@ version = "0.2.137"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libdbus-sys"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c185b5b7ad900923ef3a8ff594083d4d9b5aea80bb4f32b8342363138c0d456b"
|
|
||||||
dependencies = [
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "link-cplusplus"
|
name = "link-cplusplus"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -1536,12 +1439,6 @@ version = "1.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strsim"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
@ -1624,15 +1521,6 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "textwrap"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-width",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.37"
|
version = "1.0.37"
|
||||||
@ -1697,12 +1585,6 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vec_map"
|
|
||||||
version = "0.8.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version-compare"
|
name = "version-compare"
|
||||||
version = "0.0.10"
|
version = "0.0.10"
|
||||||
@ -1817,9 +1699,3 @@ name = "winapi-x86_64-pc-windows-gnu"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xml-rs"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
extern crate subprocess;
|
extern crate subprocess;
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use gettextrs::gettext;
|
use gettextrs::gettext;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{CheckButton, ComboBoxText, Entry, FileChooserNative, ProgressBar, SpinButton, Window};
|
use gtk::{
|
||||||
use gtk::{ButtonsType, DialogFlags, MessageDialog, MessageType, ResponseType};
|
CheckButton, ComboBoxText, Entry, FileChooserNative, ProgressBar, SpinButton, Window,
|
||||||
|
};
|
||||||
|
use gtk::{ButtonsType, DialogFlags, MessageDialog, MessageType};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
@ -19,10 +20,7 @@ pub struct ProgressWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProgressWidget {
|
impl ProgressWidget {
|
||||||
pub fn new(
|
pub fn new(progress_dialog: MessageDialog, progressbar: ProgressBar) -> ProgressWidget {
|
||||||
progress_dialog: MessageDialog,
|
|
||||||
progressbar: ProgressBar,
|
|
||||||
) -> ProgressWidget {
|
|
||||||
ProgressWidget {
|
ProgressWidget {
|
||||||
progress_dialog,
|
progress_dialog,
|
||||||
progressbar,
|
progressbar,
|
||||||
@ -54,6 +52,7 @@ pub struct Ffmpeg {
|
|||||||
pub record_mouse: CheckButton,
|
pub record_mouse: CheckButton,
|
||||||
pub follow_mouse: CheckButton,
|
pub follow_mouse: CheckButton,
|
||||||
pub record_frames: SpinButton,
|
pub record_frames: SpinButton,
|
||||||
|
pub record_delay: SpinButton,
|
||||||
pub command: Entry,
|
pub command: Entry,
|
||||||
pub video_process_id: Option<u32>,
|
pub video_process_id: Option<u32>,
|
||||||
pub audio_process_id: Option<u32>,
|
pub audio_process_id: Option<u32>,
|
||||||
@ -100,19 +99,17 @@ impl Ffmpeg {
|
|||||||
let message_dialog = MessageDialog::new(
|
let message_dialog = MessageDialog::new(
|
||||||
Some(&self.window),
|
Some(&self.window),
|
||||||
DialogFlags::empty(),
|
DialogFlags::empty(),
|
||||||
MessageType::Warning,
|
MessageType::Question,
|
||||||
ButtonsType::Ok,
|
ButtonsType::YesNo,
|
||||||
&gettext("File already exist."),
|
&gettext("File already exist. Do you want to overwrite it?"),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
message_dialog.connect_response(|message_dialog: &MessageDialog, _| {
|
||||||
|
message_dialog.hide()
|
||||||
|
});
|
||||||
|
|
||||||
message_dialog.show();
|
message_dialog.show();
|
||||||
message_dialog.connect_response(
|
|
||||||
glib::clone!(@strong message_dialog => move |_, response| {
|
|
||||||
if response == ResponseType::Ok {
|
|
||||||
message_dialog.hide();
|
|
||||||
}
|
|
||||||
message_dialog.hide();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return (None, None);
|
return (None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +132,7 @@ impl Ffmpeg {
|
|||||||
if self.record_video.is_active() {
|
if self.record_video.is_active() {
|
||||||
let mut ffmpeg_command: Command = Command::new("ffmpeg");
|
let mut ffmpeg_command: Command = Command::new("ffmpeg");
|
||||||
|
|
||||||
// Record video with specified width and hight
|
// record video with specified width and hight
|
||||||
ffmpeg_command.arg("-video_size");
|
ffmpeg_command.arg("-video_size");
|
||||||
ffmpeg_command.arg(format!("{}x{}", width, height));
|
ffmpeg_command.arg(format!("{}x{}", width, height));
|
||||||
ffmpeg_command.arg("-framerate");
|
ffmpeg_command.arg("-framerate");
|
||||||
@ -152,7 +149,7 @@ impl Ffmpeg {
|
|||||||
y
|
y
|
||||||
));
|
));
|
||||||
|
|
||||||
// If show mouse switch is enabled, draw the mouse to video
|
// if show mouse switch is enabled, draw the mouse to video
|
||||||
ffmpeg_command.arg("-draw_mouse");
|
ffmpeg_command.arg("-draw_mouse");
|
||||||
if self.record_mouse.is_active() {
|
if self.record_mouse.is_active() {
|
||||||
ffmpeg_command.arg("1");
|
ffmpeg_command.arg("1");
|
||||||
@ -160,7 +157,7 @@ impl Ffmpeg {
|
|||||||
ffmpeg_command.arg("0");
|
ffmpeg_command.arg("0");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If follow mouse switch is enabled, follow the mouse
|
// if follow mouse switch is enabled, follow the mouse
|
||||||
if self.follow_mouse.is_active() {
|
if self.follow_mouse.is_active() {
|
||||||
ffmpeg_command.arg("-follow_mouse");
|
ffmpeg_command.arg("-follow_mouse");
|
||||||
ffmpeg_command.arg("centered");
|
ffmpeg_command.arg("centered");
|
||||||
@ -169,7 +166,9 @@ impl Ffmpeg {
|
|||||||
ffmpeg_command.arg("1");
|
ffmpeg_command.arg("1");
|
||||||
ffmpeg_command.arg(self.saved_filename.as_ref().unwrap());
|
ffmpeg_command.arg(self.saved_filename.as_ref().unwrap());
|
||||||
ffmpeg_command.arg("-y");
|
ffmpeg_command.arg("-y");
|
||||||
// Start recording and return the process id
|
// 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());
|
self.video_process_id = Some(ffmpeg_command.spawn().unwrap().id());
|
||||||
return (self.video_process_id, self.audio_process_id);
|
return (self.video_process_id, self.audio_process_id);
|
||||||
}
|
}
|
||||||
@ -179,7 +178,7 @@ impl Ffmpeg {
|
|||||||
|
|
||||||
pub fn stop_record(&self) {
|
pub fn stop_record(&self) {
|
||||||
self.progress_widget.show();
|
self.progress_widget.show();
|
||||||
// Kill the process to stop recording
|
// kill the process to stop recording
|
||||||
self.progress_widget.set_progress("".to_string(), 1, 6);
|
self.progress_widget.set_progress("".to_string(), 1, 6);
|
||||||
|
|
||||||
if self.video_process_id.is_some() {
|
if self.video_process_id.is_some() {
|
||||||
@ -241,47 +240,78 @@ impl Ffmpeg {
|
|||||||
|
|
||||||
self.progress_widget.set_progress("".to_string(), 4, 6);
|
self.progress_widget.set_progress("".to_string(), 4, 6);
|
||||||
|
|
||||||
// If audio record, then merge video with audio
|
// if audio record, then merge video with audio
|
||||||
if is_audio_record {
|
if is_audio_record {
|
||||||
self.progress_widget
|
self.progress_widget
|
||||||
.set_progress("Save Audio Recording".to_string(), 4, 6);
|
.set_progress("Save Audio Recording".to_string(), 4, 6);
|
||||||
let mut ffmpeg_audio_merge_command = Command::new("ffmpeg");
|
|
||||||
ffmpeg_audio_merge_command.arg("-i");
|
let video_filename = format!(
|
||||||
ffmpeg_audio_merge_command.arg(format!(
|
|
||||||
"{}.temp.without.audio.{}",
|
"{}.temp.without.audio.{}",
|
||||||
self.saved_filename.as_ref().unwrap(),
|
self.saved_filename.as_ref().unwrap(),
|
||||||
self.filename.2.active_id().unwrap()
|
self.filename.2.active_id().unwrap()
|
||||||
));
|
);
|
||||||
ffmpeg_audio_merge_command.arg("-i");
|
|
||||||
ffmpeg_audio_merge_command.arg(format!(
|
let audio_filename =
|
||||||
"{}.temp.audio",
|
format!("{}.temp.audio", self.saved_filename.as_ref().unwrap());
|
||||||
self.saved_filename.as_ref().unwrap()
|
|
||||||
));
|
Command::new("ffmpeg")
|
||||||
ffmpeg_audio_merge_command.arg("-c:v");
|
.args([
|
||||||
ffmpeg_audio_merge_command.arg("copy");
|
"-i",
|
||||||
ffmpeg_audio_merge_command.arg("-c:a");
|
video_filename.as_str(),
|
||||||
ffmpeg_audio_merge_command.arg("aac");
|
"-i",
|
||||||
ffmpeg_audio_merge_command.arg(self.saved_filename.as_ref().unwrap());
|
audio_filename.as_str(),
|
||||||
ffmpeg_audio_merge_command.arg("-y");
|
"-c:v",
|
||||||
|
"copy",
|
||||||
|
"-c:a",
|
||||||
|
"aac",
|
||||||
|
self.saved_filename.as_ref().unwrap(),
|
||||||
|
"-y",
|
||||||
|
])
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
sleep(Duration::from_secs(1));
|
sleep(Duration::from_secs(1));
|
||||||
ffmpeg_audio_merge_command.output().unwrap();
|
|
||||||
std::fs::remove_file(format!(
|
// std::fs::remove_file(format!(
|
||||||
|
// "{}.temp.audio",
|
||||||
|
// self.saved_filename.as_ref().unwrap()
|
||||||
|
// ))
|
||||||
|
// .unwrap();
|
||||||
|
// std::fs::remove_file(format!(
|
||||||
|
// "{}.temp.without.audio.{}",
|
||||||
|
// self.saved_filename.as_ref().unwrap(),
|
||||||
|
// self.filename.2.active_id().unwrap()
|
||||||
|
// ))
|
||||||
|
// .unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if only audio is recording then convert it to chosen format
|
||||||
|
else if is_audio_record {
|
||||||
|
self.progress_widget
|
||||||
|
.set_progress("Convert Audio to choosen format".to_string(), 4, 6);
|
||||||
|
sleep(Duration::from_secs(1));
|
||||||
|
Command::new("ffmpeg")
|
||||||
|
.arg("-f")
|
||||||
|
.arg("ogg")
|
||||||
|
.arg("-i")
|
||||||
|
.arg(format!(
|
||||||
"{}.temp.audio",
|
"{}.temp.audio",
|
||||||
self.saved_filename.as_ref().unwrap()
|
self.saved_filename.as_ref().unwrap()
|
||||||
))
|
))
|
||||||
|
.arg(self.saved_filename.as_ref().unwrap())
|
||||||
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
std::fs::remove_file(format!(
|
std::fs::remove_file(format!(
|
||||||
"{}.temp.without.audio.{}",
|
"{}.temp.audio",
|
||||||
self.saved_filename.as_ref().unwrap(),
|
self.saved_filename.as_ref().unwrap()
|
||||||
self.filename.2.active_id().unwrap()
|
))
|
||||||
))
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.progress_widget.set_progress("".to_string(), 5, 6);
|
self.progress_widget.set_progress("".to_string(), 5, 6);
|
||||||
|
|
||||||
// Execute command after finish recording
|
// execute command after finish recording
|
||||||
if self.command.text().trim() != "" {
|
if self.command.text().trim() != "" {
|
||||||
self.progress_widget.set_progress(
|
self.progress_widget.set_progress(
|
||||||
"execute custom command after finish".to_string(),
|
"execute custom command after finish".to_string(),
|
||||||
@ -299,7 +329,7 @@ impl Ffmpeg {
|
|||||||
pub fn play_record(self) {
|
pub fn play_record(self) {
|
||||||
if self.saved_filename.is_some() {
|
if self.saved_filename.is_some() {
|
||||||
if is_snap() {
|
if is_snap() {
|
||||||
// Open the video using snapctrl for snap package
|
// open the video using snapctrl for snap package
|
||||||
Command::new("snapctl")
|
Command::new("snapctl")
|
||||||
.arg("user-open")
|
.arg("user-open")
|
||||||
.arg(self.saved_filename.unwrap())
|
.arg(self.saved_filename.unwrap())
|
||||||
|
124
src/main.rs
124
src/main.rs
@ -1,6 +1,6 @@
|
|||||||
extern crate gio;
|
|
||||||
extern crate gdk;
|
extern crate gdk;
|
||||||
extern crate gettextrs;
|
extern crate gettextrs;
|
||||||
|
extern crate gio;
|
||||||
extern crate gtk;
|
extern crate gtk;
|
||||||
mod area_capture;
|
mod area_capture;
|
||||||
mod config_management;
|
mod config_management;
|
||||||
@ -8,10 +8,14 @@ mod ffmpeg_interface;
|
|||||||
mod timer;
|
mod timer;
|
||||||
|
|
||||||
use ffmpeg_interface::{Ffmpeg, ProgressWidget};
|
use ffmpeg_interface::{Ffmpeg, ProgressWidget};
|
||||||
use gettextrs::{bindtextdomain, gettext, LocaleCategory, setlocale, textdomain};
|
use gettextrs::{bindtextdomain, gettext, setlocale, textdomain, LocaleCategory};
|
||||||
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 gtk::glib;
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::{
|
||||||
|
AboutDialog, Application, Builder, Button, CheckButton, ComboBoxText, CssProvider, Entry,
|
||||||
|
FileChooserAction, FileChooserNative, Image, Label, MessageDialog, ProgressBar, SpinButton,
|
||||||
|
ToggleButton, Window,
|
||||||
|
};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -21,7 +25,7 @@ use timer::{recording_delay, start_timer, stop_timer};
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Create new application
|
// Create new application
|
||||||
let application = Application::new(Some("sa.sy.blue-recorder"), Default::default(),);
|
let application = Application::new(Some("sa.sy.blue-recorder"), Default::default());
|
||||||
application.connect_activate(build_ui);
|
application.connect_activate(build_ui);
|
||||||
application.run();
|
application.run();
|
||||||
}
|
}
|
||||||
@ -37,7 +41,7 @@ pub fn build_ui(application: &Application) {
|
|||||||
let ui_src = include_str!("../interfaces/main.ui").to_string();
|
let ui_src = include_str!("../interfaces/main.ui").to_string();
|
||||||
let builder: Builder = Builder::from_string(ui_src.as_str());
|
let builder: Builder = Builder::from_string(ui_src.as_str());
|
||||||
|
|
||||||
// Translate
|
// Translate
|
||||||
let mut po_path_abs = {
|
let mut po_path_abs = {
|
||||||
let mut current_exec_dir = std::env::current_exe().unwrap();
|
let mut current_exec_dir = std::env::current_exe().unwrap();
|
||||||
current_exec_dir.pop();
|
current_exec_dir.pop();
|
||||||
@ -136,27 +140,19 @@ pub fn build_ui(application: &Application) {
|
|||||||
// Get audio sources
|
// Get audio sources
|
||||||
let sources_descriptions: Vec<String> = {
|
let sources_descriptions: Vec<String> = {
|
||||||
let list_sources_child = Command::new("pactl")
|
let list_sources_child = Command::new("pactl")
|
||||||
.args(&["list", "sources"])
|
.args(&["list", "sources"])
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn();
|
.spawn();
|
||||||
let sources_descriptions = String::from_utf8(
|
let sources_descriptions = String::from_utf8(if let Ok(..) = list_sources_child {
|
||||||
if let Ok(..) = list_sources_child {
|
|
||||||
Command::new("grep")
|
Command::new("grep")
|
||||||
.args(&["-e", "device.description"])
|
.args(&["-e", "device.description"])
|
||||||
.stdin(
|
.stdin(list_sources_child.unwrap().stdout.take().unwrap())
|
||||||
list_sources_child
|
|
||||||
.unwrap()
|
|
||||||
.stdout
|
|
||||||
.take()
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.output()
|
.output()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.stdout
|
.stdout
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
sources_descriptions
|
sources_descriptions
|
||||||
.split('\n')
|
.split('\n')
|
||||||
@ -187,22 +183,19 @@ pub fn build_ui(application: &Application) {
|
|||||||
follow_mouse_switch.set_active(config_management::get_bool("default", "followmousecheck"));
|
follow_mouse_switch.set_active(config_management::get_bool("default", "followmousecheck"));
|
||||||
overwrite_switch.set_active(config_management::get_bool("default", "overwritecheck"));
|
overwrite_switch.set_active(config_management::get_bool("default", "overwritecheck"));
|
||||||
|
|
||||||
|
let _video_switch = video_switch.clone();
|
||||||
let _audio_switch = audio_switch.clone();
|
let _audio_switch = audio_switch.clone();
|
||||||
let _mouse_switch = mouse_switch.clone();
|
let _mouse_switch = mouse_switch.clone();
|
||||||
let _follow_mouse_switch = follow_mouse_switch.clone();
|
let _follow_mouse_switch = follow_mouse_switch.clone();
|
||||||
video_switch.connect_toggled(move |switch: &CheckButton| {
|
video_switch.connect_toggled(move |switch: &CheckButton| {
|
||||||
config_management::set_bool("default", "videocheck", switch.is_active());
|
config_management::set_bool("default", "videocheck", switch.is_active());
|
||||||
if switch.is_active() {
|
if switch.is_active() {
|
||||||
_audio_switch.set_active(false);
|
|
||||||
_audio_switch.set_sensitive(true);
|
|
||||||
_mouse_switch.set_sensitive(true);
|
_mouse_switch.set_sensitive(true);
|
||||||
} else {
|
} else {
|
||||||
_mouse_switch.set_sensitive(false);
|
_mouse_switch.set_sensitive(false);
|
||||||
_follow_mouse_switch.set_sensitive(false);
|
_follow_mouse_switch.set_sensitive(false);
|
||||||
}
|
_audio_switch.set_active(true);
|
||||||
if !switch.is_active() {
|
_audio_switch.set_sensitive(true);
|
||||||
_audio_switch.set_active(false);
|
|
||||||
_audio_switch.set_sensitive(false);
|
|
||||||
_mouse_switch.set_active(false);
|
_mouse_switch.set_active(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -216,8 +209,13 @@ pub fn build_ui(application: &Application) {
|
|||||||
_follow_mouse_switch.set_sensitive(false);
|
_follow_mouse_switch.set_sensitive(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
audio_switch.connect_toggled(|switch: &CheckButton| {
|
let _mouse_switch = mouse_switch.clone();
|
||||||
|
audio_switch.connect_toggled(move |switch: &CheckButton| {
|
||||||
config_management::set_bool("default", "audiocheck", switch.is_active());
|
config_management::set_bool("default", "audiocheck", switch.is_active());
|
||||||
|
if !switch.is_active() && !_video_switch.is_active() {
|
||||||
|
_video_switch.set_active(true);
|
||||||
|
_mouse_switch.set_sensitive(true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
follow_mouse_switch.connect_toggled(|switch: &CheckButton| {
|
follow_mouse_switch.connect_toggled(|switch: &CheckButton| {
|
||||||
config_management::set_bool("default", "followmousecheck", switch.is_active());
|
config_management::set_bool("default", "followmousecheck", switch.is_active());
|
||||||
@ -305,25 +303,28 @@ pub fn build_ui(application: &Application) {
|
|||||||
});
|
});
|
||||||
let _delay_spin = delay_spin.to_owned();
|
let _delay_spin = delay_spin.to_owned();
|
||||||
delay_spin.connect_value_changed(move |_| {
|
delay_spin.connect_value_changed(move |_| {
|
||||||
config_management::set(
|
config_management::set("default", "delay", _delay_spin.value().to_string().as_str());
|
||||||
"default",
|
|
||||||
"delay",
|
|
||||||
_delay_spin.value().to_string().as_str(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// FileChooser
|
// FileChooser
|
||||||
let folder_chooser_native = FileChooserNative::new(
|
let folder_chooser_native = FileChooserNative::new(
|
||||||
Some("Select Folder"),
|
Some("Select Folder"),
|
||||||
Some(&main_window),
|
Some(&main_window),
|
||||||
FileChooserAction::SelectFolder,
|
FileChooserAction::SelectFolder,
|
||||||
Some("Select"),
|
Some("Select"),
|
||||||
Some("Cancel"),
|
Some("Cancel"),
|
||||||
);
|
);
|
||||||
folder_chooser_native.set_transient_for(Some(&main_window));
|
folder_chooser_native.set_transient_for(Some(&main_window));
|
||||||
folder_chooser_native.set_modal(true);
|
folder_chooser_native.set_modal(true);
|
||||||
folder_chooser_native.set_file(&gio::File::for_uri(&config_management::get("default", "folder"))).unwrap();
|
folder_chooser_native
|
||||||
let folder_chooser = Some(gio::File::for_uri(&config_management::get("default", "folder"))).unwrap();
|
.set_file(&gio::File::for_uri(&config_management::get(
|
||||||
|
"default", "folder",
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
let folder_chooser = Some(gio::File::for_uri(&config_management::get(
|
||||||
|
"default", "folder",
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
let folder_chooser_name = folder_chooser.basename().unwrap();
|
let folder_chooser_name = folder_chooser.basename().unwrap();
|
||||||
folder_chooser_label.set_label(&folder_chooser_name.to_string_lossy());
|
folder_chooser_label.set_label(&folder_chooser_name.to_string_lossy());
|
||||||
let folder_chooser_icon = config_management::folder_icon(folder_chooser_name.to_str());
|
let folder_chooser_icon = config_management::folder_icon(folder_chooser_name.to_str());
|
||||||
@ -385,9 +386,15 @@ pub fn build_ui(application: &Application) {
|
|||||||
_area_capture.borrow_mut().get_area();
|
_area_capture.borrow_mut().get_area();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let _delay_spin = delay_spin.clone();
|
||||||
|
|
||||||
// Init record struct
|
// Init record struct
|
||||||
let ffmpeg_record_interface: Rc<RefCell<Ffmpeg>> = Rc::new(RefCell::new(Ffmpeg {
|
let ffmpeg_record_interface: Rc<RefCell<Ffmpeg>> = Rc::new(RefCell::new(Ffmpeg {
|
||||||
filename: (folder_chooser_native, filename_entry, format_chooser_combobox),
|
filename: (
|
||||||
|
folder_chooser_native,
|
||||||
|
filename_entry,
|
||||||
|
format_chooser_combobox,
|
||||||
|
),
|
||||||
record_video: video_switch,
|
record_video: video_switch,
|
||||||
record_audio: audio_switch,
|
record_audio: audio_switch,
|
||||||
audio_id: audio_source_combobox,
|
audio_id: audio_source_combobox,
|
||||||
@ -402,6 +409,7 @@ pub fn build_ui(application: &Application) {
|
|||||||
progress_widget: ProgressWidget::new(progress_dialog, progressbar),
|
progress_widget: ProgressWidget::new(progress_dialog, progressbar),
|
||||||
window: main_window.clone(),
|
window: main_window.clone(),
|
||||||
overwrite: overwrite_switch,
|
overwrite: overwrite_switch,
|
||||||
|
record_delay: delay_spin,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Record Button
|
// Record Button
|
||||||
@ -412,12 +420,19 @@ pub fn build_ui(application: &Application) {
|
|||||||
let _record_button = record_button.clone();
|
let _record_button = record_button.clone();
|
||||||
let _record_time_label = record_time_label.clone();
|
let _record_time_label = record_time_label.clone();
|
||||||
let _stop_button = stop_button.clone();
|
let _stop_button = stop_button.clone();
|
||||||
|
|
||||||
record_button.connect_clicked(move |_| {
|
record_button.connect_clicked(move |_| {
|
||||||
_delay_window_button.set_active(false);
|
_delay_window_button.set_active(false);
|
||||||
if delay_spin.value()as u64 > 0 {
|
if _delay_spin.value() as u64 > 0 {
|
||||||
recording_delay(delay_spin.clone(), delay_spin.value()as u64, delay_window.clone(), _delay_window_button.clone(), delay_window_label.clone(), _record_button.clone());
|
recording_delay(
|
||||||
}
|
_delay_spin.clone(),
|
||||||
if delay_spin.value()as u64 == 0 {
|
_delay_spin.value() as u64,
|
||||||
|
delay_window.clone(),
|
||||||
|
_delay_window_button.clone(),
|
||||||
|
delay_window_label.clone(),
|
||||||
|
_record_button.clone(),
|
||||||
|
);
|
||||||
|
} else if _delay_spin.value() as u64 == 0 {
|
||||||
let _area_capture = area_capture.borrow_mut();
|
let _area_capture = area_capture.borrow_mut();
|
||||||
match _ffmpeg_record_interface.borrow_mut().start_record(
|
match _ffmpeg_record_interface.borrow_mut().start_record(
|
||||||
_area_capture.x,
|
_area_capture.x,
|
||||||
@ -427,7 +442,7 @@ pub fn build_ui(application: &Application) {
|
|||||||
) {
|
) {
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
// Do nothing if the start_record function return nothing
|
// Do nothing if the start_record function return nothing
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
start_timer(record_time_label.clone());
|
start_timer(record_time_label.clone());
|
||||||
record_time_label.set_visible(true);
|
record_time_label.set_visible(true);
|
||||||
@ -454,8 +469,7 @@ pub fn build_ui(application: &Application) {
|
|||||||
|
|
||||||
// Delay Window Button
|
// Delay Window Button
|
||||||
let _delay_window_button = delay_window_button.clone();
|
let _delay_window_button = delay_window_button.clone();
|
||||||
delay_window_button.connect_clicked(move |_| {
|
delay_window_button.connect_clicked(move |_| {});
|
||||||
});
|
|
||||||
|
|
||||||
// Play Button
|
// Play Button
|
||||||
let mut _ffmpeg_record_interface = ffmpeg_record_interface.clone();
|
let mut _ffmpeg_record_interface = ffmpeg_record_interface.clone();
|
||||||
@ -498,7 +512,10 @@ pub fn build_ui(application: &Application) {
|
|||||||
"O.Chibani <11yzyv86j@relay.firefox.com>",
|
"O.Chibani <11yzyv86j@relay.firefox.com>",
|
||||||
"Patreon Supporters: Ahmad Gharib, Medium,\nWilliam Grunow, Alex Benishek.",
|
"Patreon Supporters: Ahmad Gharib, Medium,\nWilliam Grunow, Alex Benishek.",
|
||||||
]);
|
]);
|
||||||
about_dialog.set_artists(&["Mustapha Assabar", "Abdullah Al-Baroty <albaroty@gmail.com>"]);
|
about_dialog.set_artists(&[
|
||||||
|
"Mustapha Assabar",
|
||||||
|
"Abdullah Al-Baroty <albaroty@gmail.com>",
|
||||||
|
]);
|
||||||
about_dialog.set_website(Some("https://github.com/xlmnxp/blue-recorder/"));
|
about_dialog.set_website(Some("https://github.com/xlmnxp/blue-recorder/"));
|
||||||
about_dialog.set_logo_icon_name(Some("blue-recorder"));
|
about_dialog.set_logo_icon_name(Some("blue-recorder"));
|
||||||
about_dialog.set_logo(logo.paintable().as_ref());
|
about_dialog.set_logo(logo.paintable().as_ref());
|
||||||
@ -507,12 +524,12 @@ pub fn build_ui(application: &Application) {
|
|||||||
// Windows
|
// Windows
|
||||||
// Hide area chooser after it deleted.
|
// Hide area chooser after it deleted.
|
||||||
let _area_chooser_window = area_chooser_window.clone();
|
let _area_chooser_window = area_chooser_window.clone();
|
||||||
area_chooser_window.connect_close_request (move |_| {
|
area_chooser_window.connect_close_request(move |_| {
|
||||||
_area_chooser_window.hide();
|
_area_chooser_window.hide();
|
||||||
gtk::Inhibit(true)
|
gtk::Inhibit(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Close the application when main window destroy
|
// Close the application when main window destroy
|
||||||
main_window.connect_destroy(move |main_window| {
|
main_window.connect_destroy(move |main_window| {
|
||||||
let mut _ffmpeg_record_interface = ffmpeg_record_interface.clone();
|
let mut _ffmpeg_record_interface = ffmpeg_record_interface.clone();
|
||||||
// Stop recording before close the application
|
// Stop recording before close the application
|
||||||
@ -522,8 +539,7 @@ pub fn build_ui(application: &Application) {
|
|||||||
|
|
||||||
// Apply CSS
|
// Apply CSS
|
||||||
let provider = CssProvider::new();
|
let provider = CssProvider::new();
|
||||||
provider
|
provider.load_from_data(include_str!("styles/global.css").as_bytes());
|
||||||
.load_from_data(include_str!("styles/global.css").as_bytes());
|
|
||||||
gtk::StyleContext::add_provider_for_display(
|
gtk::StyleContext::add_provider_for_display(
|
||||||
&area_chooser_window.display(),
|
&area_chooser_window.display(),
|
||||||
&provider,
|
&provider,
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#delay_window {
|
#delay_window {
|
||||||
border: 3px solid @theme_selected_bg_color;
|
border: 3px solid @theme_selected_bg_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
#delay_window_label {
|
#delay_window_label {
|
||||||
font-size: 350%;
|
font-size: 350%;
|
||||||
font-weight: 250;
|
font-weight: 250;
|
||||||
|
Loading…
Reference in New Issue
Block a user