From 96117c2faff517c3101e4b8cf3e2701ab138ebf1 Mon Sep 17 00:00:00 2001 From: chaos Date: Fri, 20 Oct 2023 15:31:26 +0100 Subject: [PATCH] extract more info using ffprobe for album art detection --- src/utils/ffprobe/ffprobe_output.rs | 12 ++++++++++++ src/utils/ffprobe/mod.rs | 30 +++++++++++++++++++++++------ src/utils/ffprobe/types.rs | 8 ++++++++ src/utils/formats/handlers/mod.rs | 20 +++++++++++-------- 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/utils/ffprobe/ffprobe_output.rs b/src/utils/ffprobe/ffprobe_output.rs index 9f5c6de..bb2ce9f 100644 --- a/src/utils/ffprobe/ffprobe_output.rs +++ b/src/utils/ffprobe/ffprobe_output.rs @@ -3,6 +3,18 @@ use serde::Deserialize; #[derive(Debug, Clone, Deserialize)] pub struct FFProbeOutput { pub format: FFProbeOutputFormat, + pub streams: Vec, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct FFProbeOutputStream { + pub index: u8, + pub channels: Option, + pub duration: String, + pub codec_name: String, + pub codec_type: String, + pub height: Option, + pub width: Option, } #[derive(Debug, Clone, Deserialize)] diff --git a/src/utils/ffprobe/mod.rs b/src/utils/ffprobe/mod.rs index 52cea90..94b0d1a 100644 --- a/src/utils/ffprobe/mod.rs +++ b/src/utils/ffprobe/mod.rs @@ -6,7 +6,7 @@ use std::{convert::Into, path::Path, process::Command}; use self::errors::{AnalyzeError, FFProbeError}; -pub fn analyze(path: &Path) -> Result { +fn extract(path: &Path) -> Result { let output = Command::new(crate::meta::FFPROBE) .args([ "-v", @@ -14,6 +14,7 @@ pub fn analyze(path: &Path) -> Result { "-print_format", "json", "-show_format", + "-show_streams", path.to_str().unwrap(), ]) .output(); @@ -35,9 +36,26 @@ pub fn analyze(path: &Path) -> Result { let ffprobe_out: serde_json::Result = serde_json::from_str(output.as_str()); - let ffprobe_out = ffprobe_out.unwrap(); - - Ok(types::FFProbeData { - tags: ffprobe_out.format.tags.into(), - }) + Ok(ffprobe_out.unwrap()) +} + +pub fn analyze(path: &Path) -> Result { + let raw_data = extract(path)?; + + let mut data = types::FFProbeData { + tags: raw_data.format.tags.into(), + album_art: None, + }; + + for stream in raw_data.streams.into_iter() { + if stream.codec_type == "video" { + data.album_art = Some(types::FFProbeAlbumArt { + codec_name: stream.codec_name, + height: stream.height.unwrap(), + width: stream.width.unwrap(), + }); + } + } + + Ok(data) } diff --git a/src/utils/ffprobe/types.rs b/src/utils/ffprobe/types.rs index 2b81c3d..c019052 100644 --- a/src/utils/ffprobe/types.rs +++ b/src/utils/ffprobe/types.rs @@ -21,7 +21,15 @@ impl From for FFProbeTags { } } +#[derive(Debug, Clone, Serialize)] +pub struct FFProbeAlbumArt { + pub codec_name: String, + pub height: u16, + pub width: u16, +} + #[derive(Debug, Clone, Serialize)] pub struct FFProbeData { pub tags: FFProbeTags, + pub album_art: Option, } diff --git a/src/utils/formats/handlers/mod.rs b/src/utils/formats/handlers/mod.rs index 9264434..3dfe7a9 100644 --- a/src/utils/formats/handlers/mod.rs +++ b/src/utils/formats/handlers/mod.rs @@ -6,17 +6,21 @@ use lazy_static::lazy_static; use super::{BoxedError, FormatHandler}; -#[cfg(feature = "mp3_extractor")] -mod id3; -#[cfg(feature = "flac_extractor")] -mod flac; -#[cfg(feature = "taglib_extractor")] -mod taglib; #[cfg(feature = "ffprobe_extractor")] mod ffprobe; +#[cfg(feature = "flac_extractor")] +mod flac; +#[cfg(feature = "mp3_extractor")] +mod id3; +#[cfg(feature = "taglib_extractor")] +mod taglib; - -#[cfg(not(any(feature = "mp3_extractor", feature = "flac_extractor", feature = "taglib_extractor", feature = "ffprobe_extractor")))] +#[cfg(not(any( + feature = "mp3_extractor", + feature = "flac_extractor", + feature = "taglib_extractor", + feature = "ffprobe_extractor" +)))] compile_error!("at least one extractor feature must be enabled"); type NewHandlerFuncReturn = Result, BoxedError>;