diff --git a/Cargo.lock b/Cargo.lock index 6cb6068..a51ea09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,24 +308,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.6.0", - "cexpr", - "clang-sys", - "itertools", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -390,8 +372,6 @@ version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ - "jobserver", - "libc", "shlex", ] @@ -401,15 +381,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -422,17 +393,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.5.24" @@ -516,32 +476,25 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "coreaudio-rs" -version = "0.11.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" +checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17" dependencies = [ "bitflags 1.3.2", - "core-foundation-sys", - "coreaudio-sys", -] - -[[package]] -name = "coreaudio-sys" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce857aa0b77d77287acc1ac3e37a05a8c95a2af3647d23b15f263bdaeb7562b" -dependencies = [ - "bindgen", + "libc", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", ] [[package]] name = "cpal" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" +checksum = "cbd307f43cc2a697e2d1f8bc7a1d824b5269e052209e28883e5bc04d095aaa3f" dependencies = [ "alsa", - "core-foundation-sys", "coreaudio-rs", "dasp_sample", "jni", @@ -550,7 +503,11 @@ dependencies = [ "mach2", "ndk", "ndk-context", - "oboe", + "num-derive", + "num-traits", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -679,6 +636,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.6.0", + "objc2", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -711,12 +678,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c6ba7d4eec39eaa9ab24d44a0e73a7949a1095a8b3f3abb11eddf27dbb56a53" -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - [[package]] name = "encoding_rs" version = "0.8.35" @@ -790,6 +751,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "extended" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" + [[package]] name = "eyre" version = "0.6.12" @@ -993,12 +960,6 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - [[package]] name = "h2" version = "0.4.7" @@ -1335,15 +1296,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.14" @@ -1372,15 +1324,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" version = "0.3.76" @@ -1403,16 +1346,6 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "libloading" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - [[package]] name = "libredox" version = "0.1.3" @@ -1484,9 +1417,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "mach2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] @@ -1526,12 +1459,6 @@ 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.8.2" @@ -1585,9 +1512,9 @@ dependencies = [ [[package]] name = "ndk" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.6.0", "jni-sys", @@ -1605,9 +1532,9 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-sys" -version = "0.5.0+25.2.9519653" +version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ "jni-sys", ] @@ -1632,13 +1559,13 @@ dependencies = [ ] [[package]] -name = "nom" -version = "7.1.3" +name = "num-bigint" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "memchr", - "minimal-lexical", + "num-integer", + "num-traits", ] [[package]] @@ -1652,6 +1579,26 @@ dependencies = [ "syn", ] +[[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" @@ -1663,18 +1610,19 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1682,6 +1630,78 @@ dependencies = [ "syn", ] +[[package]] +name = "objc2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-audio-toolbox" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cbe18d879e20a4aea544f8befe38bcf52255eb63d3f23eca2842f3319e4c07" +dependencies = [ + "bitflags 2.6.0", + "libc", + "objc2", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-audio" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca44961e888e19313b808f23497073e3f6b3c22bb485056674c8b49f3b025c82" +dependencies = [ + "dispatch2", + "objc2", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-core-audio-types" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f1cc99bb07ad2ddb6527ddf83db6a15271bb036b3eb94b801cd44fdc666ee1" +dependencies = [ + "bitflags 2.6.0", + "objc2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags 2.6.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "objc2", +] + [[package]] name = "object" version = "0.36.7" @@ -1691,29 +1711,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "oboe" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" -dependencies = [ - "jni", - "ndk", - "ndk-context", - "num-derive", - "num-traits", - "oboe-sys", -] - -[[package]] -name = "oboe-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" -dependencies = [ - "cc", -] - [[package]] name = "once_cell" version = "1.20.2" @@ -2112,11 +2109,13 @@ dependencies = [ [[package]] name = "rodio" -version = "0.20.1" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1" +checksum = "e40ecf59e742e03336be6a3d53755e789fd05a059fa22dfa0ed624722319e183" dependencies = [ "cpal", + "dasp_sample", + "num-rational", "symphonia", ] @@ -2126,12 +2125,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustix" version = "0.38.42" @@ -2184,6 +2177,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + [[package]] name = "ryu" version = "1.0.18" @@ -2483,9 +2482,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9" dependencies = [ "lazy_static", + "symphonia-bundle-flac", "symphonia-bundle-mp3", + "symphonia-codec-aac", + "symphonia-codec-pcm", + "symphonia-codec-vorbis", + "symphonia-core", + "symphonia-format-isomp4", + "symphonia-format-ogg", + "symphonia-format-riff", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-bundle-flac" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97" +dependencies = [ + "log", "symphonia-core", "symphonia-metadata", + "symphonia-utils-xiph", ] [[package]] @@ -2500,6 +2518,38 @@ dependencies = [ "symphonia-metadata", ] +[[package]] +name = "symphonia-codec-aac" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbf25b545ad0d3ee3e891ea643ad115aff4ca92f6aec472086b957a58522f70" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-pcm" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f395a67057c2ebc5e84d7bb1be71cce1a7ba99f64e0f0f0e303a03f79116f89b" +dependencies = [ + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-vorbis" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a98765fb46a0a6732b007f7e2870c2129b6f78d87db7987e6533c8f164a9f30" +dependencies = [ + "log", + "symphonia-core", + "symphonia-utils-xiph", +] + [[package]] name = "symphonia-core" version = "0.5.4" @@ -2513,6 +2563,43 @@ dependencies = [ "log", ] +[[package]] +name = "symphonia-format-isomp4" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfdf178d697e50ce1e5d9b982ba1b94c47218e03ec35022d9f0e071a16dc844" +dependencies = [ + "encoding_rs", + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-ogg" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-riff" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f7be232f962f937f4b7115cbe62c330929345434c834359425e043bfd15f50" +dependencies = [ + "extended", + "log", + "symphonia-core", + "symphonia-metadata", +] + [[package]] name = "symphonia-metadata" version = "0.5.4" @@ -2525,6 +2612,16 @@ dependencies = [ "symphonia-core", ] +[[package]] +name = "symphonia-utils-xiph" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe" +dependencies = [ + "symphonia-core", + "symphonia-metadata", +] + [[package]] name = "syn" version = "2.0.95" @@ -3016,7 +3113,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a474669..9a66386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ repository = "https://github.com/talwat/lowfi" [features] mpris = ["dep:mpris-server"] +extra-audio-formats = ["rodio/default"] [dependencies] # Basics @@ -40,7 +41,7 @@ bytes = "1.9.0" # I/O crossterm = { version = "0.28.1", features = ["event-stream"] } -rodio = { version = "0.20.1", features = ["symphonia-mp3"], default-features = false } +rodio = { version = "0.21.1", features = ["symphonia-mp3", "playback"], default-features = false } mpris-server = { version = "0.8.1", optional = true } dirs = "5.0.1" diff --git a/src/main.rs b/src/main.rs index 1babc8a..e1fb2d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,15 +13,12 @@ mod player; mod tracks; #[allow(clippy::all, clippy::pedantic, clippy::nursery, clippy::restriction)] -mod scrape; +mod scrapers; /// An extremely simple lofi player. #[derive(Parser, Clone)] #[command(about, version)] -#[allow( - clippy::struct_excessive_bools, - reason = "seƱor clippy, i assure you this is not a state machine" -)] +#[allow(clippy::struct_excessive_bools)] struct Args { /// Use an alternate terminal screen. #[clap(long, short)] @@ -68,8 +65,11 @@ struct Args { /// Defines all of the extra commands lowfi can run. #[derive(Subcommand, Clone)] enum Commands { - /// Scrapes the lofi girl website file server for files. + /// Scrapes a music source for files. Scrape { + // The source to scrape from. + source: scrapers::Sources, + /// The file extension to search for, defaults to mp3. #[clap(long, short, default_value = "mp3")] extension: String, @@ -98,10 +98,12 @@ async fn main() -> eyre::Result<()> { if let Some(command) = cli.command { match command { + // TODO: Actually distinguish between sources. Commands::Scrape { + source, extension, include_full, - } => scrape::scrape(extension, include_full).await, + } => scrapers::lofigirl::scrape(extension, include_full).await, } } else { play::play(cli).await diff --git a/src/play.rs b/src/play.rs index fc2c31e..98b4903 100644 --- a/src/play.rs +++ b/src/play.rs @@ -67,11 +67,11 @@ impl PersistentVolume { let config = Self::config().await?; let path = config.join(PathBuf::from("volume.txt")); + // Already rounded & absolute, therefore this should be safe. #[expect( clippy::as_conversions, clippy::cast_sign_loss, - clippy::cast_possible_truncation, - reason = "already rounded & absolute, therefore this should be safe" + clippy::cast_possible_truncation )] let percentage = (volume * 100.0).abs().round() as u16; @@ -81,20 +81,6 @@ impl PersistentVolume { } } -/// Wrapper around [`rodio::OutputStream`] to implement [Send], currently unsafely. -/// -/// This is more of a temporary solution until cpal implements [Send] on it's output stream. -pub struct SendableOutputStream(pub rodio::OutputStream); - -// SAFETY: This is necessary because [OutputStream] does not implement [Send], -// due to some limitation with Android's Audio API. -// I'm pretty sure nobody will use lowfi with android, so this is safe. -#[expect( - clippy::non_send_fields_in_send_ty, - reason = "this is expected because of the nature of the struct" -)] -unsafe impl Send for SendableOutputStream {} - /// Initializes the audio server, and then safely stops /// it when the frontend quits. pub async fn play(args: Args) -> eyre::Result<()> { @@ -123,7 +109,7 @@ pub async fn play(args: Args) -> eyre::Result<()> { // Save the volume.txt file for the next session. PersistentVolume::save(player.sink.volume()).await?; - drop(stream.0); + drop(stream); player.sink.stop(); ui.and_then(|x| Some(x.abort())); diff --git a/src/player.rs b/src/player.rs index eb6549d..1fabd1e 100644 --- a/src/player.rs +++ b/src/player.rs @@ -14,7 +14,7 @@ use std::{ use arc_swap::ArcSwapOption; use downloader::Downloader; use reqwest::Client; -use rodio::{OutputStream, OutputStreamHandle, Sink}; +use rodio::{OutputStream, OutputStreamBuilder, Sink}; use tokio::{ select, sync::{ @@ -29,7 +29,7 @@ use mpris_server::{PlaybackStatus, PlayerInterface, Property}; use crate::{ messages::Messages, - play::{PersistentVolume, SendableOutputStream}, + play::PersistentVolume, tracks::{self, list::List}, Args, }; @@ -82,11 +82,6 @@ pub struct Player { /// The web client, which can contain a `UserAgent` & some /// settings that help lowfi work more effectively. client: Client, - - /// The [`OutputStreamHandle`], which also can control some - /// playback, is for now unused and is here just to keep it - /// alive so the playback can function properly. - _handle: OutputStreamHandle, } impl Player { @@ -108,7 +103,7 @@ impl Player { /// Initializes the entire player, including audio devices & sink. /// /// This also will load the track list & persistent volume. - pub async fn new(args: &Args) -> eyre::Result<(Self, SendableOutputStream)> { + pub async fn new(args: &Args) -> eyre::Result<(Self, OutputStream)> { // Load the volume file. let volume = PersistentVolume::load().await?; @@ -117,17 +112,15 @@ impl Player { // We should only shut up alsa forcefully on Linux if we really have to. #[cfg(target_os = "linux")] - let (stream, handle) = if !args.alternate && !args.debug { + let mut stream = if !args.alternate && !args.debug { audio::silent_get_output_stream()? } else { - OutputStream::try_default()? + OutputStreamBuilder::open_default_stream()? }; - // If we're not on Linux, then there's no problem. - #[cfg(not(target_os = "linux"))] - let (stream, handle) = OutputStream::try_default()?; + stream.log_on_drop(false); // Frankly, this is a stupid feature. Stop shoving your crap into my beloved stderr!!! + let sink = Sink::connect_new(stream.mixer()); - let sink = Sink::try_new(&handle)?; if args.paused { sink.pause(); } @@ -149,11 +142,10 @@ impl Player { sink, volume, list, - _handle: handle, bookmarked: AtomicBool::new(false), }; - Ok((player, SendableOutputStream(stream))) + Ok((player, stream)) } /// This is the main "audio server". diff --git a/src/player/audio.rs b/src/player/audio.rs index 5942b6c..81d62a4 100644 --- a/src/player/audio.rs +++ b/src/player/audio.rs @@ -1,11 +1,12 @@ #[cfg(target_os = "linux")] -use rodio::{OutputStream, OutputStreamHandle}; +use rodio::OutputStream; /// This gets the output stream while also shutting up alsa with [libc]. /// Uses raw libc calls, and therefore is functional only on Linux. #[cfg(target_os = "linux")] -pub fn silent_get_output_stream() -> eyre::Result<(OutputStream, OutputStreamHandle)> { +pub fn silent_get_output_stream() -> eyre::Result { use libc::freopen; + use rodio::OutputStreamBuilder; use std::ffi::CString; // Get the file descriptor to stderr from libc. @@ -28,7 +29,7 @@ pub fn silent_get_output_stream() -> eyre::Result<(OutputStream, OutputStreamHan } // Make the OutputStream while stderr is still redirected to /dev/null. - let (stream, handle) = OutputStream::try_default()?; + let stream = OutputStreamBuilder::open_default_stream()?; // Redirect back to the current terminal, so that other output isn't silenced. let tty = CString::new("/dev/tty")?; @@ -38,5 +39,5 @@ pub fn silent_get_output_stream() -> eyre::Result<(OutputStream, OutputStreamHan freopen(tty.as_ptr(), mode.as_ptr(), stderr); } - Ok((stream, handle)) + Ok(stream) } diff --git a/src/scrapers.rs b/src/scrapers.rs new file mode 100644 index 0000000..1729657 --- /dev/null +++ b/src/scrapers.rs @@ -0,0 +1,9 @@ +use clap::ValueEnum; + +pub mod lofigirl; + +#[derive(Clone, Copy, PartialEq, Eq, Debug, ValueEnum)] +pub enum Sources { + Lofigirl, + Chillhop, +} diff --git a/src/scrape.rs b/src/scrapers/lofigirl.rs similarity index 100% rename from src/scrape.rs rename to src/scrapers/lofigirl.rs diff --git a/src/tracks.rs b/src/tracks.rs index e0ffb0c..cca38b1 100644 --- a/src/tracks.rs +++ b/src/tracks.rs @@ -15,7 +15,7 @@ //! 2. [`Info`] created from decoded data. //! 3. [`Decoded`] made from [`Info`] and the original decoded data. -use std::{io::Cursor, time::Duration}; +use std::{io::Cursor, path::Path, time::Duration}; use bytes::Bytes; use inflector::Inflector as _; @@ -137,10 +137,13 @@ impl Info { /// This will also strip the first few numbers that are /// usually present on most lofi tracks. fn format_name(name: &str) -> eyre::Result { - let split = name.split('/').last().ok_or(TrackError::InvalidName)?; + let path = Path::new(name); - let stripped = split.strip_suffix(".mp3").unwrap_or(split); - let formatted = Self::decode_url(stripped) + let stem = path + .file_stem() + .and_then(|x| x.to_str()) + .ok_or(TrackError::InvalidName)?; + let formatted = Self::decode_url(stem) .to_lowercase() .to_title_case() // Inflector doesn't like contractions... diff --git a/src/tracks/list.rs b/src/tracks/list.rs index b41af93..8de291f 100644 --- a/src/tracks/list.rs +++ b/src/tracks/list.rs @@ -1,5 +1,5 @@ //! The module containing all of the logic behind track lists, -//! as well as obtaining track names & downloading the raw mp3 data. +//! as well as obtaining track names & downloading the raw audio data use bytes::Bytes; use eyre::OptionExt as _;