Redo metadata -> song pipeline
Following the rejection of https://github.com/RustAudio/rodio/pull/410
This commit is contained in:
parent
b97ae618b0
commit
746715be39
|
@ -1,7 +1,3 @@
|
||||||
[submodule "rodio"]
|
|
||||||
path = rodio
|
|
||||||
url = https://github.com/Alch-Emi/rodio.git
|
|
||||||
branch = new-from-format-reader
|
|
||||||
[submodule "iced"]
|
[submodule "iced"]
|
||||||
path = iced
|
path = iced
|
||||||
url = https://github.com/Alch-Emi/iced.git
|
url = https://github.com/Alch-Emi/iced.git
|
||||||
|
|
|
@ -96,12 +96,6 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "269d0f5e68353a7cab87f81e7c736adc008d279a36ebc6a05dfe01193a89f0c9"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
|
@ -2693,7 +2687,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rodio"
|
name = "rodio"
|
||||||
version = "0.14.0"
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0939e9f626e6c6f1989adb6226a039c855ca483053f0ee7c98b90e41cf731e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cpal",
|
"cpal",
|
||||||
"symphonia",
|
"symphonia",
|
||||||
|
@ -2970,15 +2966,16 @@ checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia"
|
name = "symphonia"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fae959d5ea7b4cd0cd8db3b899ec4f549b0d8a298694826a36ae7e5f19d4aa6"
|
checksum = "a7e5f38aa07e792f4eebb0faa93cee088ec82c48222dd332897aae1569d9a4b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"symphonia-bundle-flac",
|
"symphonia-bundle-flac",
|
||||||
"symphonia-bundle-mp3",
|
"symphonia-bundle-mp3",
|
||||||
"symphonia-codec-aac",
|
"symphonia-codec-aac",
|
||||||
"symphonia-codec-pcm",
|
"symphonia-codec-pcm",
|
||||||
|
"symphonia-codec-vorbis",
|
||||||
"symphonia-core",
|
"symphonia-core",
|
||||||
"symphonia-format-isomp4",
|
"symphonia-format-isomp4",
|
||||||
"symphonia-format-ogg",
|
"symphonia-format-ogg",
|
||||||
|
@ -2988,9 +2985,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-bundle-flac"
|
name = "symphonia-bundle-flac"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b237be42d0ff1ff64c6e073aea4f93985ca51de93b8279f16a4b006e3e5997af"
|
checksum = "116e5412f5fb4e5d07efd6628d50d6fcd7a61ebef43d98f5012f3cf763b25d02"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"symphonia-core",
|
"symphonia-core",
|
||||||
|
@ -3000,9 +2997,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-bundle-mp3"
|
name = "symphonia-bundle-mp3"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9f596fe16d2ae06e9404558644b61e27e2dcfee6c511f559be4699c403283fa"
|
checksum = "ec4d97c4a61ece4651751dddb393ebecb7579169d9e758ae808fe507a5250790"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -3013,9 +3010,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-codec-aac"
|
name = "symphonia-codec-aac"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e636422dccfb202b24f8066b8d3ebfa914bbc690dae78db52b54691ba916c3f"
|
checksum = "bd3d7ab37eb9b7df16ddedd7adb7cc382afe708ff078e525a14dc9b05e57558f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
|
@ -3024,32 +3021,43 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-codec-pcm"
|
name = "symphonia-codec-pcm"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "021d8161b186bea81c7cf4a80c67c71fb53862cd9f426cd3e032ae09bdd42dec"
|
checksum = "ba1d54738758993546107e3a4be2c1da827f2d4489fcffee0fa47867254e44c7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"symphonia-core",
|
"symphonia-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-core"
|
name = "symphonia-codec-vorbis"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1742e06f50b4a7ed7abee53433231e050a248b498cd0ae2c639c8a70b115001"
|
checksum = "a29ed6748078effb35a05064a451493a78038918981dc1a76bdf5a2752d441fa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.6.1",
|
"log",
|
||||||
|
"symphonia-core",
|
||||||
|
"symphonia-utils-xiph",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "symphonia-core"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa135e97be0f4a666c31dfe5ef4c75435ba3d355fd6a73d2100aa79b14c104c9"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec 0.7.2",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"bytemuck",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-format-isomp4"
|
name = "symphonia-format-isomp4"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf3c6b6ca3347caa22d72f04cfd509f0c32683b0dbe01d0cfb63fd2726ac6da5"
|
checksum = "feee3a7711e7ec1b7540756f3868bbb3cbb0d1195569b9bc26471a24a02f57b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"log",
|
"log",
|
||||||
|
@ -3059,9 +3067,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-format-ogg"
|
name = "symphonia-format-ogg"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4898eef85c5a05136e1f3b5ff1afe4423cd7642c8979ed007cc8924b9a4c18c1"
|
checksum = "d7b2357288a79adfec532cfd86049696cfa5c58efeff83bd51687a528f18a519"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"symphonia-core",
|
"symphonia-core",
|
||||||
|
@ -3071,9 +3079,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-format-wav"
|
name = "symphonia-format-wav"
|
||||||
version = "0.3.0"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97e863d9a912ea518dfae664292e38b2b961a1eb780251eba89b60e3905fef37"
|
checksum = "6d9fa5e5b420dea6763ba2547887eb1a02a142c676c5b02ed1b113a247101dad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"symphonia-core",
|
"symphonia-core",
|
||||||
|
@ -3082,9 +3090,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-metadata"
|
name = "symphonia-metadata"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db5e36e38a7400f968569135e7ac0f8647de42e93905ad41c79d583aaeae565c"
|
checksum = "5260599daba18d8fe905ca3eb3b42ba210529a6276886632412cc74984e79b1a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -3094,9 +3102,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-utils-xiph"
|
name = "symphonia-utils-xiph"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "47377d86d61acf4d5b1a054b8e7a7cac8266155577a5410e4d746aec6394c42a"
|
checksum = "6a37026c6948ff842e0bf94b4008579cc71ab16ed0ff9ca70a331f60f4f1e1e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"symphonia-core",
|
"symphonia-core",
|
||||||
"symphonia-metadata",
|
"symphonia-metadata",
|
||||||
|
|
|
@ -26,7 +26,7 @@ blocking = "1.1.0"
|
||||||
[dependencies.symphonia]
|
[dependencies.symphonia]
|
||||||
# Music decoding and metadata parsing
|
# Music decoding and metadata parsing
|
||||||
features = ["isomp4", "aac", "mp3"]
|
features = ["isomp4", "aac", "mp3"]
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
|
|
||||||
[dependencies.iced]
|
[dependencies.iced]
|
||||||
# Display windows & graphics
|
# Display windows & graphics
|
||||||
|
@ -50,4 +50,4 @@ path = "./iced/futures"
|
||||||
# Playing audio
|
# Playing audio
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["symphonia-all"]
|
features = ["symphonia-all"]
|
||||||
path = "./rodio/"
|
version = "0.15"
|
||||||
|
|
1
rodio
1
rodio
|
@ -1 +0,0 @@
|
||||||
Subproject commit 706abafcadab2c0049d7a7724cae43f203ba0f67
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
use std::fs::File;
|
||||||
use iced::Command;
|
use iced::Command;
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use iced::Length;
|
use iced::Length;
|
||||||
use iced::Color;
|
use iced::Color;
|
||||||
use iced::Point;
|
use iced::Point;
|
||||||
use symphonia::core::formats::FormatReader;
|
|
||||||
use crate::player::PlayerError;
|
use crate::player::PlayerError;
|
||||||
use iced::canvas::event::Status;
|
use iced::canvas::event::Status;
|
||||||
use iced::canvas::Event;
|
use iced::canvas::Event;
|
||||||
|
@ -39,7 +39,7 @@ use ErrorState::*;
|
||||||
pub struct Controls(pub ErrorState);
|
pub struct Controls(pub ErrorState);
|
||||||
|
|
||||||
impl Controls {
|
impl Controls {
|
||||||
pub fn new(song: Box<dyn FormatReader>) -> (Self, Command<Message>) {
|
pub fn new(song: File) -> (Self, Command<Message>) {
|
||||||
match Player::new(song) {
|
match Player::new(song) {
|
||||||
Ok(player) => {
|
Ok(player) => {
|
||||||
let duration_task = unblock(player.compute_duration());
|
let duration_task = unblock(player.compute_duration());
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fs::File;
|
||||||
use image::DynamicImage;
|
use image::DynamicImage;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
|
@ -11,7 +12,7 @@ use symphonia::core::probe::{Hint, ProbeResult};
|
||||||
use symphonia::core::meta::StandardVisualKey;
|
use symphonia::core::meta::StandardVisualKey;
|
||||||
use symphonia::core::formats::FormatReader;
|
use symphonia::core::formats::FormatReader;
|
||||||
|
|
||||||
pub fn load_song(path: &Path) -> Result<ProbeResult, LoadError> {
|
pub fn load_song(path: &Path) -> Result<(File, ProbeResult), LoadError> {
|
||||||
let probe = default::get_probe();
|
let probe = default::get_probe();
|
||||||
|
|
||||||
let file = OpenOptions::new()
|
let file = OpenOptions::new()
|
||||||
|
@ -19,7 +20,13 @@ pub fn load_song(path: &Path) -> Result<ProbeResult, LoadError> {
|
||||||
.write(false)
|
.write(false)
|
||||||
.open(path)
|
.open(path)
|
||||||
.map_err(LoadError::OpenError)?;
|
.map_err(LoadError::OpenError)?;
|
||||||
let media_source_stream = MediaSourceStream::new(Box::new(file), Default::default());
|
let media_source_stream = MediaSourceStream::new(
|
||||||
|
Box::new(
|
||||||
|
file.try_clone()
|
||||||
|
.map_err(LoadError::OpenError)?
|
||||||
|
),
|
||||||
|
Default::default()
|
||||||
|
);
|
||||||
|
|
||||||
let ext_hint = path.extension()
|
let ext_hint = path.extension()
|
||||||
.and_then(OsStr::to_str)
|
.and_then(OsStr::to_str)
|
||||||
|
@ -36,6 +43,7 @@ pub fn load_song(path: &Path) -> Result<ProbeResult, LoadError> {
|
||||||
&Default::default(),
|
&Default::default(),
|
||||||
&Default::default(),
|
&Default::default(),
|
||||||
).map_err(LoadError::SymphoniaError)
|
).map_err(LoadError::SymphoniaError)
|
||||||
|
.map(|fr| (file, fr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_cover(format: &mut dyn FormatReader) -> Option<DynamicImage>{
|
pub fn extract_cover(format: &mut dyn FormatReader) -> Option<DynamicImage>{
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
use std::io::Seek;
|
||||||
|
use crate::load_song::LoadError;
|
||||||
|
use crate::model::load_song;
|
||||||
|
use std::path::Path;
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use core::ops::RangeInclusive;
|
use core::ops::RangeInclusive;
|
||||||
use iced_native::widget::text_input::Value;
|
use iced_native::widget::text_input::Value;
|
||||||
|
@ -11,7 +15,6 @@ use std::time::Duration;
|
||||||
use crate::styles::Theme;
|
use crate::styles::Theme;
|
||||||
use crate::controls::Controls;
|
use crate::controls::Controls;
|
||||||
use image::DynamicImage;
|
use image::DynamicImage;
|
||||||
use symphonia::core::formats::FormatReader;
|
|
||||||
|
|
||||||
use iced::widget::text_input;
|
use iced::widget::text_input;
|
||||||
use iced::widget::scrollable;
|
use iced::widget::scrollable;
|
||||||
|
@ -57,8 +60,11 @@ impl LyricEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Editing {
|
impl Editing {
|
||||||
pub fn new(mut song: Box<dyn FormatReader>) -> (Self, Command<Message>) {
|
pub fn new(song_path: &Path) -> Result<(Self, Command<Message>), LoadError> {
|
||||||
let cover = extract_cover(song.as_mut());
|
let (mut file, fr) = load_song(song_path)?;
|
||||||
|
let mut fr = fr.format;
|
||||||
|
|
||||||
|
let cover = extract_cover(fr.as_mut());
|
||||||
|
|
||||||
let theme = cover.as_ref()
|
let theme = cover.as_ref()
|
||||||
.map(|cover| {
|
.map(|cover| {
|
||||||
|
@ -80,7 +86,10 @@ impl Editing {
|
||||||
cover.to_bgra8().into_raw(),
|
cover.to_bgra8().into_raw(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let (controls, cmd) = Controls::new(song);
|
// Reset file handle and drop the format reader
|
||||||
|
file.rewind().map_err(LoadError::OpenError)?;
|
||||||
|
|
||||||
|
let (controls, cmd) = Controls::new(file);
|
||||||
|
|
||||||
let mut lyrics = Vec::with_capacity(70);
|
let mut lyrics = Vec::with_capacity(70);
|
||||||
lyrics.push(Lyric::new());
|
lyrics.push(Lyric::new());
|
||||||
|
@ -92,7 +101,7 @@ impl Editing {
|
||||||
controls, theme, cached_resized_bg, lyrics,
|
controls, theme, cached_resized_bg, lyrics,
|
||||||
};
|
};
|
||||||
|
|
||||||
(editor, cmd)
|
Ok((editor, cmd))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, message: Message) -> Command<Message> {
|
pub fn update(&mut self, message: Message) -> Command<Message> {
|
||||||
|
|
|
@ -31,10 +31,17 @@ impl Model {
|
||||||
},
|
},
|
||||||
Message::FileOpened(path) => {
|
Message::FileOpened(path) => {
|
||||||
println!("File opened! {}", path.display());
|
println!("File opened! {}", path.display());
|
||||||
let song = load_song(&path).unwrap().format;
|
match Editing::new(&path) {
|
||||||
let (editing, cmd) = Editing::new(song);
|
Ok((editing, cmd)) => {
|
||||||
*self = Self::Editing(editing);
|
*self = Self::Editing(editing);
|
||||||
cmd
|
cmd
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("yikeys! Problem opening doodad: {}", e);
|
||||||
|
//TODO! Report the error on the file loader
|
||||||
|
Command::none()
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Message::PromptForFile => {
|
Message::PromptForFile => {
|
||||||
let show_dialog = AsyncFileDialog::new()
|
let show_dialog = AsyncFileDialog::new()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
use std::fs::File;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use rodio::Decoder;
|
use rodio::Decoder;
|
||||||
use symphonia::core::formats::FormatReader;
|
|
||||||
use rodio::source::Buffered;
|
use rodio::source::Buffered;
|
||||||
use rodio::OutputStream;
|
use rodio::OutputStream;
|
||||||
use rodio::Sink;
|
use rodio::Sink;
|
||||||
|
@ -9,7 +9,7 @@ use rodio::Source;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub type Song = Buffered<Decoder<std::io::Empty>>;
|
pub type Song = Buffered<Decoder<File>>;
|
||||||
|
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
// [Buffered] is a pointer to a linked-list representation of the song, and so cloning
|
// [Buffered] is a pointer to a linked-list representation of the song, and so cloning
|
||||||
|
@ -34,9 +34,9 @@ impl Player {
|
||||||
/// task, this DOES NOT COMPUTE THE DURATION. All calculations that require a
|
/// task, this DOES NOT COMPUTE THE DURATION. All calculations that require a
|
||||||
/// duration assume a duration of 2:30s until a duration is manually calculated with
|
/// duration assume a duration of 2:30s until a duration is manually calculated with
|
||||||
/// [`compute_duration()`] AND passed back into [`set_duration()`].
|
/// [`compute_duration()`] AND passed back into [`set_duration()`].
|
||||||
pub fn new(song: Box<dyn FormatReader>) -> Result<Self, PlayerError> {
|
pub fn new(song: File) -> Result<Self, PlayerError> {
|
||||||
|
|
||||||
let song = Decoder::new_from_format_reader(song)
|
let song = Decoder::new(song)
|
||||||
.map_err(PlayerError::Decoder)?
|
.map_err(PlayerError::Decoder)?
|
||||||
.buffered();
|
.buffered();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue