diff --git a/bun.lockb b/bun.lockb index f6ce846..773bc3c 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 5233ffc..1a59b8a 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,12 @@ "license": "MIT", "dependencies": { "@tauri-apps/api": "^2.0.0-beta.13", + "@tauri-apps/plugin-dialog": "^2.0.0-beta.5", "@tauri-apps/plugin-shell": "^2.0.0-beta.6", "@types/crypto-js": "^4.2.2", "crypto-js": "^4.2.0", "dayjs": "^1.11.11", + "jsonpath-plus": "^9.0.0", "svelte-sonner": "^0.3.24", "sveltekit-i18n": "^2.4.2" }, @@ -37,12 +39,12 @@ "prettier": "^3.3.2", "prettier-plugin-svelte": "^3.2.4", "prettier-plugin-tailwindcss": "^0.5.14", - "svelte": "^5.0.0-next.153", + "svelte": "^5.0.0-next.154", "svelte-check": "^3.8.0", "tailwindcss": "^3.4.4", "tslib": "^2.6.3", "typescript": "^5.4.5", "unplugin-icons": "^0.19.0", - "vite": "^5.2.13" + "vite": "^5.3.0" } } diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 0f9811c..71a16eb 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -26,6 +26,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -62,6 +68,46 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ashpd" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093" +dependencies = [ + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.8.5", + "serde", + "serde_repr", + "tokio", + "url", + "zbus", +] + [[package]] name = "async-broadcast" version = "0.7.1" @@ -241,11 +287,34 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + [[package]] name = "backtrace" -version = "0.3.72" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -268,6 +337,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -283,6 +358,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c12d1856e42f0d817a835fe55853957c85c8c8a470114029143d3f12671446e" + [[package]] name = "block" version = "0.1.6" @@ -341,6 +422,12 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "built" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" + [[package]] name = "bumpalo" version = "3.16.0" @@ -359,6 +446,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.6.0" @@ -440,6 +533,11 @@ name = "cc" version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] [[package]] name = "cesu8" @@ -525,6 +623,12 @@ dependencies = [ "objc", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "combine" version = "4.6.7" @@ -617,12 +721,37 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -889,6 +1018,12 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + [[package]] name = "embed-resource" version = "2.4.2" @@ -982,6 +1117,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -1026,6 +1177,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1331,6 +1491,16 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.29.0" @@ -1504,6 +1674,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1590,9 +1770,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3935c160d00ac752e09787e6e6bfc26494c2183cc922f1bc678a60d4733bc2" +checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545" [[package]] name = "hyper" @@ -1819,6 +1999,45 @@ dependencies = [ "utf8_iter", ] +[[package]] +name = "image" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +dependencies = [ + "byteorder-lite", + "thiserror", +] + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + [[package]] name = "indexmap" version = "1.9.3" @@ -1859,6 +2078,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -1884,6 +2114,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -1941,6 +2180,21 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.69" @@ -1991,6 +2245,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libappindicator" version = "0.9.0" @@ -2021,6 +2281,17 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2071,7 +2342,7 @@ checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "liveship" -version = "0.1.15" +version = "0.1.16" dependencies = [ "anyhow", "async-trait", @@ -2079,6 +2350,7 @@ dependencies = [ "dashmap", "dirs", "ffmpeg-sidecar", + "image", "once_cell", "redb", "reqwest", @@ -2088,6 +2360,7 @@ dependencies = [ "strum", "tauri", "tauri-build", + "tauri-plugin-dialog", "tauri-plugin-shell", "tauri-plugin-single-instance", "tokio", @@ -2124,6 +2397,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "mac" version = "0.1.1" @@ -2168,6 +2450,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.7.2" @@ -2198,6 +2490,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.3" @@ -2321,6 +2619,22 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2331,12 +2645,53 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2387,6 +2742,17 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + [[package]] name = "objc-sys" version = "0.3.5" @@ -2457,6 +2823,7 @@ checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.5.0", "block2", + "dispatch", "libc", "objc2", ] @@ -2506,9 +2873,9 @@ dependencies = [ [[package]] name = "object" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "memchr", ] @@ -2660,6 +3027,12 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pathdiff" version = "0.2.1" @@ -2974,6 +3347,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +dependencies = [ + "quote", + "syn 2.0.66", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.31.0" @@ -3073,6 +3480,56 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -3085,6 +3542,26 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redb" version = "2.1.1" @@ -3202,6 +3679,39 @@ dependencies = [ "winreg", ] +[[package]] +name = "rfd" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" +dependencies = [ + "ashpd", + "block", + "dispatch", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle 0.6.2", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + [[package]] name = "rustbus" version = "0.19.3" @@ -3592,6 +4102,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "siphasher" version = "0.3.11" @@ -3625,9 +4144,9 @@ dependencies = [ [[package]] name = "softbuffer" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d09e57a5a6b300bf917329da0ff30a58737d83abb7b14f99a419c23e83007cb8" +checksum = "2ae0d2e93c874cca74fe830bccbd1132299318932d273d2a3c77ad77476a3d7e" dependencies = [ "bytemuck", "cfg_aliases", @@ -3673,6 +4192,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3834,9 +4362,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12a8121bd5721ebbbe0889f8286d5824673beeb04071519b68916fbed04f3093" +checksum = "ea538df05fbc2dcbbd740ba0cfe8607688535f4798d213cbbfa13ce494f3451f" dependencies = [ "bitflags 2.5.0", "cocoa", @@ -3865,8 +4393,8 @@ dependencies = [ "tao-macros", "unicode-segmentation", "url", - "windows 0.56.0", - "windows-core 0.56.0", + "windows 0.57.0", + "windows-core 0.57.0", "windows-version", "x11-dl", ] @@ -4017,6 +4545,43 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-dialog" +version = "2.0.0-beta.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed4b22c59f7b04ae2a0bed8241aa715b41973c3f042c84aa67a1f4dc0174a8d" +dependencies = [ + "dunce", + "log", + "raw-window-handle 0.6.2", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror", +] + +[[package]] +name = "tauri-plugin-fs" +version = "2.0.0-beta.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3aa91955751f329e0aa431b87c199b7378b6f91ec0765d2ad9d4c64e017c3cda" +dependencies = [ + "anyhow", + "glob", + "schemars", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "thiserror", + "url", + "uuid", +] + [[package]] name = "tauri-plugin-shell" version = "2.0.0-beta.7" @@ -4199,6 +4764,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.36" @@ -4252,8 +4828,10 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", + "signal-hook-registry", "socket2", "tokio-macros", + "tracing", "windows-sys 0.48.0", ] @@ -4592,6 +5170,17 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.0" @@ -4821,8 +5410,8 @@ dependencies = [ "webview2-com-sys", "windows 0.56.0", "windows-core 0.56.0", - "windows-implement", - "windows-interface", + "windows-implement 0.56.0", + "windows-interface 0.56.0", ] [[package]] @@ -4847,6 +5436,12 @@ dependencies = [ "windows-core 0.56.0", ] +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "winapi" version = "0.3.9" @@ -4920,6 +5515,16 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.5", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -4935,8 +5540,20 @@ version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.56.0", + "windows-interface 0.56.0", + "windows-result", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement 0.57.0", + "windows-interface 0.57.0", "windows-result", "windows-targets 0.52.5", ] @@ -4952,6 +5569,17 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "windows-interface" version = "0.56.0" @@ -4963,6 +5591,17 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -5344,6 +5983,7 @@ dependencies = [ "serde_repr", "sha1", "static_assertions", + "tokio", "tracing", "uds_windows", "windows-sys 0.52.0", @@ -5421,6 +6061,30 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +dependencies = [ + "zune-core", +] + [[package]] name = "zvariant" version = "4.0.0" @@ -5431,6 +6095,7 @@ dependencies = [ "enumflags2", "serde", "static_assertions", + "url", "zvariant_derive", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 291ba36..171dc80 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "liveship" -version = "0.1.15" +version = "0.1.16" description = "liveship 是一个直播录制工具,目前已支持抖音、虎牙、小红书、tiktok、twitch" authors = ["jlvihv"] email = "imvihv@gmail.com" @@ -18,6 +18,7 @@ tauri-build = { version = "2.0.0-beta", features = [] } [dependencies] tauri = { version = "2.0.0-beta", features = [] } tauri-plugin-shell = "2.0.0-beta" +tauri-plugin-dialog = "2.0.0-beta.9" tauri-plugin-single-instance = "2.0.0-beta" serde = { version = "1", features = ["derive"] } serde_json = "1" @@ -30,9 +31,10 @@ once_cell = "1" redb = "2.1" reqwest = "0.12" strum = { version = "0.26", features = ["derive"] } -tokio = { version = "1.37", features = ["rt-multi-thread", "macros"] } +tokio = { version = "1.38", features = ["rt-multi-thread", "macros"] } showfile = "0.1" ffmpeg-sidecar = "1.1" +image = "0.25" [profile.release] strip = true diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index e14ca1d..61e72a9 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -1,17 +1,19 @@ { - "$schema": "../gen/schemas/desktop-schema.json", - "identifier": "default", - "description": "Capability for the main window", - "windows": ["main"], - "permissions": [ - "path:default", - "event:default", - "window:default", - "app:default", - "image:default", - "resources:default", - "menu:default", - "tray:default", - "shell:allow-open" - ] + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + "path:default", + "event:default", + "window:default", + "app:default", + "image:default", + "resources:default", + "menu:default", + "tray:default", + "shell:allow-open", + "dialog:default", + "dialog:allow-open" + ] } diff --git a/src-tauri/src/ffmpeg.rs b/src-tauri/src/ffmpeg.rs index b40158c..8e73a21 100644 --- a/src-tauri/src/ffmpeg.rs +++ b/src-tauri/src/ffmpeg.rs @@ -5,6 +5,55 @@ use std::process::{Child, Stdio}; use crate::config::config_dir; +/// 给定 ffmpeg 命令,这里只负责执行 +pub fn execute_ffmpeg_command(ffmpeg_command: Vec) -> Result { + println!("ffmpeg_command: {:?}", ffmpeg_command); + // 调用 ffmpeg 命令 + let mut cmd = std::process::Command::new("ffmpeg"); + // 特定于 windows 的实现,使用 CommandExt,避免出现黑窗口 + #[cfg(target_os = "windows")] + { + use std::os::windows::process::CommandExt; + cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW + } + // cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); + cmd.args(&ffmpeg_command); + let mut child = cmd.spawn()?; + // 立刻 try_wait 一下,看是否有错误 + if let Some(status) = child.try_wait()? { + let output = child.wait_with_output()?; + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + let error_message = format!( + "status: {:?}\nstdout: {}\nstderr: {}", + status, stdout, stderr + ); + return Err(anyhow::anyhow!(error_message)); + } + println!("录制进程启动:{:?}", child.id()); + Ok(child) +} + +/// 给定 ffmpeg 命令,执行并返回输出 +pub fn execute_ffmpeg_command_return_output(ffmpeg_command: Vec) -> Result { + println!("ffmpeg_command: {:?}", ffmpeg_command); + // 调用 ffmpeg 命令 + let output = std::process::Command::new("ffmpeg") + .args(&ffmpeg_command) + .output()?; + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + if !output.status.success() { + return Err(anyhow::anyhow!( + "status: {:?}\nstdout: {}\nstderr: {}", + output.status, + stdout, + stderr + )); + } + Ok(stdout.to_string()) +} + pub fn record(ffmpeg_path: &str, url: &str, filename: &str) -> Result { println!("开始录制:{} -> {}", url, filename); @@ -17,7 +66,7 @@ pub fn record(ffmpeg_path: &str, url: &str, filename: &str) -> Result { cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW } cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); - let ffmpeg_command = build_ffmpeg_command(url, filename); + let ffmpeg_command = build_ffmpeg_record_command(url, filename); cmd.args(&ffmpeg_command); let mut child = cmd.spawn()?; // 立刻 try_wait 一下,看是否有错误 @@ -40,7 +89,7 @@ pub fn record(ffmpeg_path: &str, url: &str, filename: &str) -> Result { Ok(child) } -fn build_ffmpeg_command(url: &str, filename: &str) -> Vec { +fn build_ffmpeg_record_command(url: &str, filename: &str) -> Vec { let user_agent = r#""Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36""#; let analyzeduration = "20000000"; let probesize = "10000000"; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5e5d139..30a3ce2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -5,6 +5,7 @@ mod config; mod ffmpeg; pub mod kv; mod manager; +mod media; mod model; mod request; mod utils; @@ -12,6 +13,7 @@ mod utils; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() + .plugin(tauri_plugin_dialog::init()) .setup(|app| { let main_window = app.get_webview_window("main").unwrap(); main_window.on_window_event(|event| match event { @@ -47,6 +49,9 @@ pub fn run() { manager::ffmpeg_api::check_ffmpeg_version, manager::ffmpeg_api::check_ffmpeg_availability, manager::ffmpeg_api::download_ffmpeg, + manager::ffmpeg_api::execute_ffmpeg_command, + manager::ffmpeg_api::execute_ffmpeg_command_return_output, + manager::ffmpeg_api::get_image_info, manager::request_api::request, manager::request_api::try_request_get_status, manager::request_api::request_post, diff --git a/src-tauri/src/manager.rs b/src-tauri/src/manager.rs index 227077b..5c054c0 100644 --- a/src-tauri/src/manager.rs +++ b/src-tauri/src/manager.rs @@ -348,6 +348,8 @@ pub mod config { } pub mod ffmpeg_api { + use crate::media::{self, MediaInfo}; + use super::*; /// 检查 ffmpeg @@ -377,6 +379,29 @@ pub mod ffmpeg_api { kv::config::set(&config).map_err(|e| format!("Could not set config: {}", e))?; Ok(path) } + + /// 执行 ffmpeg 命令 + #[tauri::command] + pub async fn execute_ffmpeg_command(ffmpeg_command: Vec) -> Result<(), String> { + ffmpeg::execute_ffmpeg_command(ffmpeg_command) + .map_err(|e| format!("Could not run ffmpeg command: {}", e))?; + Ok(()) + } + + #[tauri::command] + pub async fn execute_ffmpeg_command_return_output( + ffmpeg_command: Vec, + ) -> Result { + let output = ffmpeg::execute_ffmpeg_command_return_output(ffmpeg_command) + .map_err(|e| format!("Could not run ffmpeg command: {}", e))?; + Ok(output) + } + + #[tauri::command] + pub async fn get_image_info(file_path: String) -> Result { + let info = media::get_image_info(&file_path)?; + Ok(info) + } } pub mod request_api { diff --git a/src-tauri/src/media.rs b/src-tauri/src/media.rs new file mode 100644 index 0000000..460c731 --- /dev/null +++ b/src-tauri/src/media.rs @@ -0,0 +1,29 @@ +use std::path::Path; + +use image::GenericImageView; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MediaInfo { + path: String, + media_type: String, + width: u32, + height: u32, + fps: Option, + bitrate: Option, +} + +pub fn get_image_info(file_path: &str) -> Result { + let img = image::open(&Path::new(file_path)).map_err(|e| e.to_string())?; + let dimensions = img.dimensions(); + + Ok(MediaInfo { + path: file_path.to_string(), + media_type: "image".to_string(), + width: dimensions.0, + height: dimensions.1, + fps: None, + bitrate: None, + }) +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4f62971..f848c4b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "productName": "liveship", - "version": "0.1.15", + "version": "0.1.16", "identifier": "app.happyship.liveship", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/lib/backstage.ts b/src/lib/backstage.ts index 7423739..1d9661b 100644 --- a/src/lib/backstage.ts +++ b/src/lib/backstage.ts @@ -3,10 +3,12 @@ import { LiveStatus, type RecordingPlan } from './model'; import { getLiveInfoForPlatform } from './utils'; export function checkPlanLoop() { - // 每 60 秒检查一次计划 + // 进入时立刻检查一次计划 + checkPlans(); + // 然后每 60 秒检查一次 setInterval(() => { checkPlans(); - }, 6000); + }, 60000); } function checkPlans() { diff --git a/src/lib/components/button.svelte b/src/lib/components/button.svelte index 594b36f..a74b3cc 100644 --- a/src/lib/components/button.svelte +++ b/src/lib/components/button.svelte @@ -1,10 +1,25 @@ - - - - - - - - - - - -
-
- -
- {#if errorMessage || liveInfo || requesting} -
- -
- {/if} - -
- {#if isFirst} -
-

{$t('tips')}

-
- {/if} - {#if requesting} -
- -
- {/if} - {#if liveInfo} -
-
- {#if liveInfo.status !== LiveStatus.NotLive} -
-

- {liveInfo.title} - {#if recordStatus === RecordingStatus.Recording} - {$t('recording')} - {/if} -

-
- -
-
-
- {liveInfo.anchorName} -
-
-
- {liveInfo.anchorName} -
- {#if liveInfo.status === LiveStatus.Live} -

{$t('living')}

- {:else} -

{$t('notLiving')}

- {/if} -

- {liveInfo.viewerCount ? liveInfo.viewerCount + $t('watching') : ''} -

-
-
-
-
-
- - {#if recordStatus !== RecordingStatus.Recording} - - - {:else} - - - {/if} -
-
-
- {#if loading} -
- -
- {:else if recordStatus === RecordingStatus.Recording} -
- -
- {:else} -
- -
- {/if} -
- {:else} -
-
{$t('anchor')} {liveInfo.anchorName} {$t('notInLive')}
- {#if liveInfo.platformKind == PlatformKind.Huya} -
{$t('forHuyaError')}
- {/if} - -
- {/if} -
-
- {/if} - {#if errorMessage} -
{errorMessage}
- {#if refreshCount >= 5} - - {/if} - {/if} -
-
- - diff --git a/src/lib/components/sidebar.svelte b/src/lib/components/sidebar.svelte index 2e00274..8f510e0 100644 --- a/src/lib/components/sidebar.svelte +++ b/src/lib/components/sidebar.svelte @@ -1,42 +1,47 @@