mirror of
https://github.com/xlmnxp/blue-recorder.git
synced 2024-11-23 17:13:11 +03:00
fix video and audio merges and fix audio recording issue
This commit is contained in:
parent
d82d71b1e7
commit
b5b10cf9b0
@ -4,8 +4,10 @@ use gettextrs::gettext;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{ButtonsType, DialogFlags, MessageDialog, MessageType};
|
use gtk::{ButtonsType, DialogFlags, MessageDialog, MessageType};
|
||||||
use gtk::{CheckButton, ComboBoxText, Entry, FileChooserNative, ProgressBar, SpinButton, Window};
|
use gtk::{CheckButton, ComboBoxText, Entry, FileChooserNative, ProgressBar, SpinButton, Window};
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{Child, Command};
|
use std::process::{Child, Command};
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -54,8 +56,8 @@ pub struct Ffmpeg {
|
|||||||
pub command: Entry,
|
pub command: Entry,
|
||||||
|
|
||||||
// TODO: fix Clone derive for process
|
// TODO: fix Clone derive for process
|
||||||
pub video_process: Option<Child>,
|
pub video_process: Option<Rc<RefCell<Child>>>,
|
||||||
pub audio_process: Option<Child>,
|
pub audio_process: Option<Rc<RefCell<Child>>>,
|
||||||
pub saved_filename: Option<String>,
|
pub saved_filename: Option<String>,
|
||||||
pub unbound: Option<Sender<bool>>,
|
pub unbound: Option<Sender<bool>>,
|
||||||
pub progress_widget: ProgressWidget,
|
pub progress_widget: ProgressWidget,
|
||||||
@ -63,22 +65,8 @@ pub struct Ffmpeg {
|
|||||||
pub overwrite: CheckButton,
|
pub overwrite: CheckButton,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for Ffmpeg {
|
|
||||||
type Target = Option<Child>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.video_process
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ffmpeg {
|
impl Ffmpeg {
|
||||||
pub fn start_record(
|
pub fn start_record(&mut self, x: u16, y: u16, width: u16, height: u16) -> Option<()> {
|
||||||
&mut self,
|
|
||||||
x: u16,
|
|
||||||
y: u16,
|
|
||||||
width: u16,
|
|
||||||
height: u16,
|
|
||||||
) -> (Option<u32>, Option<u32>) {
|
|
||||||
self.saved_filename = Some(
|
self.saved_filename = Some(
|
||||||
self.filename
|
self.filename
|
||||||
.0
|
.0
|
||||||
@ -117,7 +105,7 @@ impl Ffmpeg {
|
|||||||
|
|
||||||
message_dialog.show();
|
message_dialog.show();
|
||||||
|
|
||||||
return (None, None);
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.record_audio.is_active() {
|
if self.record_audio.is_active() {
|
||||||
@ -133,21 +121,31 @@ impl Ffmpeg {
|
|||||||
self.saved_filename.as_ref().unwrap()
|
self.saved_filename.as_ref().unwrap()
|
||||||
));
|
));
|
||||||
ffmpeg_command.arg("-y");
|
ffmpeg_command.arg("-y");
|
||||||
self.video_process = Some(ffmpeg_command.spawn().unwrap());
|
self.audio_process = Some(Rc::new(RefCell::new(ffmpeg_command.spawn().unwrap())));
|
||||||
}
|
}
|
||||||
|
|
||||||
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.args(["-video_size", format!("{}x{}", width, height).as_str(), "-framerate", self.record_frames.value().to_string().as_str(), "-f", "x11grab", "-i", format!(
|
ffmpeg_command.args([
|
||||||
"{}+{},{}",
|
"-video_size",
|
||||||
std::env::var("DISPLAY")
|
format!("{}x{}", width, height).as_str(),
|
||||||
.unwrap_or_else(|_| ":0".to_string())
|
"-framerate",
|
||||||
.as_str(),
|
self.record_frames.value().to_string().as_str(),
|
||||||
x,
|
"-f",
|
||||||
y
|
"x11grab",
|
||||||
).as_str()]);
|
"-i",
|
||||||
|
format!(
|
||||||
|
"{}+{},{}",
|
||||||
|
std::env::var("DISPLAY")
|
||||||
|
.unwrap_or_else(|_| ":0".to_string())
|
||||||
|
.as_str(),
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
|
]);
|
||||||
|
|
||||||
// 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");
|
||||||
@ -162,20 +160,33 @@ impl Ffmpeg {
|
|||||||
ffmpeg_command.args(["-follow_mouse", "centered"]);
|
ffmpeg_command.args(["-follow_mouse", "centered"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ffmpeg_command.args(["-crf", "1", self.saved_filename.as_ref().unwrap(), "-y"]);
|
let video_filename = format!(
|
||||||
|
"{}.temp.without.audio.{}",
|
||||||
|
self.saved_filename.as_ref().unwrap(),
|
||||||
|
self.filename.2.active_id().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
ffmpeg_command.args([
|
||||||
|
"-crf",
|
||||||
|
"1",
|
||||||
|
{
|
||||||
|
if self.record_audio.is_active() {
|
||||||
|
video_filename.as_str()
|
||||||
|
} else {
|
||||||
|
self.saved_filename.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"-y",
|
||||||
|
]);
|
||||||
|
|
||||||
// sleep for delay
|
// sleep for delay
|
||||||
sleep(Duration::from_secs(self.record_delay.value() as u64));
|
sleep(Duration::from_secs(self.record_delay.value() as u64));
|
||||||
|
|
||||||
// start recording and return the process id
|
// start recording and return the process id
|
||||||
self.video_process = Some(ffmpeg_command.spawn().unwrap());
|
self.video_process = Some(Rc::new(RefCell::new(ffmpeg_command.spawn().unwrap())));
|
||||||
return (
|
|
||||||
Some(self.video_process.unwrap().id()),
|
|
||||||
Some(self.audio_process.unwrap().id()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(None, None)
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop_record(&self) {
|
pub fn stop_record(&self) {
|
||||||
@ -186,7 +197,23 @@ impl Ffmpeg {
|
|||||||
if self.video_process.is_some() {
|
if self.video_process.is_some() {
|
||||||
self.progress_widget
|
self.progress_widget
|
||||||
.set_progress("Stop Recording Video".to_string(), 1, 6);
|
.set_progress("Stop Recording Video".to_string(), 1, 6);
|
||||||
self.video_process.unwrap().kill().unwrap();
|
|
||||||
|
Command::new("kill")
|
||||||
|
.arg(format!(
|
||||||
|
"{}",
|
||||||
|
self.video_process.clone().unwrap().borrow_mut().id()
|
||||||
|
))
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
self.video_process
|
||||||
|
.clone()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("video killed");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.progress_widget.set_progress("".to_string(), 2, 6);
|
self.progress_widget.set_progress("".to_string(), 2, 6);
|
||||||
@ -194,7 +221,22 @@ impl Ffmpeg {
|
|||||||
if self.audio_process.is_some() {
|
if self.audio_process.is_some() {
|
||||||
self.progress_widget
|
self.progress_widget
|
||||||
.set_progress("Stop Recording Audio".to_string(), 2, 6);
|
.set_progress("Stop Recording Audio".to_string(), 2, 6);
|
||||||
self.audio_process.unwrap().kill().unwrap();
|
|
||||||
|
Command::new("kill")
|
||||||
|
.arg(format!(
|
||||||
|
"{}",
|
||||||
|
self.audio_process.clone().unwrap().borrow_mut().id()
|
||||||
|
))
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
self.audio_process
|
||||||
|
.clone()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
println!("audio killed");
|
||||||
}
|
}
|
||||||
|
|
||||||
let video_filename = format!(
|
let video_filename = format!(
|
||||||
@ -215,7 +257,7 @@ impl Ffmpeg {
|
|||||||
if is_audio_record {
|
if is_audio_record {
|
||||||
video_filename.as_str()
|
video_filename.as_str()
|
||||||
} else {
|
} else {
|
||||||
self.saved_filename.unwrap().as_str()
|
self.saved_filename.as_ref().unwrap()
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
move_command.output().unwrap();
|
move_command.output().unwrap();
|
||||||
@ -231,6 +273,8 @@ impl Ffmpeg {
|
|||||||
.args([
|
.args([
|
||||||
"-i",
|
"-i",
|
||||||
video_filename.as_str(),
|
video_filename.as_str(),
|
||||||
|
"-f",
|
||||||
|
"ogg",
|
||||||
"-i",
|
"-i",
|
||||||
audio_filename.as_str(),
|
audio_filename.as_str(),
|
||||||
"-c:v",
|
"-c:v",
|
||||||
|
@ -125,11 +125,8 @@ pub fn build_ui(application: &Application) {
|
|||||||
command_entry.set_text(&config_management::get("default", "command"));
|
command_entry.set_text(&config_management::get("default", "command"));
|
||||||
|
|
||||||
// CheckBox
|
// CheckBox
|
||||||
format_chooser_combobox.append(
|
|
||||||
Some("mkv"),
|
|
||||||
&gettext("MKV (Matroska multimedia container format)"),
|
|
||||||
);
|
|
||||||
format_chooser_combobox.append(Some("mp4"), &gettext("MP4 (MPEG-4 Part 14)"));
|
format_chooser_combobox.append(Some("mp4"), &gettext("MP4 (MPEG-4 Part 14)"));
|
||||||
|
format_chooser_combobox.append(Some("mkv"), &gettext("MKV (Matroska multimedia container format)"));
|
||||||
format_chooser_combobox.append(Some("webm"), &gettext("WEBM (Open Web Media File)"));
|
format_chooser_combobox.append(Some("webm"), &gettext("WEBM (Open Web Media File)"));
|
||||||
format_chooser_combobox.append(Some("gif"), &gettext("GIF (Graphics Interchange Format)"));
|
format_chooser_combobox.append(Some("gif"), &gettext("GIF (Graphics Interchange Format)"));
|
||||||
format_chooser_combobox.append(Some("avi"), &gettext("AVI (Audio Video Interleaved)"));
|
format_chooser_combobox.append(Some("avi"), &gettext("AVI (Audio Video Interleaved)"));
|
||||||
@ -440,7 +437,7 @@ pub fn build_ui(application: &Application) {
|
|||||||
_area_capture.width,
|
_area_capture.width,
|
||||||
_area_capture.height,
|
_area_capture.height,
|
||||||
) {
|
) {
|
||||||
(None, None) => {
|
None => {
|
||||||
// Do nothing if the start_record function return nothing
|
// Do nothing if the start_record function return nothing
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
Loading…
Reference in New Issue
Block a user