Use ffprobe to read meta-data if not compiled against libav

Closes #18
This commit is contained in:
CDrummond committed 2025-03-05 18:39:54 +00:00
1 parent 751dca7091
commit 32610f22b7
3 files changed
+61 -7

No files matched your search

+4 -5
View File
@@ -40,11 +40,7 @@ use bliss_audio::{decoder::Decoder, BlissResult, Song};
const DONT_ANALYSE: &str = ".notmusic";
const MAX_ERRORS_TO_SHOW: usize = 100;
const MAX_TAG_ERRORS_TO_SHOW: usize = 50;
#[cfg(feature = "libav")]
const VALID_EXTENSIONS: [&str; 7] = ["m4a", "mp3", "ogg", "flac", "opus", "wv", "dsf"];
#[cfg(not(feature = "libav"))]
const VALID_EXTENSIONS: [&str; 6] = ["m4a", "mp3", "ogg", "flac", "opus", "wv"];
fn get_file_list(db: &mut db::Db, mpath: &Path, path: &Path, track_paths: &mut Vec<String>, cue_tracks:&mut Vec<cue::CueTrack>, file_count:&mut usize, max_num_files: usize, use_tags: bool, tagged_file_count:&mut usize, dry_run: bool) {
if !path.is_dir() {
@@ -285,7 +281,10 @@ fn analyse_new_files(db: &db::Db, mpath: &PathBuf, track_paths: Vec<String>, max
match result {
Ok(track) => {
let cpath = String::from(path.to_string_lossy());
let meta = tags::read(&cpath, false);
let mut meta = tags::read(&cpath, false);
if meta.is_empty() {
meta = ffmpeg::read_tags(&cpath);
}
if meta.is_empty() {
tag_error.push(sname.clone());
}
+56
View File
@@ -6,6 +6,7 @@
*
**/
use crate::db;
use bliss_audio::decoder::Decoder as DecoderTrait;
use bliss_audio::decoder::PreAnalyzedSong;
use bliss_audio::{BlissError, BlissResult};
@@ -13,6 +14,8 @@ use std::path::Path;
use std::process::{Child, Command, Stdio};
use std::io;
use std::io::Read;
use std::io::BufRead;
use std::io::BufReader;
use std::time::Duration;
pub const TIME_SEP:&str = "<TIME>";
@@ -41,6 +44,59 @@ fn handle_command(mut child: Child) -> BlissResult<PreAnalyzedSong> {
Ok(decoded_song)
}
fn get_val(line: String) -> String {
let parts = line.split("=");
let mut resp:Vec<String> = Vec::new();
let mut first =true;
for part in parts {
if !first {
resp.push(String::from(part));
}
first = false
}
resp.join("=")
}
pub fn read_tags(path: &String) -> db::Metadata {
let mut meta = db::Metadata {
duration: 0,
..db::Metadata::default()
};
if let Ok(child) = Command::new("ffprobe")
.arg("-hide_banner")
.arg("-v").arg("quiet")
.arg("-show_entries").arg("format")
.arg(path)
.stdout(Stdio::piped())
.spawn() {
let out = child.stdout.unwrap();
let lines = BufReader::new(out).lines().filter_map(|line| line.ok());
for line in lines {
if line.starts_with("duration=") {
let val = get_val(line);
match val.parse::<f32>() {
Ok(v) => {
meta.duration = v as u32;
},
Err(_) => { }
}
} else if line.starts_with("TAG:title=") {
meta.title = get_val(line);
} else if line.starts_with("TAG:artist=") {
meta.artist = get_val(line);
} else if line.starts_with("TAG:album=") {
meta.album = get_val(line);
} else if line.starts_with("TAG:album_artist=") {
meta.album_artist = get_val(line);
} else if line.starts_with("TAG:genre=") {
meta.genre = get_val(line);
}
}
}
meta
}
impl DecoderTrait for FFmpegCmdDecoder {
fn decode(path: &Path) -> BlissResult<PreAnalyzedSong> {
let binding = path.to_string_lossy();