tauri-app: game review, with video showcase, stats and clip export
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
This commit is contained in:
345
tauri-app/src-tauri/Cargo.lock
generated
345
tauri-app/src-tauri/Cargo.lock
generated
@@ -47,6 +47,15 @@ version = "1.0.102"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arbitrary"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
||||||
|
dependencies = [
|
||||||
|
"derive_arbitrary",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-broadcast"
|
name = "async-broadcast"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@@ -670,6 +679,17 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_arbitrary"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.20"
|
version = "0.99.20"
|
||||||
@@ -716,11 +736,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "directories"
|
name = "directories"
|
||||||
version = "5.0.1"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-sys 0.4.1",
|
"dirs-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -729,19 +749,7 @@ version = "6.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-sys 0.5.0",
|
"dirs-sys",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dirs-sys"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"option-ext",
|
|
||||||
"redox_users 0.4.6",
|
|
||||||
"windows-sys 0.48.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -752,7 +760,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users 0.5.2",
|
"redox_users",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -963,6 +971,19 @@ dependencies = [
|
|||||||
"simd-adler32",
|
"simd-adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ffmpeg-sidecar"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f076483fb6efcf02e4abcf3e9388d30123346f85b9a96e8fe834718951b945ed"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"tar",
|
||||||
|
"ureq",
|
||||||
|
"xz2",
|
||||||
|
"zip",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "field-offset"
|
name = "field-offset"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@@ -973,6 +994,17 @@ dependencies = [
|
|||||||
"rustc_version",
|
"rustc_version",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filetime"
|
||||||
|
version = "0.2.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"libredox",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@@ -987,6 +1019,7 @@ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
|
"zlib-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1550,6 +1583,12 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-range"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
@@ -1973,7 +2012,10 @@ version = "0.1.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a"
|
checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags 2.11.0",
|
||||||
"libc",
|
"libc",
|
||||||
|
"plain",
|
||||||
|
"redox_syscall 0.7.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2003,6 +2045,17 @@ version = "0.4.29"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "mac"
|
name = "mac"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -2399,7 +2452,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall 0.5.18",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
@@ -2632,6 +2685,12 @@ version = "0.3.32"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plain"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "plist"
|
name = "plist"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
@@ -2907,14 +2966,12 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_syscall"
|
||||||
version = "0.4.6"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.17",
|
"bitflags 2.11.0",
|
||||||
"libredox",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3011,6 +3068,20 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.17.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"getrandom 0.2.17",
|
||||||
|
"libc",
|
||||||
|
"untrusted",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-hash"
|
name = "rustc-hash"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
@@ -3039,6 +3110,41 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.23.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-webpki",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pki-types"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
|
||||||
|
dependencies = [
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-webpki"
|
||||||
|
version = "0.103.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
@@ -3407,7 +3513,7 @@ dependencies = [
|
|||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
"objc2-quartz-core",
|
"objc2-quartz-core",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"redox_syscall",
|
"redox_syscall 0.5.18",
|
||||||
"tracing",
|
"tracing",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
@@ -3501,6 +3607,12 @@ version = "0.11.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swift-rs"
|
name = "swift-rs"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -3616,6 +3728,17 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tar"
|
||||||
|
version = "0.4.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973"
|
||||||
|
dependencies = [
|
||||||
|
"filetime",
|
||||||
|
"libc",
|
||||||
|
"xattr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.12.16"
|
version = "0.12.16"
|
||||||
@@ -3639,6 +3762,7 @@ dependencies = [
|
|||||||
"gtk",
|
"gtk",
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"http",
|
"http",
|
||||||
|
"http-range",
|
||||||
"jni",
|
"jni",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
@@ -3679,6 +3803,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"directories",
|
"directories",
|
||||||
|
"ffmpeg-sidecar",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
@@ -4322,6 +4447,41 @@ version = "0.2.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq"
|
||||||
|
version = "3.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"flate2",
|
||||||
|
"log",
|
||||||
|
"percent-encoding",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"ureq-proto",
|
||||||
|
"utf8-zero",
|
||||||
|
"webpki-roots",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq-proto"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.8"
|
version = "2.5.8"
|
||||||
@@ -4353,6 +4513,12 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-zero"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8_iter"
|
name = "utf8_iter"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -4624,6 +4790,15 @@ dependencies = [
|
|||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webview2-com"
|
name = "webview2-com"
|
||||||
version = "0.38.2"
|
version = "0.38.2"
|
||||||
@@ -4856,11 +5031,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4905,21 +5080,6 @@ dependencies = [
|
|||||||
"windows_x86_64_msvc 0.42.2",
|
"windows_x86_64_msvc 0.42.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.48.5",
|
|
||||||
"windows_aarch64_msvc 0.48.5",
|
|
||||||
"windows_i686_gnu 0.48.5",
|
|
||||||
"windows_i686_msvc 0.48.5",
|
|
||||||
"windows_x86_64_gnu 0.48.5",
|
|
||||||
"windows_x86_64_gnullvm 0.48.5",
|
|
||||||
"windows_x86_64_msvc 0.48.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -4977,12 +5137,6 @@ version = "0.42.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -5001,12 +5155,6 @@ version = "0.42.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -5025,12 +5173,6 @@ version = "0.42.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -5061,12 +5203,6 @@ version = "0.42.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -5085,12 +5221,6 @@ version = "0.42.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -5109,12 +5239,6 @@ version = "0.42.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -5133,12 +5257,6 @@ version = "0.42.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -5347,6 +5465,25 @@ dependencies = [
|
|||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xattr"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xz2"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
|
||||||
|
dependencies = [
|
||||||
|
"lzma-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -5472,6 +5609,12 @@ dependencies = [
|
|||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zeroize"
|
||||||
|
version = "1.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerotrie"
|
name = "zerotrie"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@@ -5505,12 +5648,44 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zip"
|
||||||
|
version = "4.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1"
|
||||||
|
dependencies = [
|
||||||
|
"arbitrary",
|
||||||
|
"crc32fast",
|
||||||
|
"flate2",
|
||||||
|
"indexmap 2.13.0",
|
||||||
|
"memchr",
|
||||||
|
"zopfli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zlib-rs"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zmij"
|
name = "zmij"
|
||||||
version = "1.0.21"
|
version = "1.0.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zopfli"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"crc32fast",
|
||||||
|
"log",
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zvariant"
|
name = "zvariant"
|
||||||
version = "5.10.0"
|
version = "5.10.0"
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ crate-type = ["staticlib", "cdylib", "rlib"]
|
|||||||
tauri-build = { version = "2", features = [] }
|
tauri-build = { version = "2", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "2", features = [] }
|
tauri = { version = "2", features = ["protocol-asset"] }
|
||||||
tauri-plugin-opener = "2"
|
tauri-plugin-opener = "2"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
uuid = { version = "1", features = ["v4", "serde"] }
|
uuid = { version = "1", features = ["v4", "serde"] }
|
||||||
directories = "5"
|
directories = "6"
|
||||||
|
ffmpeg-sidecar = "2.4"
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
use ffmpeg_sidecar::{
|
||||||
|
command::{ffmpeg_is_installed, FfmpegCommand},
|
||||||
|
download::auto_download,
|
||||||
|
event::{FfmpegEvent, LogLevel},
|
||||||
|
paths::sidecar_path,
|
||||||
|
};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -77,6 +83,312 @@ fn get_recordings_dir() -> String {
|
|||||||
.unwrap_or_else(|| "./recordings".to_string())
|
.unwrap_or_else(|| "./recordings".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find a video file in the recordings directory.
|
||||||
|
/// Searches for exact filename match or pattern match.
|
||||||
|
#[tauri::command]
|
||||||
|
fn find_video_file(recordings_dir: String, filename: String) -> Option<String> {
|
||||||
|
let recordings_path = PathBuf::from(&recordings_dir);
|
||||||
|
|
||||||
|
if !recordings_path.exists() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try exact match first
|
||||||
|
let exact_path = recordings_path.join(&filename);
|
||||||
|
if exact_path.exists() {
|
||||||
|
return Some(exact_path.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find by pattern (date_time_*.mp4)
|
||||||
|
if let Ok(entries) = fs::read_dir(&recordings_path) {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let path = entry.path();
|
||||||
|
if path.extension().map(|e| e == "mp4" || e == "mkv" || e == "mov").unwrap_or(false) {
|
||||||
|
let file_name = path.file_name()?.to_string_lossy().to_string();
|
||||||
|
|
||||||
|
// Check if filename starts with the same date/time pattern
|
||||||
|
// filename format: "2026-03-27_16-42-52_unknown.mp4"
|
||||||
|
// We match the date_time prefix
|
||||||
|
if file_name.starts_with(&filename.replace("_unknown.mp4", "")) {
|
||||||
|
return Some(path.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get list of video files in recordings directory.
|
||||||
|
#[tauri::command]
|
||||||
|
fn list_video_files(recordings_dir: String) -> Vec<String> {
|
||||||
|
let recordings_path = PathBuf::from(&recordings_dir);
|
||||||
|
let mut videos = Vec::new();
|
||||||
|
|
||||||
|
if !recordings_path.exists() {
|
||||||
|
return videos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(entries) = fs::read_dir(&recordings_path) {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let path = entry.path();
|
||||||
|
if path.extension().map(|e| e == "mp4" || e == "mkv" || e == "mov").unwrap_or(false) {
|
||||||
|
videos.push(path.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by modification time, newest first
|
||||||
|
videos.sort_by(|a, b| {
|
||||||
|
let a_time = fs::metadata(a).and_then(|m| m.modified()).ok();
|
||||||
|
let b_time = fs::metadata(b).and_then(|m| m.modified()).ok();
|
||||||
|
b_time.cmp(&a_time)
|
||||||
|
});
|
||||||
|
|
||||||
|
videos
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensure ffmpeg is available, downloading if necessary.
|
||||||
|
fn ensure_ffmpeg() -> Result<(), String> {
|
||||||
|
if ffmpeg_is_installed() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-download ffmpeg for the current platform
|
||||||
|
auto_download().map_err(|e| format!("Failed to download ffmpeg: {}", e))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Export a clip from a video using ffmpeg-sidecar (stream copy for speed).
|
||||||
|
#[tauri::command]
|
||||||
|
fn export_clip(
|
||||||
|
video_path: String,
|
||||||
|
start_time: f64,
|
||||||
|
end_time: f64,
|
||||||
|
output_name: String,
|
||||||
|
) -> Result<String, String> {
|
||||||
|
// Ensure ffmpeg is available
|
||||||
|
ensure_ffmpeg()?;
|
||||||
|
|
||||||
|
// Verify input file exists
|
||||||
|
if !PathBuf::from(&video_path).exists() {
|
||||||
|
return Err(format!("Video file not found: {}", video_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get output directory
|
||||||
|
let output_dir = get_default_output_dir()
|
||||||
|
.map(|p| p.join("clips"))
|
||||||
|
.unwrap_or_else(|| PathBuf::from("./clips"));
|
||||||
|
|
||||||
|
// Create clips directory if it doesn't exist
|
||||||
|
if !output_dir.exists() {
|
||||||
|
fs::create_dir_all(&output_dir)
|
||||||
|
.map_err(|e| format!("Failed to create clips directory: {}", e))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_path = output_dir.join(format!("{}.mp4", output_name));
|
||||||
|
let duration = end_time - start_time;
|
||||||
|
|
||||||
|
// Build ffmpeg command with stream copy (fast, no re-encoding)
|
||||||
|
// Note: Put -ss before -i for fast seeking (input seeking)
|
||||||
|
let iter = FfmpegCommand::new()
|
||||||
|
.arg("-y") // Overwrite output file
|
||||||
|
.arg("-ss").arg(&format!("{:.3}", start_time))
|
||||||
|
.arg("-i").arg(&video_path)
|
||||||
|
.arg("-t").arg(&format!("{:.3}", duration))
|
||||||
|
.arg("-c").arg("copy") // Stream copy for fast export
|
||||||
|
.arg("-avoid_negative_ts").arg("make_zero")
|
||||||
|
.arg(&output_path.to_string_lossy().to_string())
|
||||||
|
.spawn()
|
||||||
|
.map_err(|e| format!("Failed to spawn ffmpeg: {}", e))?
|
||||||
|
.iter()
|
||||||
|
.map_err(|e| format!("Failed to create ffmpeg iterator: {}", e))?;
|
||||||
|
|
||||||
|
// Process the ffmpeg command and collect all errors
|
||||||
|
let mut errors = Vec::new();
|
||||||
|
for event in iter {
|
||||||
|
match event {
|
||||||
|
FfmpegEvent::Error(e) => {
|
||||||
|
errors.push(format!("FFmpeg error: {}", e));
|
||||||
|
}
|
||||||
|
FfmpegEvent::Log(LogLevel::Error, msg) => {
|
||||||
|
errors.push(format!("FFmpeg log error: {}", msg));
|
||||||
|
}
|
||||||
|
FfmpegEvent::Log(LogLevel::Warning, msg) => {
|
||||||
|
// Log warnings but don't fail
|
||||||
|
eprintln!("FFmpeg warning: {}", msg);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if output file was created
|
||||||
|
if !output_path.exists() {
|
||||||
|
return Err(format!(
|
||||||
|
"Export failed - output file not created. Errors: {}",
|
||||||
|
errors.join("; ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if output file has content
|
||||||
|
let metadata = fs::metadata(&output_path)
|
||||||
|
.map_err(|e| format!("Failed to check output file: {}", e))?;
|
||||||
|
if metadata.len() == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"Export failed - output file is empty. Errors: {}",
|
||||||
|
errors.join("; ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(output_path.to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Export a clip with re-encoding for more precise cuts.
|
||||||
|
#[tauri::command]
|
||||||
|
fn export_clip_precise(
|
||||||
|
video_path: String,
|
||||||
|
start_time: f64,
|
||||||
|
end_time: f64,
|
||||||
|
output_name: String,
|
||||||
|
quality: String,
|
||||||
|
) -> Result<String, String> {
|
||||||
|
// Ensure ffmpeg is available
|
||||||
|
ensure_ffmpeg()?;
|
||||||
|
|
||||||
|
// Verify input file exists
|
||||||
|
if !PathBuf::from(&video_path).exists() {
|
||||||
|
return Err(format!("Video file not found: {}", video_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_dir = get_default_output_dir()
|
||||||
|
.map(|p| p.join("clips"))
|
||||||
|
.unwrap_or_else(|| PathBuf::from("./clips"));
|
||||||
|
|
||||||
|
if !output_dir.exists() {
|
||||||
|
fs::create_dir_all(&output_dir)
|
||||||
|
.map_err(|e| format!("Failed to create clips directory: {}", e))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_path = output_dir.join(format!("{}.mp4", output_name));
|
||||||
|
let duration = end_time - start_time;
|
||||||
|
|
||||||
|
// Quality presets (CRF values - lower is better quality)
|
||||||
|
let crf = match quality.as_str() {
|
||||||
|
"low" => "28",
|
||||||
|
"medium" => "23",
|
||||||
|
"high" => "18",
|
||||||
|
_ => "23",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build ffmpeg command with re-encoding
|
||||||
|
let iter = FfmpegCommand::new()
|
||||||
|
.arg("-y") // Overwrite output file
|
||||||
|
.arg("-ss").arg(&format!("{:.3}", start_time))
|
||||||
|
.arg("-i").arg(&video_path)
|
||||||
|
.arg("-t").arg(&format!("{:.3}", duration))
|
||||||
|
.arg("-c:v").arg("libx264")
|
||||||
|
.arg("-crf").arg(crf)
|
||||||
|
.arg("-preset").arg("fast")
|
||||||
|
.arg("-c:a").arg("aac")
|
||||||
|
.arg("-b:a").arg("128k")
|
||||||
|
.arg(&output_path.to_string_lossy().to_string())
|
||||||
|
.spawn()
|
||||||
|
.map_err(|e| format!("Failed to spawn ffmpeg: {}", e))?
|
||||||
|
.iter()
|
||||||
|
.map_err(|e| format!("Failed to create ffmpeg iterator: {}", e))?;
|
||||||
|
|
||||||
|
// Process the ffmpeg command and collect all errors
|
||||||
|
let mut errors = Vec::new();
|
||||||
|
for event in iter {
|
||||||
|
match event {
|
||||||
|
FfmpegEvent::Error(e) => {
|
||||||
|
errors.push(format!("FFmpeg error: {}", e));
|
||||||
|
}
|
||||||
|
FfmpegEvent::Log(LogLevel::Error, msg) => {
|
||||||
|
errors.push(format!("FFmpeg log error: {}", msg));
|
||||||
|
}
|
||||||
|
FfmpegEvent::Log(LogLevel::Warning, msg) => {
|
||||||
|
eprintln!("FFmpeg warning: {}", msg);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if output file was created
|
||||||
|
if !output_path.exists() {
|
||||||
|
return Err(format!(
|
||||||
|
"Export failed - output file not created. Errors: {}",
|
||||||
|
errors.join("; ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if output file has content
|
||||||
|
let metadata = fs::metadata(&output_path)
|
||||||
|
.map_err(|e| format!("Failed to check output file: {}", e))?;
|
||||||
|
if metadata.len() == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"Export failed - output file is empty. Errors: {}",
|
||||||
|
errors.join("; ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(output_path.to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if ffmpeg is available.
|
||||||
|
#[tauri::command]
|
||||||
|
fn check_ffmpeg() -> bool {
|
||||||
|
ffmpeg_is_installed()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Download ffmpeg if not already installed.
|
||||||
|
#[tauri::command]
|
||||||
|
fn download_ffmpeg() -> Result<String, String> {
|
||||||
|
ensure_ffmpeg()?;
|
||||||
|
Ok(sidecar_path().unwrap_or_default().to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get video file metadata using ffprobe.
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_video_metadata(video_path: String) -> Result<Value, String> {
|
||||||
|
// Ensure ffmpeg is available
|
||||||
|
ensure_ffmpeg()?;
|
||||||
|
|
||||||
|
// Use ffprobe via ffmpeg-sidecar
|
||||||
|
let iter = FfmpegCommand::new()
|
||||||
|
.arg("-v").arg("quiet")
|
||||||
|
.arg("-print_format").arg("json")
|
||||||
|
.arg("-show_format")
|
||||||
|
.arg("-show_streams")
|
||||||
|
.arg(&video_path)
|
||||||
|
.spawn()
|
||||||
|
.map_err(|e| format!("Failed to spawn ffprobe: {}", e))?
|
||||||
|
.iter()
|
||||||
|
.map_err(|e| format!("Failed to create ffprobe iterator: {}", e))?;
|
||||||
|
|
||||||
|
let mut json_output = String::new();
|
||||||
|
|
||||||
|
for event in iter {
|
||||||
|
match event {
|
||||||
|
FfmpegEvent::Log(LogLevel::Info, msg) | FfmpegEvent::Log(LogLevel::Unknown, msg) => {
|
||||||
|
// Capture JSON output
|
||||||
|
if msg.trim().starts_with('{') || msg.trim().starts_with('[') {
|
||||||
|
json_output.push_str(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FfmpegEvent::Error(e) => {
|
||||||
|
return Err(format!("FFprobe error: {}", e));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the JSON output
|
||||||
|
serde_json::from_str(&json_output)
|
||||||
|
.map_err(|e| format!("Failed to parse ffprobe output: {}", e))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
@@ -84,7 +396,14 @@ pub fn run() {
|
|||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
get_game_history,
|
get_game_history,
|
||||||
get_timeline,
|
get_timeline,
|
||||||
get_recordings_dir
|
get_recordings_dir,
|
||||||
|
find_video_file,
|
||||||
|
list_video_files,
|
||||||
|
export_clip,
|
||||||
|
export_clip_precise,
|
||||||
|
check_ffmpeg,
|
||||||
|
download_ffmpeg,
|
||||||
|
get_video_metadata
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
|
|||||||
@@ -12,13 +12,23 @@
|
|||||||
"app": {
|
"app": {
|
||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"title": "tauri-app",
|
"title": "League Recorder",
|
||||||
"width": 800,
|
"width": 1280,
|
||||||
"height": 600
|
"height": 800,
|
||||||
|
"minWidth": 800,
|
||||||
|
"minHeight": 600
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
"csp": null
|
"csp": null,
|
||||||
|
"assetProtocol": {
|
||||||
|
"enable": true,
|
||||||
|
"scope": [
|
||||||
|
"$APPDATA/**",
|
||||||
|
"$APPDATA/../**",
|
||||||
|
"C:/Users/**/AppData/Roaming/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
|
|||||||
@@ -1,9 +1,38 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
import GameHistory from "./components/GameHistory.vue";
|
import GameHistory from "./components/GameHistory.vue";
|
||||||
|
import GameReview from "./components/GameReview.vue";
|
||||||
|
import type { GameHistoryItem } from "./types/timeline";
|
||||||
|
|
||||||
|
// Current view state
|
||||||
|
const currentView = ref<"history" | "review">("history");
|
||||||
|
const selectedGame = ref<GameHistoryItem | null>(null);
|
||||||
|
|
||||||
|
// Navigate to review view
|
||||||
|
function openReview(game: GameHistoryItem) {
|
||||||
|
selectedGame.value = game;
|
||||||
|
currentView.value = "review";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate back to history
|
||||||
|
function closeReview() {
|
||||||
|
currentView.value = "history";
|
||||||
|
selectedGame.value = null;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<GameHistory />
|
<div class="app">
|
||||||
|
<GameHistory
|
||||||
|
v-if="currentView === 'history'"
|
||||||
|
@open-review="openReview"
|
||||||
|
/>
|
||||||
|
<GameReview
|
||||||
|
v-else-if="currentView === 'review' && selectedGame"
|
||||||
|
:game="selectedGame"
|
||||||
|
@back="closeReview"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -38,4 +67,9 @@ body {
|
|||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: rgba(255, 255, 255, 0.3);
|
background: rgba(255, 255, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #0a0a13;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import type { GameHistoryItem, TimestampedEvent, ItemInfo } from "../types/timeline";
|
import type { GameHistoryItem, TimestampedEvent, ItemInfo } from "../types/timeline";
|
||||||
|
|
||||||
|
// Emits
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "open-review", game: GameHistoryItem): void;
|
||||||
|
}>();
|
||||||
import {
|
import {
|
||||||
getGameResult,
|
getGameResult,
|
||||||
formatDuration,
|
formatDuration,
|
||||||
@@ -58,6 +63,11 @@ function closeDetail() {
|
|||||||
selectedGame.value = null;
|
selectedGame.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open review view for a game
|
||||||
|
function openReview(game: GameHistoryItem) {
|
||||||
|
emit("open-review", game);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper to get items array for display (6 slots + trinket)
|
// Helper to get items array for display (6 slots + trinket)
|
||||||
function getItemsArray(game: GameHistoryItem): (ItemInfo | null)[] {
|
function getItemsArray(game: GameHistoryItem): (ItemInfo | null)[] {
|
||||||
return getItems(game);
|
return getItems(game);
|
||||||
@@ -137,7 +147,7 @@ onMounted(() => {
|
|||||||
<img
|
<img
|
||||||
v-if="getSummonerSpells(game)"
|
v-if="getSummonerSpells(game)"
|
||||||
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell1Id)"
|
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell1Id)"
|
||||||
:alt="getSummonerSpells(game)!.spell1Name || 'Spell 1'"
|
alt="Spell 1"
|
||||||
class="spell-image"
|
class="spell-image"
|
||||||
/>
|
/>
|
||||||
<div v-else class="spell-placeholder"></div>
|
<div v-else class="spell-placeholder"></div>
|
||||||
@@ -146,7 +156,7 @@ onMounted(() => {
|
|||||||
<img
|
<img
|
||||||
v-if="getSummonerSpells(game)"
|
v-if="getSummonerSpells(game)"
|
||||||
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell2Id)"
|
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell2Id)"
|
||||||
:alt="getSummonerSpells(game)!.spell2Name || 'Spell 2'"
|
alt="Spell 2"
|
||||||
class="spell-image"
|
class="spell-image"
|
||||||
/>
|
/>
|
||||||
<div v-else class="spell-placeholder"></div>
|
<div v-else class="spell-placeholder"></div>
|
||||||
@@ -348,8 +358,8 @@ onMounted(() => {
|
|||||||
|
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button class="btn-secondary" @click="closeDetail">Close</button>
|
<button class="btn-secondary" @click="closeDetail">Close</button>
|
||||||
<button class="btn-primary">
|
<button class="btn-primary" @click="openReview(selectedGame)">
|
||||||
Open Video
|
Review Game
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
1671
tauri-app/src/components/GameReview.vue
Normal file
1671
tauri-app/src/components/GameReview.vue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user