diff --git a/Cargo.lock b/Cargo.lock index 89966d5..03cb8d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,23 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] + [[package]] name = "ahash" version = "0.4.8" @@ -97,6 +99,9 @@ name = "arbitrary" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "arg_enum_proc_macro" @@ -215,7 +220,7 @@ dependencies = [ "polling 2.8.0", "rustix 0.37.28", "slab", - "socket2 0.4.10", + "socket2", "waker-fn", ] @@ -385,21 +390,6 @@ dependencies = [ "arrayvec", ] -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base64" version = "0.22.1" @@ -547,6 +537,27 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "cairo-rs" version = "0.16.7" @@ -558,7 +569,7 @@ dependencies = [ "glib 0.16.9", "libc", "once_cell", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -640,6 +651,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -662,7 +683,7 @@ dependencies = [ "cocoa-foundation", "core-foundation 0.10.0", "core-graphics 0.24.0", - "foreign-types 0.5.0", + "foreign-types", "libc", "objc", ] @@ -706,6 +727,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -741,7 +768,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", "core-graphics-types 0.1.3", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -754,7 +781,7 @@ dependencies = [ "bitflags 2.7.0", "core-foundation 0.10.0", "core-graphics-types 0.2.0", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -832,6 +859,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -916,6 +958,21 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b" +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivative" version = "2.2.0" @@ -927,6 +984,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "detect-desktop-environment" version = "0.2.0" @@ -941,6 +1009,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -1026,15 +1095,6 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "endi" version = "1.1.0" @@ -1167,12 +1227,15 @@ dependencies = [ [[package]] name = "ffmpeg-sidecar" -version = "1.2.0" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d67d09bdb90406a420b30ba06d464a976c9642081c2ecdf09e35ec80bd7eb9b1" +checksum = "57523e081f3afa5731b47829968beb2ed787fcc2ace71a055b0a93a5ea6b3ebb" dependencies = [ "anyhow", - "reqwest", + "tar", + "ureq", + "xz2", + "zip", ] [[package]] @@ -1185,6 +1248,18 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "libredox", + "windows-sys 0.59.0", +] + [[package]] name = "flate2" version = "1.0.35" @@ -1226,22 +1301,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d" dependencies = [ - "thiserror", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", + "thiserror 1.0.69", ] [[package]] @@ -1251,7 +1311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -1265,12 +1325,6 @@ dependencies = [ "syn 2.0.96", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1502,12 +1556,6 @@ dependencies = [ "weezl", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "gio" version = "0.16.7" @@ -1525,7 +1573,7 @@ dependencies = [ "once_cell", "pin-project-lite", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1579,7 +1627,7 @@ dependencies = [ "libc", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1784,25 +1832,6 @@ dependencies = [ "system-deps 6.2.2", ] -[[package]] -name = "h2" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "2.4.1" @@ -1877,115 +1906,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "http" -version = "1.2.0" +name = "hmac" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" - -[[package]] -name = "hyper" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", - "socket2 0.5.8", - "tokio", - "tower-service", - "tracing", + "digest", ] [[package]] @@ -2199,6 +2125,15 @@ dependencies = [ "hashbrown 0.15.2", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -2249,12 +2184,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "ipnet" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" - [[package]] name = "is-docker" version = "0.2.0" @@ -2318,7 +2247,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] @@ -2438,6 +2367,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.7.0", "libc", + "redox_syscall", ] [[package]] @@ -2458,6 +2388,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + [[package]] name = "log" version = "0.4.22" @@ -2476,6 +2412,27 @@ dependencies = [ "imgref", ] +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "mach2" version = "0.4.2" @@ -2537,12 +2494,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2559,34 +2510,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nb-connect" version = "1.2.0" @@ -2594,7 +2517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1bb540dc6ef51cfe1916ec038ce7a620daf3a111e2502d745197cd53d6bca15" dependencies = [ "libc", - "socket2 0.4.10", + "socket2", ] [[package]] @@ -2608,7 +2531,7 @@ dependencies = [ "log", "ndk-sys", "num_enum", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2684,6 +2607,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.4.2" @@ -2754,15 +2683,6 @@ dependencies = [ "malloc_buf", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "oboe" version = "0.6.1" @@ -2803,50 +2723,6 @@ dependencies = [ "pathdiff", ] -[[package]] -name = "openssl" -version = "0.10.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" -dependencies = [ - "bitflags 2.7.0", - "cfg-if 1.0.0", - "foreign-types 0.3.2", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.96", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "ordered-multimap" version = "0.3.1" @@ -2921,6 +2797,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -3000,6 +2886,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -3191,7 +3083,7 @@ dependencies = [ "rand_chacha", "simd_helpers", "system-deps 6.2.2", - "thiserror", + "thiserror 1.0.69", "v_frame", "wasm-bindgen", ] @@ -3231,6 +3123,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags 2.7.0", +] + [[package]] name = "redox_users" version = "0.4.6" @@ -3239,7 +3140,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3271,51 +3172,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.12.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-registry", -] - [[package]] name = "rgb" version = "0.8.50" @@ -3357,12 +3213,6 @@ dependencies = [ "ordered-multimap 0.4.3", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3411,22 +3261,15 @@ version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ + "log", "once_cell", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.10.1" @@ -3465,15 +3308,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schannel" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "scoped-tls" version = "1.0.1" @@ -3486,29 +3320,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8c73432861711997c5d0a1f61275cb4e875884c820da5ff2cffad3d3577201c" -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.7.0", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "self_cell" version = "0.10.3" @@ -3582,18 +3393,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha1" version = "0.10.6" @@ -3662,7 +3461,7 @@ dependencies = [ "log", "memmap2", "rustix 0.38.43", - "thiserror", + "thiserror 1.0.69", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -3683,16 +3482,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "socket2" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "spin" version = "0.9.8" @@ -3767,15 +3556,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - [[package]] name = "synstructure" version = "0.13.1" @@ -3787,27 +3567,6 @@ dependencies = [ "syn 2.0.96", ] -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.7.0", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "system-deps" version = "1.3.2" @@ -3818,7 +3577,7 @@ dependencies = [ "pkg-config", "strum", "strum_macros", - "thiserror", + "thiserror 1.0.69", "toml 0.5.11", "version-compare 0.0.10", ] @@ -3836,6 +3595,17 @@ dependencies = [ "version-compare 0.2.0", ] +[[package]] +name = "tar" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -3862,7 +3632,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", ] [[package]] @@ -3876,6 +3655,17 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "tiff" version = "0.9.1" @@ -3887,6 +3677,25 @@ dependencies = [ "weezl", ] +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + [[package]] name = "tinystr" version = "0.7.6" @@ -3897,54 +3706,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "tokio" -version = "1.43.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2 0.5.8", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - [[package]] name = "toml" version = "0.5.11" @@ -3999,33 +3760,6 @@ dependencies = [ "winnow 0.6.24", ] -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - [[package]] name = "tracing" version = "0.1.41" @@ -4057,12 +3791,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "type-map" version = "0.5.0" @@ -4125,6 +3853,22 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +dependencies = [ + "base64", + "flate2", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "url", + "webpki-roots", +] + [[package]] name = "url" version = "2.5.4" @@ -4165,12 +3909,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version-compare" version = "0.0.10" @@ -4205,15 +3943,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4396,6 +4125,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "weezl" version = "0.1.8" @@ -4557,17 +4295,6 @@ dependencies = [ "syn 2.0.96", ] -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result 0.2.0", - "windows-strings", - "windows-targets 0.52.6", -] - [[package]] name = "windows-result" version = "0.1.2" @@ -4872,6 +4599,17 @@ dependencies = [ "zbus 1.9.3", ] +[[package]] +name = "xattr" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909" +dependencies = [ + "libc", + "linux-raw-sys 0.4.15", + "rustix 0.38.43", +] + [[package]] name = "xcb" version = "1.5.0" @@ -4905,6 +4643,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + [[package]] name = "yoke" version = "0.7.5" @@ -5073,6 +4820,20 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] [[package]] name = "zerovec" @@ -5096,6 +4857,77 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "zip" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "rand", + "sha1", + "thiserror 2.0.11", + "time", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "zune-core" version = "0.4.12" diff --git a/core/Cargo.toml b/core/Cargo.toml index 1ba1c21..62d719f 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -5,13 +5,13 @@ edition = "2021" [features] cmd = [] -gtk = ["adw", "chrono", "glib", "subprocess"] +gtk = ["adw", "chrono", "glib", "subprocess", "ffmpeg-sidecar"] [dependencies] adw = { version = "0.2.1", package = "libadwaita", features = ["gtk_v4_6"], optional = true } anyhow = "1.0.86" chrono = { version = "0.4.19", optional = true } -ffmpeg-sidecar = "1.1.0" +ffmpeg-sidecar = { version = "2.0.5", optional = true } glib = { version = "0.10.3", optional = true } open = "5.1.4" subprocess = {version = "0.2.6", optional = true } diff --git a/core/src/ffmpeg_linux.rs b/core/src/ffmpeg_linux.rs index 304fa5c..6dd7138 100644 --- a/core/src/ffmpeg_linux.rs +++ b/core/src/ffmpeg_linux.rs @@ -4,19 +4,24 @@ use adw::gtk::{CheckButton, ComboBoxText, Entry, FileChooserNative, SpinButton}; use adw::gtk::prelude::*; use anyhow::{anyhow, Error, Result}; #[cfg(feature = "gtk")] +use ffmpeg_sidecar::{child::FfmpegChild, command::FfmpegCommand}; +#[cfg(feature = "gtk")] use chrono::Utc; -use ffmpeg_sidecar::child::FfmpegChild; -use ffmpeg_sidecar::command::FfmpegCommand; use tempfile; use std::{cell::RefCell, time::Instant}; use std::path::Path; #[cfg(feature = "gtk")] use std::path::PathBuf; +#[cfg(feature = "cmd")] +use std::process::{Child, Command}; use std::rc::Rc; use std::thread::sleep; use std::time::Duration; -use crate::utils::{is_input_audio_record, is_output_audio_record, is_valide, is_video_record, RecordMode}; +use crate::utils::{is_valide, is_video_record, RecordMode}; + +#[cfg(feature = "cmd")] +use crate::utils::{is_input_audio_record, is_output_audio_record}; #[cfg(feature = "cmd")] #[derive(Clone)] @@ -29,9 +34,9 @@ pub struct Ffmpeg { pub temp_output_audio_filename: String, pub temp_video_filename: String, pub height: Option, - pub input_audio_process: Option>>, - pub output_audio_process: Option>>, - pub video_process: Option>>, + pub input_audio_process: Option>>, + pub output_audio_process: Option>>, + pub video_process: Option>>, pub audio_record_bitrate: u16, pub record_delay: u16, pub record_frames: u16, @@ -48,8 +53,6 @@ pub struct Ffmpeg { pub audio_output_id: String, pub filename: (FileChooserNative, Entry, ComboBoxText), pub output: String, - pub temp_input_audio_filename: String, - pub temp_output_audio_filename: String, pub temp_video_filename: String, pub saved_filename: String, pub height: Option, @@ -60,138 +63,155 @@ pub struct Ffmpeg { pub record_delay: SpinButton, pub record_frames: SpinButton, pub video_record_bitrate: SpinButton, + pub audio_input_switch: CheckButton, + pub audio_output_switch: CheckButton, pub follow_mouse: CheckButton, pub record_mouse: CheckButton, pub show_area: CheckButton, + pub video_switch: CheckButton, } #[cfg(feature = "cmd")] impl Ffmpeg { // Start video recording pub fn start_video(&mut self, x: u16, y: u16, width: u16, height: u16, mode: RecordMode) -> Result<()> { - let display = format!("{}+{},{}", - std::env::var("DISPLAY").unwrap_or_else(|_| ":0".to_string()) - .as_str(), - x, - y - ); - let mut ffmpeg_command = FfmpegCommand::new(); - let format = "x11grab"; - self.height = Some(height); - - // Record video to tmp if audio record enabled - if !self.audio_input_id.is_empty() - || !self.audio_output_id.is_empty() - || self.output == "gif" - { - let suffix = if self.output == "gif" { - ".mp4" - } else { - &format!(".{}", &self.output) - }; - let video_tempfile = tempfile::Builder::new().prefix("ffmpeg-video-") - .suffix(suffix) - .tempfile()? - .keep()?; - self.temp_video_filename = Path::new(&video_tempfile.1).to_string_lossy() - .to_string(); - } - - // Record video with specified width and hight - if self.follow_mouse { - match mode { - RecordMode::Screen => { - let width = width as f32 * 0.95; - let height = height as f32 * 0.95; - ffmpeg_command.size(width as u32, height as u32); - }, - _=> { - ffmpeg_command.size(width.into(), height.into()); - } - } + if mode == RecordMode::Window && !self.follow_mouse.is_active() { + // pulse = gstreamer for video && add to cmd linux + add convert function to gstreamer ouput } else { - ffmpeg_command.size(width.into(), height.into()); - } + let display = format!("{}+{},{}", + std::env::var("DISPLAY").unwrap_or_else(|_| ":0".to_string()) + .as_str(), + x, + y + ); + let mut ffmpeg_command = Command::new("ffmpeg"); + let format = "x11grab"; + self.height = Some(height); - // Show grabbed area - if self.show_area { - ffmpeg_command.args(["-show_region", "1"]); - } - - // If show mouse switch is enabled, draw the mouse to video - if self.record_mouse { - ffmpeg_command.args(["-draw_mouse", "1"]); - } else { - ffmpeg_command.args(["-draw_mouse", "0"]); - }; - - // Follow the mouse - if self.follow_mouse { - ffmpeg_command.args(["-follow_mouse", "centered"]); - } - - // Disable frame rate if value is zero - if self.record_frames > 0 { - ffmpeg_command.args(["-framerate", &self.record_frames.to_string()]); - } - - // Video format && input - ffmpeg_command.format(format) - .input(display); - - // Disable bitrate if value is zero - if self.video_record_bitrate > 0 { - ffmpeg_command.args([ - "-b:v", - &format!("{}K", self.video_record_bitrate), - ]); - } - - // tmp file - if self.audio_input_id.is_empty() && - self.audio_output_id.is_empty() && - self.output != "gif" - { - ffmpeg_command.args(["-hls_flags", "temp_file"]); - } - - // Remove metadate - ffmpeg_command.args(["-map_metadata", "-1"]); - - // Output - ffmpeg_command.args([ + // Record video to tmp if audio record enabled + if !self.audio_input_id.is_empty() + || !self.audio_output_id.is_empty() + || self.output == "gif" { - if !self.audio_input_id.is_empty() - || !self.audio_output_id.is_empty() - || self.output == "gif" - { - &self.temp_video_filename + let suffix = if self.output == "gif" { + ".mp4" } else { - &self.filename + &format!(".{}", &self.output) + }; + let video_tempfile = tempfile::Builder::new().prefix("ffmpeg-video-") + .suffix(suffix) + .tempfile()? + .keep()?; + self.temp_video_filename = Path::new(&video_tempfile.1).to_string_lossy() + .to_string(); + } + + // Record video with specified width and hight + if self.follow_mouse { + match mode { + RecordMode::Screen => { + let width = width as f32 * 0.95; + let height = height as f32 * 0.95; + ffmpeg_command.args(["-s", &format!("{}x{}", width.to_string(), height.to_string())]); + }, + _=> { + ffmpeg_command.args(["-s", &format!("{}x{}", width.to_string(), height.to_string())]); + } } - }, - ]); - ffmpeg_command.overwrite(); + } else { + ffmpeg_command.args(["-s", &format!("{}x{}", width.to_string(), height.to_string())]); + } - // Sleep for delay - sleep(Duration::from_secs(self.record_delay as u64)); + // Show grabbed area + if self.show_area { + ffmpeg_command.args(["-show_region", "1"]); + } - // Start recording and return the process id - self.video_process = Some(Rc::new(RefCell::new(ffmpeg_command.spawn()?))); + // If show mouse switch is enabled, draw the mouse to video + if self.record_mouse { + ffmpeg_command.args(["-draw_mouse", "1"]); + } else { + ffmpeg_command.args(["-draw_mouse", "0"]); + }; + // Follow the mouse + if self.follow_mouse { + ffmpeg_command.args(["-follow_mouse", "centered"]); + } + + // Disable frame rate if value is zero + if self.record_frames > 0 { + ffmpeg_command.args(["-framerate", &self.record_frames.to_string()]); + } + + // Video format && input + ffmpeg_command.args(["-f", format]) + .args(["-i", &display]); + + // Disable bitrate if value is zero + if self.video_record_bitrate > 0 { + ffmpeg_command.args([ + "-b:v", + &format!("{}K", self.video_record_bitrate), + ]); + } + + // tmp file + if self.audio_input_id.is_empty() && + self.audio_output_id.is_empty() && + self.output != "gif" + { + ffmpeg_command.args(["-hls_flags", "temp_file"]); + } + + // Remove metadate + ffmpeg_command.args(["-map_metadata", "-1"]); + + // Output + ffmpeg_command.args([ + { + if !self.audio_input_id.is_empty() + || !self.audio_output_id.is_empty() + || self.output == "gif" + { + &self.temp_video_filename + } else { + &self.filename + } + }, + ]); + ffmpeg_command.arg("-y"); + + // Sleep for delay + sleep(Duration::from_secs(self.record_delay as u64)); + + // Start recording and return the process id + self.video_process = Some(Rc::new(RefCell::new(ffmpeg_command.spawn()?))); + } Ok(()) } // Stop video recording pub fn stop_video(&mut self) -> Result<()> { - // Quit the process to stop recording + // Kill the process to stop recording if self.video_process.is_some() { + Command::new("kill") + .arg(format!( + "{}", + self.video_process + .clone() + .ok_or_else(|| anyhow!("Failed to get video_process ID."))? + .borrow_mut().id() + )) + .output()?; + self.video_process .clone() .ok_or_else(|| anyhow!("Not exiting the video recording process successfully."))? .borrow_mut() - .quit()?; + .wait()?; } + Ok(()) } @@ -203,10 +223,10 @@ impl Ffmpeg { .keep()?; self.temp_input_audio_filename = Path::new(&input_audio_tempfile.1).to_string_lossy() .to_string(); - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.format("pulse") - .input(&self.audio_input_id) - .format("ogg"); + let mut ffmpeg_command = Command::new("ffmpeg"); + ffmpeg_command.args(["-f", "pulse"]) + .args(["-i", &self.audio_input_id]) + .args(["-f", "ogg"]); // Disable bitrate if value is zero if self.audio_record_bitrate > 0 { ffmpeg_command.args([ @@ -217,7 +237,7 @@ impl Ffmpeg { // Remove metadate ffmpeg_command.args(["-map_metadata", "-1"]); ffmpeg_command.arg(&self.temp_input_audio_filename); - ffmpeg_command.overwrite(); + ffmpeg_command.arg("-y"); // Sleep for delay if !is_video_record(&self.temp_video_filename) { @@ -231,14 +251,24 @@ impl Ffmpeg { // Stop audio input recording pub fn stop_input_audio(&mut self) -> Result<()> { - // Quit the process to stop recording + // Kill the process to stop recording if self.input_audio_process.is_some() { + Command::new("kill") + .arg(format!( + "{}", + self.input_audio_process + .clone() + .ok_or_else(|| anyhow!("Failed to get input_audio_process ID."))? + .borrow_mut().id() + )) + .output()?; + self.input_audio_process .clone() .ok_or_else(|| anyhow!("Not exiting the input audio recording process successfully."))? .borrow_mut() - .quit()?; - } + .wait()?; + } Ok(()) } @@ -250,14 +280,14 @@ impl Ffmpeg { .keep()?; self.temp_output_audio_filename = Path::new(&output_audio_tempfile.1).to_string_lossy() .to_string(); - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.format("pulse") - .input(&self.audio_output_id) - .format("ogg"); + let mut ffmpeg_command = Command::new("ffmpeg"); + ffmpeg_command.args(["-f", "pulse"]) + .args(["-i", &self.audio_output_id]) + .args(["-f", "ogg"]); // Remove metadate ffmpeg_command.args(["-map_metadata", "-1"]); ffmpeg_command.arg(&self.temp_output_audio_filename); - ffmpeg_command.overwrite(); + ffmpeg_command.arg("-y"); // Sleep for delay if !is_video_record(&self.temp_video_filename) && !is_input_audio_record(&self.temp_input_audio_filename) { @@ -271,13 +301,23 @@ impl Ffmpeg { // Stop audio output recording pub fn stop_output_audio(&mut self) -> Result<()> { - // Quit the process to stop recording + // Kill the process to stop recording if self.output_audio_process.is_some() { + Command::new("kill") + .arg(format!( + "{}", + self.output_audio_process + .clone() + .ok_or_else(|| anyhow!("Failed to get output_audio_process ID."))? + .borrow_mut().id() + )) + .output()?; + self.output_audio_process .clone() .ok_or_else(|| anyhow!("Not exiting the output audio recording process successfully."))? .borrow_mut() - .quit()?; + .wait()?; } Ok(()) } @@ -288,7 +328,7 @@ impl Ffmpeg { if self.output != "gif" { // Validate video file integrity let start_time = Instant::now(); - let duration = Duration::from_secs(60); + let duration = Duration::from_secs(300); loop { if is_valide(&self.temp_video_filename)? { break; @@ -296,27 +336,32 @@ impl Ffmpeg { return Err(Error::msg("Unable to validate tmp video file.")); } } - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.input(&self.temp_video_filename); - ffmpeg_command.format("ogg"); - if is_input_audio_record(&self.temp_input_audio_filename) { - ffmpeg_command.input(&self.temp_input_audio_filename); - } - if is_output_audio_record(&self.temp_output_audio_filename) { - ffmpeg_command.input(&self.temp_output_audio_filename); - } - ffmpeg_command.args([ - "-c:a", - "aac", - &self.filename, - ]); - ffmpeg_command.overwrite() - .spawn()? - .wait()?; + if is_input_audio_record(&self.temp_input_audio_filename) || + is_output_audio_record(&self.temp_output_audio_filename) { + let mut ffmpeg_command = Command::new("ffmpeg"); + ffmpeg_command.args(["-i", &self.temp_video_filename]); + ffmpeg_command.args(["-f", "ogg"]); + if is_input_audio_record(&self.temp_input_audio_filename) { + ffmpeg_command.args(["-i", &self.temp_input_audio_filename]); + } + if is_output_audio_record(&self.temp_output_audio_filename) { + ffmpeg_command.args(["-i", &self.temp_output_audio_filename]); + } + ffmpeg_command.args([ + "-c:a", + "aac", + &self.saved_filename.clone() + ]); + ffmpeg_command.arg("-y") + .spawn()? + .wait()?; + } else { + std::fs::copy(&self.temp_video_filename, &self.saved_filename)?; + } } else { // Validate video file integrity let start_time = Instant::now(); - let duration = Duration::from_secs(60); + let duration = Duration::from_secs(300); loop { if is_valide(&self.temp_video_filename)? { break; @@ -335,7 +380,7 @@ impl Ffmpeg { } else if is_input_audio_record(&self.temp_input_audio_filename) { // Validate audio file integrity let start_time = Instant::now(); - let duration = Duration::from_secs(60); + let duration = Duration::from_secs(300); loop { if is_valide(&self.temp_input_audio_filename)? { break; @@ -344,23 +389,23 @@ impl Ffmpeg { } } // If only audio is recording then convert it to chosen format - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.format("ogg"); - ffmpeg_command.input(&self.temp_input_audio_filename); + let mut ffmpeg_command = Command::new("ffmpeg"); + ffmpeg_command.args(["-f", "ogg"]); + ffmpeg_command.args(["-i", &self.temp_input_audio_filename]); if is_output_audio_record(&self.temp_output_audio_filename) { - ffmpeg_command.input(&self.temp_output_audio_filename); + ffmpeg_command.args(["-i", &self.temp_output_audio_filename]); } ffmpeg_command.args([ "-c:a", "aac", &self.filename, - ]).overwrite() + ]).arg("-y") .spawn()? .wait()?; } else { // Validate audio file integrity let start_time = Instant::now(); - let duration = Duration::from_secs(60); + let duration = Duration::from_secs(300); loop { if is_valide(&self.temp_output_audio_filename)? { break; @@ -369,11 +414,11 @@ impl Ffmpeg { } } // If only output audio is recording then convert it to chosen format - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.format("ogg"); - ffmpeg_command.input(&self.temp_output_audio_filename); + let mut ffmpeg_command = Command::new("ffmpeg"); + ffmpeg_command.args(["-f", "ogg"]); + ffmpeg_command.args(["-i", &self.temp_output_audio_filename]); ffmpeg_command.arg(&self.filename) - .overwrite() + .arg("-y") .spawn()? .wait()?; } @@ -458,127 +503,131 @@ impl Ffmpeg { // Start video recording pub fn start_video(&mut self, x: u16, y: u16, width: u16, height: u16, mode: RecordMode) -> Result<()> { - //if mode == RecordMode::Window && !self.follow_mouse.is_active() { //REVIEW //TODO + if mode == RecordMode::Window && !self.follow_mouse.is_active() { // pulse = gstreamer for video && add to cmd linux + add convert function to gstreamer ouput - //} else {} - let display = format!("{}+{},{}", - std::env::var("DISPLAY").unwrap_or_else(|_| ":0".to_string()) - .as_str(), - x, - y - ); - let mut ffmpeg_command = FfmpegCommand::new(); - let format = "x11grab"; - self.height = Some(height); - let filename = self.saved_filename.clone(); - self.output = Path::new(&filename).extension() - .ok_or_else(|| anyhow!("Failed to get file extension."))? - .to_string_lossy().to_string(); + } else { + let display = format!("{}+{},{}", + std::env::var("DISPLAY").unwrap_or_else(|_| ":0".to_string()) + .as_str(), + x, + y + ); + let mut ffmpeg_command = FfmpegCommand::new(); + let format = "x11grab"; + self.height = Some(height); + let filename = self.saved_filename.clone(); + self.output = Path::new(&filename).extension() + .ok_or_else(|| anyhow!("Failed to get file extension."))? + .to_string_lossy().to_string(); - // Record video to tmp if audio record enabled - if !self.audio_input_id.active_id().ok_or_else(|| anyhow!("Failed to get audio input device ID."))? - .to_string().is_empty() - || !self.audio_output_id.is_empty() - || self.output == "gif" - { - let suffix = if self.output == "gif" { - ".mp4" + // Record video to tmp if audio record enabled + if self.output == "gif" { + let suffix = ".mp4"; + let video_tempfile = tempfile::Builder::new().prefix("ffmpeg-video-") + .suffix(suffix) + .tempfile()? + .keep()?; + self.temp_video_filename = Path::new(&video_tempfile.1).to_string_lossy() + .to_string(); + } + + // Record video with specified width and hight + if self.follow_mouse.is_active() { + match mode { + RecordMode::Screen => { + let width = width as f32 * 0.95; + let height = height as f32 * 0.95; + ffmpeg_command.size(width as u32, height as u32); + }, + _=> { + ffmpeg_command.size(width as u32, height as u32); + } + } } else { - &format!(".{}", &self.output) - }; - let video_tempfile = tempfile::Builder::new().prefix("ffmpeg-video-") - .suffix(suffix) - .tempfile()? - .keep()?; - self.temp_video_filename = Path::new(&video_tempfile.1).to_string_lossy() - .to_string(); - } + ffmpeg_command.size(width as u32, height as u32); + } - // Record video with specified width and hight - if self.follow_mouse.is_active() { - match mode { - RecordMode::Screen => { - let width = width as f32 * 0.95; - let height = height as f32 * 0.95; - ffmpeg_command.size(width as u32, height as u32); - }, - _=> { - ffmpeg_command.size(width.into(), height.into()); + // Show grabbed area + if self.show_area.is_active() { + ffmpeg_command.args(["-show_region", "1"]); + } + + // If show mouse switch is enabled, draw the mouse to video + if self.record_mouse.is_active() { + ffmpeg_command.args(["-draw_mouse", "1"]); + } else { + ffmpeg_command.args(["-draw_mouse", "0"]); + }; + + // Follow the mouse + if self.follow_mouse.is_active() { + ffmpeg_command.args(["-follow_mouse", "centered"]); + } + + // Disable frame rate if value is zero + if self.record_frames.value() as u16 > 0 { + ffmpeg_command.args(["-framerate", &self.record_frames.value().to_string()]); + } + + // Video format && input + ffmpeg_command.format(format) + .input(display); + + // Record audio input + if self.audio_input_switch.is_active() { + ffmpeg_command.format("pulse") + .input(&self.audio_input_id.active_id() + .ok_or_else(|| anyhow!("Failed to get audio input ID."))? + ); + } + + // Record audio output + if self.audio_output_switch.is_active() { + ffmpeg_command.format("pulse") + .input(&self.audio_output_id); + } + + // Disable video bitrate if value is zero + if self.video_record_bitrate.value() as u16 > 0 { + ffmpeg_command.args([ + "-b:v", + &format!("{}K", self.video_record_bitrate.value() as u16), + ]); + } + + // Disable audio bitrate if value is zero + if self.audio_input_switch.is_active() || self.audio_output_switch.is_active() { + if self.audio_record_bitrate.value() as u16 > 0 { + ffmpeg_command.args([ + "-b:a", + &format!("{}K", self.audio_record_bitrate.value() as u16), + ]); } } - } else { - ffmpeg_command.size(width.into(), height.into()); - } - // Show grabbed area - if self.show_area.is_active() { - ffmpeg_command.args(["-show_region", "1"]); - } + // Remove metadate + ffmpeg_command.args(["-map_metadata", "-1"]); - // If show mouse switch is enabled, draw the mouse to video - if self.record_mouse.is_active() { - ffmpeg_command.args(["-draw_mouse", "1"]); - } else { - ffmpeg_command.args(["-draw_mouse", "0"]); - }; - - // Follow the mouse - if self.follow_mouse.is_active() { - ffmpeg_command.args(["-follow_mouse", "centered"]); - } - - // Disable frame rate if value is zero - if self.record_frames.value() as u16 > 0 { - ffmpeg_command.args(["-framerate", &self.record_frames.value().to_string()]); - } - - // Video format && input - ffmpeg_command.format(format) - .input(display); - - // Disable bitrate if value is zero - if self.video_record_bitrate.value() as u16 > 0 { + // Output + let saved_filename = self.saved_filename.clone(); ffmpeg_command.args([ - "-b:v", - &format!("{}K", self.video_record_bitrate.value() as u16), - ]); - } - - // tmp file - if self.audio_input_id.active_id().ok_or_else(|| anyhow!("Failed to get audio input device ID."))? - .to_string().is_empty() && - self.audio_output_id.is_empty() && - self.output != "gif" - { - ffmpeg_command.args(["-hls_flags", "temp_file"]); - } - - // Remove metadate - ffmpeg_command.args(["-map_metadata", "-1"]); - - // Output - let saved_filename = self.saved_filename.clone(); - ffmpeg_command.args([ - { - if !self.audio_input_id.active_id() - .ok_or_else(|| anyhow!("Failed to get active audio input device ID."))? - .to_string().is_empty() - || !self.audio_output_id.is_empty() - || self.output == "gif" { - &self.temp_video_filename - } else { - &saved_filename - } - }, - ]); - ffmpeg_command.overwrite(); + if self.output == "gif" + { + &self.temp_video_filename + } else { + &saved_filename + } + }, + ]); + ffmpeg_command.overwrite(); - // Sleep for delay - sleep(Duration::from_secs(self.record_delay.value() as u64)); + // Sleep for delay + sleep(Duration::from_secs(self.record_delay.value() as u64)); - // Start recording and return the process id - self.video_process = Some(Rc::new(RefCell::new(ffmpeg_command.spawn()?))); + // Start recording and return the process id + self.video_process = Some(Rc::new(RefCell::new(ffmpeg_command.spawn()?))); + } Ok(()) } @@ -598,18 +647,18 @@ impl Ffmpeg { // Start audio input recording pub fn start_input_audio(&mut self) -> Result<()> { - let input_audio_tempfile = tempfile::Builder::new().prefix("ffmpeg-audio-") - .suffix(".ogg") - .tempfile()? - .keep()?; - self.temp_input_audio_filename = Path::new(&input_audio_tempfile.1).to_string_lossy() - .to_string(); let mut ffmpeg_command = FfmpegCommand::new(); ffmpeg_command.format("pulse") .input(&self.audio_input_id.active_id() .ok_or_else(|| anyhow!("Failed to get audio input ID."))? - ) - .format("ogg"); + ); + ffmpeg_command.format("ogg"); + if self.audio_output_switch.is_active() { + ffmpeg_command.format("pulse") + .input(&self.audio_output_id); + } + ffmpeg_command.format("ogg"); + // Disable bitrate if value is zero if self.audio_record_bitrate.value() as u16 > 0 { ffmpeg_command.args([ @@ -617,13 +666,16 @@ impl Ffmpeg { &format!("{}K", self.audio_record_bitrate.value() as u16), ]); } + // Remove metadate ffmpeg_command.args(["-map_metadata", "-1"]); - ffmpeg_command.arg(&self.temp_input_audio_filename); + + // Output + ffmpeg_command.arg(&self.saved_filename); ffmpeg_command.overwrite(); // Sleep for delay - if !is_video_record(&self.temp_video_filename) { + if !self.video_switch.is_active() { sleep(Duration::from_secs(self.record_delay.value() as u64)); } @@ -641,29 +693,25 @@ impl Ffmpeg { .ok_or_else(|| anyhow!("Not exiting the input audio recording process successfully."))? .borrow_mut() .quit()?; - } + } Ok(()) } // Start audio output recording pub fn start_output_audio(&mut self) -> Result<()> { - let output_audio_tempfile = tempfile::Builder::new().prefix("ffmpeg-audio-") - .suffix(".ogg") - .tempfile()? - .keep()?; - self.temp_output_audio_filename = Path::new(&output_audio_tempfile.1).to_string_lossy() - .to_string(); let mut ffmpeg_command = FfmpegCommand::new(); ffmpeg_command.format("pulse") .input(&self.audio_output_id) .format("ogg"); // Remove metadate ffmpeg_command.args(["-map_metadata", "-1"]); - ffmpeg_command.arg(&self.temp_output_audio_filename); + + // Output + ffmpeg_command.arg(&self.saved_filename); ffmpeg_command.overwrite(); // Sleep for delay - if !is_video_record(&self.temp_video_filename) && !is_input_audio_record(&self.temp_input_audio_filename) { + if !self.video_switch.is_active() && !self.audio_input_switch.is_active() { sleep(Duration::from_secs(self.record_delay.value() as u64)); } @@ -688,118 +736,34 @@ impl Ffmpeg { // Merge tmp to target format pub fn merge(&mut self) -> Result<()> { if is_video_record(&self.temp_video_filename) { - if self.output != "gif" { - // Validate video file integrity - let start_time = Instant::now(); - let duration = Duration::from_secs(60); - loop { - if is_valide(&self.temp_video_filename)? { - break; - } else if Instant::now().duration_since(start_time) >= duration { - return Err(Error::msg("Unable to validate tmp video file.")); - } - } - if is_input_audio_record(&self.temp_input_audio_filename) || - is_output_audio_record(&self.temp_output_audio_filename) { - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.input(&self.temp_video_filename); - ffmpeg_command.format("ogg"); - if is_input_audio_record(&self.temp_input_audio_filename) { - ffmpeg_command.input(&self.temp_input_audio_filename); - } - if is_output_audio_record(&self.temp_output_audio_filename) { - ffmpeg_command.input(&self.temp_output_audio_filename); - } - ffmpeg_command.args([ - "-c:a", - "aac", - &self.saved_filename.clone() - ]); - ffmpeg_command.overwrite() - .spawn()? - .wait()?; - } else { - std::fs::copy(&self.temp_video_filename, &self.saved_filename)?; - } - } else { - // Validate video file integrity - let start_time = Instant::now(); - let duration = Duration::from_secs(60); - loop { - if is_valide(&self.temp_video_filename)? { - break; - } else if Instant::now().duration_since(start_time) >= duration { - return Err(Error::msg("Unable to validate tmp video file.")); - } - } - // Convert MP4 to GIF - let filter = format!("fps={},scale={}:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse", - self.record_frames.value() as u16, - self.height.ok_or_else - (|| anyhow!("Unable to get height value"))?); - let ffmpeg_convert = format!("ffmpeg -i file:{} -filter_complex '{}' \ - -loop 0 {} -y", &self.temp_video_filename,filter, - &self.saved_filename - .clone()); - std::process::Command::new("sh").arg("-c").arg(&ffmpeg_convert).output()?; - } - } else if is_input_audio_record(&self.temp_input_audio_filename) { - // Validate audio file integrity + // Validate video file integrity let start_time = Instant::now(); - let duration = Duration::from_secs(60); + let duration = Duration::from_secs(300); loop { - if is_valide(&self.temp_input_audio_filename)? { + if is_valide(&self.temp_video_filename)? { break; } else if Instant::now().duration_since(start_time) >= duration { return Err(Error::msg("Unable to validate tmp video file.")); } } - // If only audio is recording then convert it to chosen format - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.format("ogg"); - ffmpeg_command.input(&self.temp_input_audio_filename); - if is_output_audio_record(&self.temp_output_audio_filename) { - ffmpeg_command.input(&self.temp_output_audio_filename); - } - ffmpeg_command.args([ - "-c:a", - "aac", - &self.saved_filename - .clone() - ]).overwrite() - .spawn()? - .wait()?; - } else { - // Validate audio file integrity - let start_time = Instant::now(); - let duration = Duration::from_secs(60); - loop { - if is_valide(&self.temp_output_audio_filename)? { - break; - } else if Instant::now().duration_since(start_time) >= duration { - return Err(Error::msg("Unable to validate tmp video file.")); - } - } - // If only output audio is recording then convert it to chosen format - let mut ffmpeg_command = FfmpegCommand::new(); - ffmpeg_command.format("ogg"); - ffmpeg_command.input(&self.temp_output_audio_filename); - ffmpeg_command.arg(&self.saved_filename - .clone()) - .overwrite() - .spawn()? - .wait()?; + // Convert MP4 to GIF + let filter = format!("fps={},scale={}:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse", + self.record_frames.value() as u16, + self.height.ok_or_else + (|| anyhow!("Unable to get height value"))?); + let ffmpeg_convert = format!("ffmpeg -i file:{} -filter_complex '{}' \ + -loop 0 {} -y", &self.temp_video_filename,filter, + &self.saved_filename + .clone()); + std::process::Command::new("sh").arg("-c").arg(&ffmpeg_convert).output()?; } Ok(()) } // Clean tmp pub fn clean(&mut self) -> Result<()> { - let tmp_files = vec![ &self.temp_input_audio_filename, &self.temp_output_audio_filename, &self.temp_video_filename ]; - for file in tmp_files { - if Path::new(file).try_exists()? { - std::fs::remove_file(file)?; - } + if Path::new(&self.temp_video_filename).try_exists()? { + std::fs::remove_file(&self.temp_video_filename)?; } Ok(()) } diff --git a/core/src/ffmpeg_windows.rs b/core/src/ffmpeg_windows.rs index 78f9712..0470159 100644 --- a/core/src/ffmpeg_windows.rs +++ b/core/src/ffmpeg_windows.rs @@ -37,12 +37,9 @@ pub struct Ffmpeg { pub record_delay: u16, pub record_frames: u16, pub video_record_bitrate: u16, - pub audio_input_switch: bool, - pub audio_output_switch: bool, pub follow_mouse: bool, pub record_mouse: bool, pub show_area: bool, - pub video_switch: bool, } #[cfg(feature = "gtk")] @@ -304,13 +301,13 @@ impl Ffmpeg { ffmpeg_command.args([ "-c:a", "aac", - &self.saved_filename.clone() + &self.filename ]); ffmpeg_command.overwrite() .spawn()? .wait()?; } else { - std::fs::copy(&self.temp_video_filename, &self.saved_filename)?; + std::fs::copy(&self.temp_video_filename, &self.filename)?; } } else { // Validate video file integrity diff --git a/core/src/utils.rs b/core/src/utils.rs index ea506e1..283c8da 100644 --- a/core/src/utils.rs +++ b/core/src/utils.rs @@ -2,7 +2,7 @@ use anyhow::Result; use std::process::Command; // Select recording mode -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum RecordMode { Area, Screen, diff --git a/gui/src/ui.rs b/gui/src/ui.rs index 33b0187..3ed078e 100644 --- a/gui/src/ui.rs +++ b/gui/src/ui.rs @@ -779,9 +779,12 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag record_delay: delay_spin.clone(), record_frames: frames_spin, video_record_bitrate: video_bitrate_spin, + audio_input_switch: audio_input_switch.clone(), + audio_output_switch: audio_output_switch.clone(), follow_mouse: follow_mouse_switch.clone(), record_mouse: mouse_switch.clone(), - show_area: area_switch + show_area: area_switch, + video_switch: video_switch.clone() })); #[cfg(any(target_os = "freebsd", target_os = "linux"))] let ffmpeg_record_interface: Rc> = Rc::new(RefCell::new(Ffmpeg { @@ -793,8 +796,6 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag format_chooser_combobox, ), output: String::new(), - temp_input_audio_filename: String::new(), - temp_output_audio_filename: String::new(), temp_video_filename: String::new(), saved_filename: String::new(), height: None, @@ -805,9 +806,12 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag record_delay: delay_spin.clone(), record_frames: frames_spin, video_record_bitrate: video_bitrate_spin, + audio_input_switch: audio_input_switch.clone(), + audio_output_switch: audio_output_switch.clone(), follow_mouse: follow_mouse_switch.clone(), record_mouse: mouse_switch.clone(), - show_area: area_switch + show_area: area_switch, + video_switch: video_switch.clone() })); // Record button @@ -817,7 +821,6 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag record_label.set_label(&get_bundle("record", None)); let _audio_input_switch = audio_input_switch.clone(); let _audio_output_switch = audio_output_switch.clone(); - //let bundle_msg = get_bundle("already-exist", None); let _delay_spin = delay_spin.clone(); let _delay_window = delay_window.clone(); let _delay_window_button = delay_window_button.clone(); @@ -903,7 +906,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag _play_button.hide(); _record_button.hide(); _stop_button.show(); - if _audio_input_switch.is_active() { + if _audio_input_switch.is_active() && !_video_switch.is_active() { match _ffmpeg_record_interface.borrow_mut().start_input_audio() { Ok(_) => { // Do nothing @@ -923,7 +926,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag }, } } - if _audio_output_switch.is_active() { + if _audio_output_switch.is_active() && !_audio_input_switch.is_active() && !_video_switch.is_active() { match _ffmpeg_record_interface.borrow_mut().start_output_audio() { Ok(_) => { // Do nothing @@ -991,7 +994,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag let mut show_play = true; _record_time_label.set_visible(false); stop_timer(_record_time_label.clone()); - if _audio_input_switch.is_active() { + if _audio_input_switch.is_active() && !_video_switch.is_active() { match _ffmpeg_record_interface.borrow_mut().stop_input_audio() { Ok(_) => { // Continue @@ -1012,7 +1015,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag }, } } - if _audio_output_switch.is_active() { + if _audio_output_switch.is_active() && !_audio_input_switch.is_active() && !_video_switch.is_active() { match _ffmpeg_record_interface.borrow_mut().stop_output_audio() { Ok(_) => { // Continue @@ -1054,19 +1057,6 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag }, } } - // Save tmp files - match _ffmpeg_record_interface.borrow_mut().merge() { - Ok(_) => { - // Continue - }, - Err(error) => { - show_play = false; - let text_buffer = TextBuffer::new(None); - text_buffer.set_text(&format!("{}", error)); - _error_message.set_buffer(Some(&text_buffer)); - _error_dialog.show(); - }, - }; if _video_switch.is_active() { _mouse_switch.set_sensitive(true); _follow_mouse_switch.set_sensitive(true); @@ -1078,17 +1068,6 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag _play_button.show(); } _record_button.show(); - match _ffmpeg_record_interface.borrow_mut().clean() { - Ok(_) => { - // Continue - }, - Err(error) => { - let text_buffer = TextBuffer::new(None); - text_buffer.set_text(&format!("{}", error)); - _error_message.set_buffer(Some(&text_buffer)); - _error_dialog.show(); - }, - }; }); // Delay window button