update ffmpeg

This commit is contained in:
ochibani 2024-06-16 01:40:13 +02:00
parent a98caffa89
commit 7fe3a99bcd
No known key found for this signature in database
GPG Key ID: 2C6B61CE0C704ED4
10 changed files with 253 additions and 164 deletions

60
Cargo.lock generated
View File

@ -285,9 +285,9 @@ dependencies = [
[[package]]
name = "async-signal"
version = "0.2.7"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "329972aa325176e89114919f2a80fdae4f4c040f66a370b1a1159c6c0f94e7aa"
checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d"
dependencies = [
"async-io 2.3.3",
"async-lock 3.4.0",
@ -432,6 +432,7 @@ dependencies = [
"cpal",
"dark-light",
"dirs",
"ffmpeg-sidecar",
"filename",
"fluent-bundle",
"gdk-pixbuf 0.9.0",
@ -484,7 +485,7 @@ dependencies = [
[[package]]
name = "cairo-rs"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"bitflags 2.5.0",
"cairo-sys-rs 0.20.0",
@ -507,7 +508,7 @@ dependencies = [
[[package]]
name = "cairo-sys-rs"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"glib-sys 0.20.0",
"libc",
@ -889,6 +890,15 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
name = "ffmpeg-sidecar"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec830aba6cd3da7621c58e8f06727e3b750e8383bcd934d789f2b9c3c4ea595"
dependencies = [
"anyhow",
]
[[package]]
name = "field-offset"
version = "0.3.6"
@ -1091,7 +1101,7 @@ dependencies = [
[[package]]
name = "gdk-pixbuf"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"gdk-pixbuf-sys 0.20.0",
"gio 0.20.0",
@ -1128,7 +1138,7 @@ dependencies = [
[[package]]
name = "gdk-pixbuf-sys"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"gio-sys 0.20.0",
"glib-sys 0.20.0",
@ -1173,7 +1183,7 @@ dependencies = [
[[package]]
name = "gdk4"
version = "0.9.0"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#32e7155cd32bd5c27e1847c7e38aae825642043a"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#d1c8a6fedad4d21dfbdb09abe607bf1875cada7e"
dependencies = [
"cairo-rs 0.20.0",
"gdk-pixbuf 0.20.0",
@ -1204,7 +1214,7 @@ dependencies = [
[[package]]
name = "gdk4-sys"
version = "0.9.0"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#32e7155cd32bd5c27e1847c7e38aae825642043a"
source = "git+https://github.com/gtk-rs/gtk4-rs.git#d1c8a6fedad4d21dfbdb09abe607bf1875cada7e"
dependencies = [
"cairo-sys-rs 0.20.0",
"gdk-pixbuf-sys 0.20.0",
@ -1279,7 +1289,7 @@ dependencies = [
[[package]]
name = "gio"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"futures-channel",
"futures-core",
@ -1335,7 +1345,7 @@ dependencies = [
[[package]]
name = "gio-sys"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"glib-sys 0.20.0",
"gobject-sys 0.20.0",
@ -1409,7 +1419,7 @@ dependencies = [
[[package]]
name = "glib"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"bitflags 2.5.0",
"futures-channel",
@ -1476,7 +1486,7 @@ dependencies = [
[[package]]
name = "glib-macros"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"heck 0.5.0",
"proc-macro-crate 3.1.0",
@ -1518,7 +1528,7 @@ dependencies = [
[[package]]
name = "glib-sys"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"libc",
"system-deps 6.2.2",
@ -1578,7 +1588,7 @@ dependencies = [
[[package]]
name = "gobject-sys"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"glib-sys 0.20.0",
"libc",
@ -2308,7 +2318,7 @@ dependencies = [
[[package]]
name = "pango"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"gio 0.20.0",
"glib 0.20.0",
@ -2331,7 +2341,7 @@ dependencies = [
[[package]]
name = "pango-sys"
version = "0.20.0"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#7cd06421c5027e2c1b4cc657529e6acd8bac1ea3"
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=master#0a0d3166157123035acc396c00ce8816011b1697"
dependencies = [
"glib-sys 0.20.0",
"gobject-sys 0.20.0",
@ -2551,9 +2561,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.4"
version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
"aho-corasick",
"memchr",
@ -2563,9 +2573,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
@ -2574,9 +2584,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "rust-ini"
@ -3475,12 +3485,12 @@ dependencies = [
[[package]]
name = "xdg-home"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e"
checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8"
dependencies = [
"libc",
"winapi",
"windows-sys 0.52.0",
]
[[package]]

View File

@ -11,8 +11,9 @@ chrono = "0.4.19"
cpal = "0.15.3"
dark-light = "1.0.0"
dirs = "4.0.0"
fluent-bundle = "0.15.3"
ffmpeg-sidecar = "1.1.0"
filename = "0.1.1"
fluent-bundle = "0.15.3"
gdk = { git = "https://github.com/gtk-rs/gtk4-rs.git", package = "gdk4"}
gdk-pixbuf = "0.9.0"
gio = { version = "0.15.0" }

View File

@ -15,17 +15,12 @@
<object class="GtkAdjustment" id="adjustment2">
<property name="lower">1</property>
<property name="upper">200</property>
<property name="value">30</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment3">
<property name="upper">100</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment4">
<property name="upper">100</property>
<property name="lower">0</property>
<property name="upper">51</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
@ -403,6 +398,20 @@
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="speakerswitch">
<property name="label" translatable="yes">checkbutton</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">False</property>
<property name="has-tooltip">True</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkSeparator" id="followmouse-separator">
<property name="visible">True</property>
@ -478,6 +487,43 @@
</layout>
</object>
</child>
<child>
<object class="GtkLabel" id="quality_label">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="label" translatable="yes">label</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="quality">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="max-width-chars">2</property>
<property name="width-chars">2</property>
<property name="text">number</property>
<property name="adjustment">adjustment3</property>
<property name="climb-rate">1</property>
<property name="has-tooltip">True</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkSeparator" id="quality-separator">
<property name="visible">True</property>
<property name="opacity">0.0</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
</object>
</child>
</object>
@ -502,7 +548,7 @@
<property name="vexpand">True</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
@ -515,7 +561,7 @@
<property name="label" translatable="yes">label</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="row">2</property>
</layout>
</object>
</child>

View File

@ -102,12 +102,18 @@ license =
لمزيد تفاصيل راجع رخصة جنو العمومية. إن لم تكن حصلت على نسخة من رخصة جنو العمومية مع المسجل الأزرق فانظر { license-website }.
# Quality label
quality = الجودة:
# Recording button
record = سجل
# Record audio label
record-audio = تسجيل الصوت
# Record speaker label
record-speaker = تسجيل المكبر
# Record video label
record-video = تسجيل الصورة
@ -140,8 +146,10 @@ format-tooltip = لاختيار صيغة الخَرج
frames-tooltip = عدد الإطارات في الثانية
hide-tooltip = لإخفاء نافذة المسجل الأزرق عند بدء التسجيل
mouse-tooltip = يظهر مؤشر الفأرة عند التسجيل
quality-tooltip = جودة التسجيل (CRF)
record-tooltip = يبدأ تسجيل الشاشة
screen-tooltip = يحدد الشاشة ليسجلها
speaker-tooltip = تسجيل صوت المكبر
stop-tooltip = وقف تسجيل الشاشة
video-tooltip = يسجل الشاشة
wayland-tooltip = غير مدعوم في وايلاند

View File

@ -102,12 +102,18 @@ license =
لمزيد تفاصيل راجع رخصة جنو العمومية. إن لم تكن حصلت على نسخة من رخصة جنو العمومية مع المسجل الأزرق فانظر { license-website }.
# Quality label
quality = الجودة:
# Recording button
record = سجل
# Record audio label
record-audio = تسجيل الصوت
# Record speaker label
record-speaker = تسجيل المكبر
# Record video label
record-video = تسجيل الصورة
@ -140,8 +146,10 @@ format-tooltip = لاختيار صيغة الخَرج
frames-tooltip = عدد الإطارات في الثانية
hide-tooltip = لإخفاء نافذة المسجل الأزرق عند بدء التسجيل
mouse-tooltip = يظهر مؤشر الفأرة عند التسجيل
quality-tooltip = جودة التسجيل (CRF)
record-tooltip = يبدأ تسجيل الشاشة
screen-tooltip = يحدد الشاشة ليسجلها
speaker-tooltip = تسجيل صوت المكبر
stop-tooltip = وقف تسجيل الشاشة
video-tooltip = يسجل الشاشة
wayland-tooltip = غير مدعوم في وايلاند

View File

@ -99,12 +99,18 @@ license =
Blue Recorder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Blue Recorder. If not, see { license-website }.
# Quality label
quality = Quality:
# Recording button
record = Record
# Record audio label
record-audio = Record Audio
# Record speaker label
record-speaker = Record Speaker
# Record video label
record-video = Record Video
@ -132,13 +138,15 @@ audio-source-tooltip = Select audio source
audio-tooltip = Audio recording
delay-tooltip = Delay time before starting record
folder-tooltip = Select storage location
follow-mouse-tooltip = Highlight Mouse
follow-mouse-tooltip = Highlight mouse
format-tooltip = Select file format
frames-tooltip = Frames rate
hide-tooltip = Hide window when start recording
mouse-tooltip = Mouse appears in video recording
quality-tooltip = Video quality (CRF)
record-tooltip = Start screen record
screen-tooltip = Select screen to record
speaker-tooltip = Speakr sound recording
stop-tooltip = Stop screen recording
video-tooltip = Video recording
wayland-tooltip = Not supported in Wayland

View File

@ -99,12 +99,18 @@ license =
Blue Recorder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Blue Recorder. If not, see { license-website }.
# Quality label
quality = Quality:
# Recording button
record = Record
# Record audio label
record-audio = Record Audio
# Record speaker label
record-speaker = Record Speaker
# Record video label
record-video = Record Video
@ -132,13 +138,15 @@ audio-source-tooltip = Select audio source
audio-tooltip = Audio recording
delay-tooltip = Delay time before starting record
folder-tooltip = Select storage location
follow-mouse-tooltip = Highlight Mouse
follow-mouse-tooltip = Highlight mouse
format-tooltip = Select file format
frames-tooltip = Frames rate
hide-tooltip = Hide window when start recording
mouse-tooltip = Mouse appears in video recording
quality-tooltip = Video quality (CRF)
record-tooltip = Start screen record
screen-tooltip = Select screen to record
speaker-tooltip = Speakr sound recording
stop-tooltip = Stop screen recording
video-tooltip = Video recording
wayland-tooltip = Not supported in Wayland

View File

@ -29,6 +29,8 @@ pub fn initialize() -> PathBuf {
fn default() {
set("default", "frame", "60");
set("default", "delay", "0");
set("default", "format", "0");
set("default", "quality", get_quality(&self::get("default", "format")));
set(
"default",
"folder",
@ -54,6 +56,7 @@ fn default() {
set("default", "mousecheck", "1");
set("default", "followmousecheck", "0");
set("default", "hidecheck", "0");
set("default", "speakercheck", "0");
}
fn merge_previous_version() -> Option<PathBuf> {
@ -125,3 +128,17 @@ pub fn folder_icon(folder_chooser_name: Option<&str>) -> &str {
}
}
}
pub fn get_quality(format: &str) -> &str {
let crf = match format {
"0" => "23",
"1" => "23",
"2" => "10.0",
"3" => "23",
"4" => "23",
"5" => "23",
"6" => "23.0",
_=> "23", // Default value
};
crf
}

View File

@ -2,12 +2,14 @@ extern crate subprocess;
use crate::utils::{is_snap, is_wayland};
use crate::wayland_record::{CursorModeTypes, RecordTypes, WaylandRecorder};
use chrono::prelude::*;
use ffmpeg_sidecar::child::FfmpegChild;
use ffmpeg_sidecar::command::FfmpegCommand;
use gtk::{prelude::*, ResponseType};
use gtk::{ButtonsType, DialogFlags, MessageDialog, MessageType};
use gtk::{CheckButton, ComboBoxText, Entry, FileChooserNative, SpinButton, Window};
use std::cell::RefCell;
use std::path::PathBuf;
use std::process::{Child, Command};
use std::process::Command;
use std::rc::Rc;
use std::sync::mpsc::Sender;
use std::thread::sleep;
@ -26,8 +28,8 @@ pub struct Ffmpeg {
pub record_frames: SpinButton,
pub record_delay: SpinButton,
pub command: Entry,
pub video_process: Option<Rc<RefCell<Child>>>,
pub audio_process: Option<Rc<RefCell<Child>>>,
pub video_process: Option<Rc<RefCell<FfmpegChild>>>,
pub audio_process: Option<Rc<RefCell<FfmpegChild>>>,
pub saved_filename: Option<String>,
pub unbound: Option<Sender<bool>>,
pub window: Window,
@ -36,6 +38,7 @@ pub struct Ffmpeg {
pub main_context: gtk::glib::MainContext,
pub temp_video_filename: String,
pub bundle: String,
pub record_quality: SpinButton,
}
impl Ffmpeg {
@ -82,27 +85,17 @@ impl Ffmpeg {
}
if self.record_video.is_active() && !is_wayland() {
let mut ffmpeg_command: Command = Command::new("ffmpeg");
let mut ffmpeg_command = FfmpegCommand::new();
// 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!(
"{}+{},{}",
std::env::var("DISPLAY")
.unwrap_or_else(|_| ":0".to_string())
ffmpeg_command.size(width.into(), height.into())
.rate(self.record_frames.value() as f32)
.format("x11grab")
.input(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
ffmpeg_command.arg("-draw_mouse");
@ -123,9 +116,8 @@ impl Ffmpeg {
self.filename.2.active_id().unwrap()
);
ffmpeg_command.crf(self.record_quality.value() as u32);
ffmpeg_command.args([
"-crf",
"1",
{
if self.record_audio.is_active() {
video_filename.as_str()
@ -133,8 +125,8 @@ impl Ffmpeg {
self.saved_filename.as_ref().unwrap()
}
},
"-y",
]);
ffmpeg_command.overwrite();
// sleep for delay
sleep(Duration::from_secs(self.record_delay.value() as u64));
@ -171,18 +163,15 @@ impl Ffmpeg {
}
if self.record_audio.is_active() {
let mut ffmpeg_command = Command::new("ffmpeg");
ffmpeg_command.arg("-f");
ffmpeg_command.arg("pulse");
ffmpeg_command.arg("-i");
ffmpeg_command.arg(&self.audio_id.active_id().unwrap());
ffmpeg_command.arg("-f");
ffmpeg_command.arg("ogg");
let mut ffmpeg_command = FfmpegCommand::new();
ffmpeg_command.format("pulse")
.input(&self.audio_id.active_id().unwrap())
.format("ogg");
ffmpeg_command.arg(format!(
"{}.temp.audio",
self.saved_filename.as_ref().unwrap()
));
ffmpeg_command.arg("-y");
ffmpeg_command.overwrite();
self.audio_process = Some(Rc::new(RefCell::new(ffmpeg_command.spawn().unwrap())));
}
@ -192,19 +181,11 @@ impl Ffmpeg {
pub fn stop_record(&mut self) {
// kill the process to stop recording
if self.video_process.is_some() {
Command::new("kill")
.arg(format!(
"{}",
self.video_process.clone().unwrap().borrow_mut().id()
))
.output()
.unwrap();
self.video_process
.clone()
.unwrap()
.borrow_mut()
.wait()
.quit()
.unwrap();
println!("video killed");
@ -213,20 +194,13 @@ impl Ffmpeg {
}
if self.audio_process.is_some() {
Command::new("kill")
.arg(format!(
"{}",
self.audio_process.clone().unwrap().borrow_mut().id()
))
.output()
.unwrap();
self.audio_process
.clone()
.unwrap()
.borrow_mut()
.wait()
.quit()
.unwrap();
println!("audio killed");
}
@ -252,20 +226,15 @@ impl Ffmpeg {
if is_video_record {
if is_wayland() {
// convert webm to specified format
Command::new("ffmpeg")
let mut ffmpeg_command = FfmpegCommand::new();
ffmpeg_command.input(self.temp_video_filename.as_str())
.crf(self.record_quality.value() as u32)
.args([
"-i",
self.temp_video_filename
.as_str(),
"-crf",
"23", // default quality
"-c:a",
self.filename.2.active_id().unwrap().as_str(),
self.saved_filename.as_ref().unwrap(),
"-y",
])
.output()
.unwrap();
]).overwrite().spawn()
.unwrap().wait().unwrap();
} else {
let mut move_command = Command::new("mv");
move_command.args([
@ -281,22 +250,19 @@ impl Ffmpeg {
// if audio record, then merge video and audio
if is_audio_record {
Command::new("ffmpeg")
FfmpegCommand::new().input(video_filename.as_str())
.format("ogg")
.input(audio_filename.as_str())
.crf(self.record_quality.value() as u32)
.args([
"-i",
video_filename.as_str(),
"-f",
"ogg",
"-i",
audio_filename.as_str(),
"-crf",
"23", // default quality
"-c:a",
"aac",
self.saved_filename.as_ref().unwrap(),
"-y",
])
.output()
.overwrite()
.spawn()
.unwrap()
.wait()
.expect("failed to merge video and audio");
std::fs::remove_file(audio_filename).unwrap();
@ -306,15 +272,12 @@ impl Ffmpeg {
}
// if only audio is recording then convert it to chosen format
else if is_audio_record {
Command::new("ffmpeg")
.args([
"-f",
"ogg",
"-i",
audio_filename.as_str(),
let mut ffmpeg_command = FfmpegCommand::new();
ffmpeg_command.format("ogg").input(audio_filename.as_str()).arg(
self.saved_filename.as_ref().unwrap(),
])
.output()
).spawn()
.unwrap()
.wait()
.expect("failed convert audio to video");
std::fs::remove_file(audio_filename).unwrap();

View File

@ -81,7 +81,6 @@ pub fn build_ui(application: &Application) {
config_management::initialize();
// Get Objects from UI
let main_window: Window = builder.object("main_window").unwrap();
let area_apply_label: Label = builder.object("area_apply").unwrap();
let area_chooser_window: Window = builder.object("area_chooser_window").unwrap();
let area_grab_button: ToggleButton = builder.object("area_grab_button").unwrap();
@ -110,14 +109,18 @@ pub fn build_ui(application: &Application) {
let frames_label: Label = builder.object("frames_label").unwrap();
let frames_spin: SpinButton = builder.object("frames").unwrap();
let hide_switch: CheckButton = builder.object("hideswitch").unwrap();
let main_window: Window = builder.object("main_window").unwrap();
let mouse_switch: CheckButton = builder.object("mouseswitch").unwrap();
let play_button: Button = builder.object("playbutton").unwrap();
let quality_label: Label = builder.object("quality_label").unwrap();
let quality_spin: SpinButton = builder.object("quality").unwrap();
let record_button: Button = builder.object("recordbutton").unwrap();
let record_label: Label = builder.object("record_label").unwrap();
let record_time_label: Label = builder.object("record_time_label").unwrap();
let screen_grab_button: ToggleButton = builder.object("screen_grab_button").unwrap();
let screen_grab_icon: Image = builder.object("screen_grab_icon").unwrap();
let screen_grab_label: Label = builder.object("screen_grab_label").unwrap();
let speaker_switch: CheckButton = builder.object("speakerswitch").unwrap();
let stop_button: Button = builder.object("stopbutton").unwrap();
let stop_label: Label = builder.object("stop_label").unwrap();
let video_switch: CheckButton = builder.object("videoswitch").unwrap();
@ -133,10 +136,6 @@ pub fn build_ui(application: &Application) {
area_chooser_window.set_title(Some(&bundle.format_pattern(bundle.get_message("area-chooser").unwrap()
.value().unwrap(), None, &mut vec![]).to_string())); // Title is hidden
// disable interaction with main window
// main_window.set_can_focus(false);
// main_window.set_can_target(false);
// Hide stop & play buttons
stop_button.hide();
play_button.hide();
@ -169,7 +168,7 @@ pub fn build_ui(application: &Application) {
filename_entry.set_text(&config_management::get("default", "filename"));
command_entry.set_text(&config_management::get("default", "command"));
// CheckBox
// Format combobox
format_chooser_combobox.append(Some("mp4"), &bundle.format_pattern(bundle.get_message("mp4-format").unwrap()
.value().unwrap(), None, &mut vec![]).to_string());
format_chooser_combobox.append(
@ -187,39 +186,13 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string());
format_chooser_combobox.append(Some("nut"), &bundle.format_pattern(bundle.get_message("nut-format").unwrap()
.value().unwrap(), None, &mut vec![]).to_string());
format_chooser_combobox.set_active(Some(0));
//format_chooser_combobox.set_active(Some(config_management::get("default", "format").parse::<u32>().unwrap()));
// Get audio sources
let input_device = host_audio_device.input_devices().unwrap();
let sources_descriptions: Vec<String> = input_device
.filter_map(|device| device.name().ok())
.collect();
/*let sources_descriptions: Vec<String> = {
let list_sources_child = Command::new("pactl")
.args(&["list", "sources"])
.stdout(Stdio::piped())
.spawn();
let sources_descriptions = String::from_utf8(if let Ok(..) = list_sources_child {
Command::new("grep")
.args(&["-e", "device.description"])
.stdin(list_sources_child.unwrap().stdout.take().unwrap())
.output()
.unwrap()
.stdout
} else {
Vec::new()
})
.unwrap();
sources_descriptions
.split('\n')
.map(|s| {
s.trim()
.replace("device.description = ", "")
.replace('\"', "")
})
.filter(|s| !s.is_empty())
.collect()
};*/
audio_source_combobox.append(Some("default"), &bundle.format_pattern(bundle.get_message("audio-input").unwrap()
.value().unwrap(), None, &mut vec![]).to_string());
@ -249,11 +222,16 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string()));
hide_switch.set_label(Some(&bundle.format_pattern(bundle.get_message("auto-hide").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()));
speaker_switch.set_tooltip_text(Some(&bundle.format_pattern(bundle.get_message("speaker-tooltip").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()));
speaker_switch.set_label(Some(&bundle.format_pattern(bundle.get_message("record-speaker").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()));
video_switch.set_active(config_management::get_bool("default", "videocheck"));
audio_switch.set_active(config_management::get_bool("default", "audiocheck"));
mouse_switch.set_active(config_management::get_bool("default", "mousecheck"));
follow_mouse_switch.set_active(config_management::get_bool("default", "followmousecheck"));
hide_switch.set_active(config_management::get_bool("default", "hidecheck"));
speaker_switch.set_active(config_management::get_bool("default", "speakercheck"));
let _video_switch = video_switch.clone();
let _audio_switch = audio_switch.clone();
@ -295,6 +273,9 @@ pub fn build_ui(application: &Application) {
hide_switch.connect_toggled(|switch: &CheckButton| {
config_management::set_bool("default", "hidecheck", switch.is_active());
});
speaker_switch.connect_toggled(|switch: &CheckButton| {
config_management::set_bool("default", "speakercheck", switch.is_active());
});
match dark_light::detect() {
// Dark mode
@ -414,17 +395,43 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string()));
delay_spin.set_tooltip_text(Some(&bundle.format_pattern(bundle.get_message("delay-tooltip").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()));
quality_spin.set_tooltip_text(Some(&bundle.format_pattern(bundle.get_message("quality-tooltip").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()));
frames_spin.set_value(
config_management::get("default", "frame")
.parse::<f64>()
.unwrap(),
);
delay_spin.set_value(
config_management::get("default", "delay")
.parse::<f64>()
.unwrap(),
);
//quality_spin.set_value(
//config_management::get("default", "quality")
//.parse::<f64>()
//.unwrap(),
//);
let _format_chooser_combobox = format_chooser_combobox.clone();
let _quality_spin = quality_spin.clone();
format_chooser_combobox.connect_changed(move |_| {
if _format_chooser_combobox.active_text().is_some() {
config_management::set(
"default",
"format",
&_format_chooser_combobox.active().unwrap().to_string(),
);
let quality_spin = _quality_spin.clone();
_quality_spin.connect_value_changed(move |_| {
config_management::set(
"default",
"quality",
quality_spin.to_string().as_str(),
);
});
}
});
let _frames_spin = frames_spin.to_owned();
frames_spin.connect_value_changed(move |_| {
@ -436,7 +443,17 @@ pub fn build_ui(application: &Application) {
});
let _delay_spin = delay_spin.to_owned();
delay_spin.connect_value_changed(move |_| {
config_management::set("default", "delay", _delay_spin.value().to_string().as_str());
config_management::set("default",
"delay",
_delay_spin.value().to_string().as_str());
});
let _quality_spin = delay_spin.to_owned();
quality_spin.connect_value_changed(move |_| {
config_management::set(
"default",
"quality",
_quality_spin.value().to_string().as_str(),
);
});
// Labels
@ -446,6 +463,8 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string());
delay_label.set_label(&bundle.format_pattern(bundle.get_message("delay").unwrap()
.value().unwrap(), None, &mut vec![]).to_string());
quality_label.set_label(&bundle.format_pattern(bundle.get_message("quality").unwrap()
.value().unwrap(), None, &mut vec![]).to_string());
audio_source_label.set_label(&bundle.format_pattern(bundle.get_message("audio-source").unwrap()
.value().unwrap(), None, &mut vec![]).to_string());
@ -583,6 +602,7 @@ pub fn build_ui(application: &Application) {
main_context,
temp_video_filename: String::new(),
bundle: bundle_msg,
record_quality: quality_spin,
}));
// Record Button