From 07c3aa7edc046aa80f37ae73b113f22e8a269438 Mon Sep 17 00:00:00 2001 From: chaos Date: Fri, 20 Oct 2023 18:04:22 +0100 Subject: [PATCH] add support for extracting track number --- modules/taglib/src/impls/file.rs | 12 ++++++------ modules/taglib/src/impls/tag.rs | 9 +++++++++ modules/taglib/src/traits.rs | 1 + modules/taglib/src/wrapper.cxx | 5 +++++ modules/taglib/src/wrapper.h | 1 + src/commands/tags/get.rs | 2 ++ src/types.rs | 2 ++ src/utils/ffprobe/ffprobe_output.rs | 4 ++++ src/utils/ffprobe/types.rs | 16 ++++++++++++++++ src/utils/formats/handlers/ffprobe.rs | 3 ++- src/utils/formats/handlers/flac.rs | 15 +++++++++++++++ src/utils/formats/handlers/id3.rs | 3 ++- src/utils/formats/handlers/taglib.rs | 1 + 13 files changed, 66 insertions(+), 8 deletions(-) diff --git a/modules/taglib/src/impls/file.rs b/modules/taglib/src/impls/file.rs index d2b56ac..ceeafdd 100644 --- a/modules/taglib/src/impls/file.rs +++ b/modules/taglib/src/impls/file.rs @@ -46,13 +46,13 @@ impl TagLibFile { pub fn oggtag(&self) -> Result { if let Some(taglib_type) = &self.taglib_type { - let supported = match taglib_type { + let supported = matches!( + taglib_type, TagLibFileType::OggFLAC - | TagLibFileType::OggOpus - | TagLibFileType::OggSpeex - | TagLibFileType::OggVorbis => true, - _ => false, - }; + | TagLibFileType::OggOpus + | TagLibFileType::OggSpeex + | TagLibFileType::OggVorbis + ); if !supported { panic!("ogg tag not supported") diff --git a/modules/taglib/src/impls/tag.rs b/modules/taglib/src/impls/tag.rs index 9aaf44a..4330711 100644 --- a/modules/taglib/src/impls/tag.rs +++ b/modules/taglib/src/impls/tag.rs @@ -27,4 +27,13 @@ impl Tag for TagLibTag { unsafe { bindings::wrap_taglib_tag_set_artist(self.ctx, artist.as_ptr()) }; } + fn track(&self) -> Option { + let track = unsafe { bindings::wrap_taglib_tag_track(self.ctx) }; + + if track == 0 { + None + } else { + Some(track as u64) + } + } } diff --git a/modules/taglib/src/traits.rs b/modules/taglib/src/traits.rs index c18ee23..251f90b 100644 --- a/modules/taglib/src/traits.rs +++ b/modules/taglib/src/traits.rs @@ -7,6 +7,7 @@ pub trait File { pub trait Tag { fn title(&self) -> Option; fn artist(&self) -> Option; + fn track(&self) -> Option; fn set_title(&mut self, title: String); fn set_artist(&mut self, artist: String); } diff --git a/modules/taglib/src/wrapper.cxx b/modules/taglib/src/wrapper.cxx index 37c74e5..5a19390 100644 --- a/modules/taglib/src/wrapper.cxx +++ b/modules/taglib/src/wrapper.cxx @@ -70,6 +70,11 @@ char* wrap_taglib_tag_artist(TagLib_Tag *tag) { return stringToCharArray(t->artist()); } +unsigned int wrap_taglib_tag_track(TagLib_Tag *tag) { + const TagLib::Tag *t = reinterpret_cast(tag); + return t->track(); +} + void wrap_taglib_tag_set_title(TagLib_Tag *tag, const char *title) { TagLib::Tag *t = reinterpret_cast(tag); t->setTitle(charArrayToString(title)); diff --git a/modules/taglib/src/wrapper.h b/modules/taglib/src/wrapper.h index a19bc1f..993fccb 100644 --- a/modules/taglib/src/wrapper.h +++ b/modules/taglib/src/wrapper.h @@ -17,6 +17,7 @@ bool wrap_taglib_file_save(TagLib_File *file); char* wrap_taglib_tag_title(TagLib_Tag *tag); char* wrap_taglib_tag_artist(TagLib_Tag *tag); +unsigned int wrap_taglib_tag_track(TagLib_Tag *tag); void wrap_taglib_tag_set_title(TagLib_Tag *tag, const char *title); void wrap_taglib_tag_set_artist(TagLib_Tag *tag, const char *artist); diff --git a/src/commands/tags/get.rs b/src/commands/tags/get.rs index efffa5b..b6a80cf 100644 --- a/src/commands/tags/get.rs +++ b/src/commands/tags/get.rs @@ -18,12 +18,14 @@ pub struct GetTagsCommandArgs { struct Tags { title: String, artist: String, + track_number: Option, } fn from_main_tags(tags: &crate::types::Tags) -> Tags { Tags { title: tags.title.clone(), artist: tags.artist.clone(), + track_number: tags.track_number, } } diff --git a/src/types.rs b/src/types.rs index 4659c8f..ce27a03 100644 --- a/src/types.rs +++ b/src/types.rs @@ -6,6 +6,7 @@ use crate::utils::format_detection::FileFormat; pub struct Tags { pub title: String, pub artist: String, + pub track_number: Option, } impl Default for Tags { @@ -13,6 +14,7 @@ impl Default for Tags { Tags { title: "".to_string(), artist: "".to_string(), + track_number: None, } } } diff --git a/src/utils/ffprobe/ffprobe_output.rs b/src/utils/ffprobe/ffprobe_output.rs index bb2ce9f..3482ce0 100644 --- a/src/utils/ffprobe/ffprobe_output.rs +++ b/src/utils/ffprobe/ffprobe_output.rs @@ -24,6 +24,9 @@ pub struct FFProbeOutputFormat { #[derive(Debug, Clone, Deserialize)] pub struct FFProbeOutputTags { + #[serde(alias = "TRACK", alias = "track")] + pub track_number: Option, + #[serde(alias = "TITLE")] pub title: String, #[serde(default, alias = "ARTIST")] @@ -42,6 +45,7 @@ impl Default for FFProbeOutputTags { artist: "".to_string(), replaygain_track_peak: None, replaygain_track_gain: None, + track_number: None, } } } diff --git a/src/utils/ffprobe/types.rs b/src/utils/ffprobe/types.rs index c019052..597a0d6 100644 --- a/src/utils/ffprobe/types.rs +++ b/src/utils/ffprobe/types.rs @@ -8,15 +8,31 @@ pub struct FFProbeTags { pub artist: String, pub replaygain_track_peak: Option, pub replaygain_track_gain: Option, + pub track_number: Option, } impl From for FFProbeTags { fn from(val: ffprobe_output::FFProbeOutputTags) -> Self { + let mut track_number: Option = None; + if let Some(number) = val.track_number { + let mut number = number.clone(); + if number.contains('/') { + let mut split = number.split('/'); + number = split.next().unwrap().to_string() + } + + track_number = match number.parse::() { + Ok(n) => Some(n), + Err(_e) => None, + } + } + FFProbeTags { title: val.title, artist: val.artist, replaygain_track_peak: val.replaygain_track_peak, replaygain_track_gain: val.replaygain_track_gain, + track_number, } } } diff --git a/src/utils/formats/handlers/ffprobe.rs b/src/utils/formats/handlers/ffprobe.rs index e992d3c..2632933 100644 --- a/src/utils/formats/handlers/ffprobe.rs +++ b/src/utils/formats/handlers/ffprobe.rs @@ -47,6 +47,7 @@ impl GenericFFMpegAudioFormat { self.extracted_data.tags = Tags { title: output.tags.title, artist: output.tags.artist, + track_number: output.tags.track_number, }; if output.tags.replaygain_track_gain.is_some() @@ -72,7 +73,7 @@ impl FormatHandler for GenericFFMpegAudioFormat { tags.title = title.clone(); } - if let Some(artist) = &self.changes.title { + if let Some(artist) = &self.changes.artist { tags.artist = artist.clone(); } diff --git a/src/utils/formats/handlers/flac.rs b/src/utils/formats/handlers/flac.rs index 64f49b2..d0c3e8d 100644 --- a/src/utils/formats/handlers/flac.rs +++ b/src/utils/formats/handlers/flac.rs @@ -27,6 +27,7 @@ impl FormatHandler for FLACAudioFormat { fn get_tags(&self, allow_missing: bool) -> Result { let title = flac_get_first(&self.flac_tags, "TITLE"); let artist = flac_get_first(&self.flac_tags, "ARTIST"); + let mut track_number = flac_get_first(&self.flac_tags, "TRACKNUMBER"); if !allow_missing { if title.is_none() { @@ -37,9 +38,23 @@ impl FormatHandler for FLACAudioFormat { } } + if let Some(number) = &track_number { + if number.contains('/') { + let mut split = number.split('/'); + track_number = Some(split.next().unwrap().to_string()) + } + } + Ok(Tags { title: title.unwrap(), artist: artist.unwrap(), + track_number: match track_number { + Some(num) => match num.parse::() { + Ok(n) => Some(n), + Err(_e) => None, + }, + None => None, + }, }) } diff --git a/src/utils/formats/handlers/id3.rs b/src/utils/formats/handlers/id3.rs index 70a9a46..3f0ce25 100644 --- a/src/utils/formats/handlers/id3.rs +++ b/src/utils/formats/handlers/id3.rs @@ -30,6 +30,7 @@ impl FormatHandler for ID3AudioFormat { Ok(Tags { title: String::from(title.unwrap()), artist: String::from(artist.unwrap()), + track_number: self.id3_tags.track().map(|track_number| track_number as u64), }) } @@ -116,8 +117,8 @@ impl FormatHandler for ID3AudioFormat { ) -> Result { Ok(AudioFileInfo { tags: self.get_tags(allow_missing_tags)?, - supports_replaygain: self.supports_replaygain(), format: Some(FileFormat::MP3), + supports_replaygain: self.supports_replaygain(), contains_replaygain: self.contains_replaygain_tags(), }) } diff --git a/src/utils/formats/handlers/taglib.rs b/src/utils/formats/handlers/taglib.rs index 1bc8072..c4d725a 100644 --- a/src/utils/formats/handlers/taglib.rs +++ b/src/utils/formats/handlers/taglib.rs @@ -42,6 +42,7 @@ impl FormatHandler for TaglibAudioFormat { Ok(Tags { title: title.unwrap(), artist: artist.unwrap(), + track_number: tags.track(), }) }