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

View File

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

View File

@ -15,17 +15,12 @@
<object class="GtkAdjustment" id="adjustment2"> <object class="GtkAdjustment" id="adjustment2">
<property name="lower">1</property> <property name="lower">1</property>
<property name="upper">200</property> <property name="upper">200</property>
<property name="value">30</property>
<property name="step-increment">1</property> <property name="step-increment">1</property>
<property name="page-increment">10</property> <property name="page-increment">10</property>
</object> </object>
<object class="GtkAdjustment" id="adjustment3"> <object class="GtkAdjustment" id="adjustment3">
<property name="upper">100</property> <property name="lower">0</property>
<property name="step-increment">1</property> <property name="upper">51</property>
<property name="page-increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment4">
<property name="upper">100</property>
<property name="step-increment">1</property> <property name="step-increment">1</property>
<property name="page-increment">10</property> <property name="page-increment">10</property>
</object> </object>
@ -403,6 +398,20 @@
</layout> </layout>
</object> </object>
</child> </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> <child>
<object class="GtkSeparator" id="followmouse-separator"> <object class="GtkSeparator" id="followmouse-separator">
<property name="visible">True</property> <property name="visible">True</property>
@ -478,6 +487,43 @@
</layout> </layout>
</object> </object>
</child> </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> </object>
</child> </child>
</object> </object>
@ -502,7 +548,7 @@
<property name="vexpand">True</property> <property name="vexpand">True</property>
<layout> <layout>
<property name="column">1</property> <property name="column">1</property>
<property name="row">1</property> <property name="row">2</property>
</layout> </layout>
</object> </object>
</child> </child>
@ -515,7 +561,7 @@
<property name="label" translatable="yes">label</property> <property name="label" translatable="yes">label</property>
<layout> <layout>
<property name="column">0</property> <property name="column">0</property>
<property name="row">1</property> <property name="row">2</property>
</layout> </layout>
</object> </object>
</child> </child>

View File

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

View File

@ -102,12 +102,18 @@ license =
لمزيد تفاصيل راجع رخصة جنو العمومية. إن لم تكن حصلت على نسخة من رخصة جنو العمومية مع المسجل الأزرق فانظر { license-website }. لمزيد تفاصيل راجع رخصة جنو العمومية. إن لم تكن حصلت على نسخة من رخصة جنو العمومية مع المسجل الأزرق فانظر { license-website }.
# Quality label
quality = الجودة:
# Recording button # Recording button
record = سجل record = سجل
# Record audio label # Record audio label
record-audio = تسجيل الصوت record-audio = تسجيل الصوت
# Record speaker label
record-speaker = تسجيل المكبر
# Record video label # Record video label
record-video = تسجيل الصورة record-video = تسجيل الصورة
@ -140,8 +146,10 @@ format-tooltip = لاختيار صيغة الخَرج
frames-tooltip = عدد الإطارات في الثانية frames-tooltip = عدد الإطارات في الثانية
hide-tooltip = لإخفاء نافذة المسجل الأزرق عند بدء التسجيل hide-tooltip = لإخفاء نافذة المسجل الأزرق عند بدء التسجيل
mouse-tooltip = يظهر مؤشر الفأرة عند التسجيل mouse-tooltip = يظهر مؤشر الفأرة عند التسجيل
quality-tooltip = جودة التسجيل (CRF)
record-tooltip = يبدأ تسجيل الشاشة record-tooltip = يبدأ تسجيل الشاشة
screen-tooltip = يحدد الشاشة ليسجلها screen-tooltip = يحدد الشاشة ليسجلها
speaker-tooltip = تسجيل صوت المكبر
stop-tooltip = وقف تسجيل الشاشة stop-tooltip = وقف تسجيل الشاشة
video-tooltip = يسجل الشاشة video-tooltip = يسجل الشاشة
wayland-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. 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 }. 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 # Recording button
record = Record record = Record
# Record audio label # Record audio label
record-audio = Record Audio record-audio = Record Audio
# Record speaker label
record-speaker = Record Speaker
# Record video label # Record video label
record-video = Record Video record-video = Record Video
@ -132,13 +138,15 @@ audio-source-tooltip = Select audio source
audio-tooltip = Audio recording audio-tooltip = Audio recording
delay-tooltip = Delay time before starting record delay-tooltip = Delay time before starting record
folder-tooltip = Select storage location folder-tooltip = Select storage location
follow-mouse-tooltip = Highlight Mouse follow-mouse-tooltip = Highlight mouse
format-tooltip = Select file format format-tooltip = Select file format
frames-tooltip = Frames rate frames-tooltip = Frames rate
hide-tooltip = Hide window when start recording hide-tooltip = Hide window when start recording
mouse-tooltip = Mouse appears in video recording mouse-tooltip = Mouse appears in video recording
quality-tooltip = Video quality (CRF)
record-tooltip = Start screen record record-tooltip = Start screen record
screen-tooltip = Select screen to record screen-tooltip = Select screen to record
speaker-tooltip = Speakr sound recording
stop-tooltip = Stop screen recording stop-tooltip = Stop screen recording
video-tooltip = Video recording video-tooltip = Video recording
wayland-tooltip = Not supported in Wayland 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. 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 }. 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 # Recording button
record = Record record = Record
# Record audio label # Record audio label
record-audio = Record Audio record-audio = Record Audio
# Record speaker label
record-speaker = Record Speaker
# Record video label # Record video label
record-video = Record Video record-video = Record Video
@ -132,13 +138,15 @@ audio-source-tooltip = Select audio source
audio-tooltip = Audio recording audio-tooltip = Audio recording
delay-tooltip = Delay time before starting record delay-tooltip = Delay time before starting record
folder-tooltip = Select storage location folder-tooltip = Select storage location
follow-mouse-tooltip = Highlight Mouse follow-mouse-tooltip = Highlight mouse
format-tooltip = Select file format format-tooltip = Select file format
frames-tooltip = Frames rate frames-tooltip = Frames rate
hide-tooltip = Hide window when start recording hide-tooltip = Hide window when start recording
mouse-tooltip = Mouse appears in video recording mouse-tooltip = Mouse appears in video recording
quality-tooltip = Video quality (CRF)
record-tooltip = Start screen record record-tooltip = Start screen record
screen-tooltip = Select screen to record screen-tooltip = Select screen to record
speaker-tooltip = Speakr sound recording
stop-tooltip = Stop screen recording stop-tooltip = Stop screen recording
video-tooltip = Video recording video-tooltip = Video recording
wayland-tooltip = Not supported in Wayland wayland-tooltip = Not supported in Wayland

View File

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

View File

@ -81,7 +81,6 @@ pub fn build_ui(application: &Application) {
config_management::initialize(); config_management::initialize();
// Get Objects from UI // 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_apply_label: Label = builder.object("area_apply").unwrap();
let area_chooser_window: Window = builder.object("area_chooser_window").unwrap(); let area_chooser_window: Window = builder.object("area_chooser_window").unwrap();
let area_grab_button: ToggleButton = builder.object("area_grab_button").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_label: Label = builder.object("frames_label").unwrap();
let frames_spin: SpinButton = builder.object("frames").unwrap(); let frames_spin: SpinButton = builder.object("frames").unwrap();
let hide_switch: CheckButton = builder.object("hideswitch").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 mouse_switch: CheckButton = builder.object("mouseswitch").unwrap();
let play_button: Button = builder.object("playbutton").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_button: Button = builder.object("recordbutton").unwrap();
let record_label: Label = builder.object("record_label").unwrap(); let record_label: Label = builder.object("record_label").unwrap();
let record_time_label: Label = builder.object("record_time_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_button: ToggleButton = builder.object("screen_grab_button").unwrap();
let screen_grab_icon: Image = builder.object("screen_grab_icon").unwrap(); let screen_grab_icon: Image = builder.object("screen_grab_icon").unwrap();
let screen_grab_label: Label = builder.object("screen_grab_label").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_button: Button = builder.object("stopbutton").unwrap();
let stop_label: Label = builder.object("stop_label").unwrap(); let stop_label: Label = builder.object("stop_label").unwrap();
let video_switch: CheckButton = builder.object("videoswitch").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() 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 .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 // Hide stop & play buttons
stop_button.hide(); stop_button.hide();
play_button.hide(); play_button.hide();
@ -169,7 +168,7 @@ pub fn build_ui(application: &Application) {
filename_entry.set_text(&config_management::get("default", "filename")); filename_entry.set_text(&config_management::get("default", "filename"));
command_entry.set_text(&config_management::get("default", "command")); 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() format_chooser_combobox.append(Some("mp4"), &bundle.format_pattern(bundle.get_message("mp4-format").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()); .value().unwrap(), None, &mut vec![]).to_string());
format_chooser_combobox.append( format_chooser_combobox.append(
@ -187,39 +186,13 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string()); .value().unwrap(), None, &mut vec![]).to_string());
format_chooser_combobox.append(Some("nut"), &bundle.format_pattern(bundle.get_message("nut-format").unwrap() format_chooser_combobox.append(Some("nut"), &bundle.format_pattern(bundle.get_message("nut-format").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()); .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 // Get audio sources
let input_device = host_audio_device.input_devices().unwrap(); let input_device = host_audio_device.input_devices().unwrap();
let sources_descriptions: Vec<String> = input_device let sources_descriptions: Vec<String> = input_device
.filter_map(|device| device.name().ok()) .filter_map(|device| device.name().ok())
.collect(); .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() audio_source_combobox.append(Some("default"), &bundle.format_pattern(bundle.get_message("audio-input").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()); .value().unwrap(), None, &mut vec![]).to_string());
@ -249,11 +222,16 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string())); .value().unwrap(), None, &mut vec![]).to_string()));
hide_switch.set_label(Some(&bundle.format_pattern(bundle.get_message("auto-hide").unwrap() hide_switch.set_label(Some(&bundle.format_pattern(bundle.get_message("auto-hide").unwrap()
.value().unwrap(), None, &mut vec![]).to_string())); .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")); video_switch.set_active(config_management::get_bool("default", "videocheck"));
audio_switch.set_active(config_management::get_bool("default", "audiocheck")); audio_switch.set_active(config_management::get_bool("default", "audiocheck"));
mouse_switch.set_active(config_management::get_bool("default", "mousecheck")); mouse_switch.set_active(config_management::get_bool("default", "mousecheck"));
follow_mouse_switch.set_active(config_management::get_bool("default", "followmousecheck")); follow_mouse_switch.set_active(config_management::get_bool("default", "followmousecheck"));
hide_switch.set_active(config_management::get_bool("default", "hidecheck")); 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 _video_switch = video_switch.clone();
let _audio_switch = audio_switch.clone(); let _audio_switch = audio_switch.clone();
@ -295,6 +273,9 @@ pub fn build_ui(application: &Application) {
hide_switch.connect_toggled(|switch: &CheckButton| { hide_switch.connect_toggled(|switch: &CheckButton| {
config_management::set_bool("default", "hidecheck", switch.is_active()); 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() { match dark_light::detect() {
// Dark mode // Dark mode
@ -414,17 +395,43 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string())); .value().unwrap(), None, &mut vec![]).to_string()));
delay_spin.set_tooltip_text(Some(&bundle.format_pattern(bundle.get_message("delay-tooltip").unwrap() delay_spin.set_tooltip_text(Some(&bundle.format_pattern(bundle.get_message("delay-tooltip").unwrap()
.value().unwrap(), None, &mut vec![]).to_string())); .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( frames_spin.set_value(
config_management::get("default", "frame") config_management::get("default", "frame")
.parse::<f64>() .parse::<f64>()
.unwrap(), .unwrap(),
); );
delay_spin.set_value( delay_spin.set_value(
config_management::get("default", "delay") config_management::get("default", "delay")
.parse::<f64>() .parse::<f64>()
.unwrap(), .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(); let _frames_spin = frames_spin.to_owned();
frames_spin.connect_value_changed(move |_| { frames_spin.connect_value_changed(move |_| {
@ -436,7 +443,17 @@ 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("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 // Labels
@ -446,6 +463,8 @@ pub fn build_ui(application: &Application) {
.value().unwrap(), None, &mut vec![]).to_string()); .value().unwrap(), None, &mut vec![]).to_string());
delay_label.set_label(&bundle.format_pattern(bundle.get_message("delay").unwrap() delay_label.set_label(&bundle.format_pattern(bundle.get_message("delay").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()); .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() audio_source_label.set_label(&bundle.format_pattern(bundle.get_message("audio-source").unwrap()
.value().unwrap(), None, &mut vec![]).to_string()); .value().unwrap(), None, &mut vec![]).to_string());
@ -583,6 +602,7 @@ pub fn build_ui(application: &Application) {
main_context, main_context,
temp_video_filename: String::new(), temp_video_filename: String::new(),
bundle: bundle_msg, bundle: bundle_msg,
record_quality: quality_spin,
})); }));
// Record Button // Record Button