je ne saus plus c'est vieux ;-)

This commit is contained in:
2025-11-21 23:09:52 +01:00
parent f7f2364da6
commit e00d0ce4d8
5 changed files with 127 additions and 26 deletions

View File

@@ -6,7 +6,7 @@
use anyhow::Result;
use pmocache::CacheConfig;
use serde_json::Value;
use serde_json::{Number, Value};
use std::sync::Arc;
/// Configuration pour le cache audio
@@ -144,6 +144,57 @@ pub async fn add_with_metadata_extraction(
// Extraire les métadonnées
let mut metadata = crate::metadata::AudioMetadata::from_bytes(&flac_bytes)?;
// Propager les métadonnées techniques dans la DB (sans passer par le JSON)
if let Some(d) = metadata.duration_secs {
let _ = cache
.db
.set_a_metadata(&pk, "duration_secs", Value::Number(Number::from(d)));
}
if let Some((sr, bps, total_samples)) = parse_flac_streaminfo(&flac_bytes) {
let _ = cache
.db
.set_a_metadata(&pk, "sample_rate", Value::Number(Number::from(sr)));
let _ = cache
.db
.set_a_metadata(&pk, "bits_per_sample", Value::Number(Number::from(bps)));
let _ = cache.db.set_a_metadata(
&pk,
"total_samples",
Value::Number(Number::from(total_samples)),
);
if metadata.duration_secs.is_none() && sr > 0 {
let secs = (total_samples as f64 / sr as f64).round() as u64;
let _ = cache
.db
.set_a_metadata(&pk, "duration_secs", Value::Number(Number::from(secs)));
metadata.duration_secs = Some(secs);
}
if metadata.sample_rate.is_none() {
metadata.sample_rate = Some(sr);
}
}
// Extraire aussi les informations FLAC de base (STREAMINFO) pour peupler TrackMetadata
if let Some((sr, bps, total_samples)) = parse_flac_streaminfo(&flac_bytes) {
if let Err(e) = cache
.db
.set_a_metadata(&pk, "sample_rate", Value::Number(Number::from(sr)))
{
tracing::warn!("Failed to persist sample_rate for {}: {}", pk, e);
}
if let Err(e) = cache
.db
.set_a_metadata(&pk, "bits_per_sample", Value::Number(Number::from(bps)))
{
tracing::warn!("Failed to persist bits_per_sample for {}: {}", pk, e);
}
if let Err(e) = cache
.db
.set_a_metadata(&pk, "total_samples", Value::Number(Number::from(total_samples)))
{
tracing::warn!("Failed to persist total_samples for {}: {}", pk, e);
}
}
if let Some(transform) = cache.transform_metadata(&pk).await {
if let Some(mode) = transform.mode {
@@ -210,3 +261,40 @@ pub fn get_metadata(cache: &Cache, pk: &str) -> Result<crate::metadata::AudioMet
Ok(metadata)
}
/// Parse minimal FLAC STREAMINFO (first metadata block) to retrieve sample rate,
/// bits per sample, and total samples.
fn parse_flac_streaminfo(data: &[u8]) -> Option<(u32, u8, u64)> {
// Expect "fLaC" + 4-byte metadata block header + 34-byte STREAMINFO
if data.len() < 4 + 4 + 34 {
return None;
}
if &data[0..4] != b"fLaC" {
return None;
}
let block_type = data[4] & 0x7F;
let block_len = ((data[5] as usize) << 16) | ((data[6] as usize) << 8) | data[7] as usize;
if block_type != 0 || block_len < 34 || data.len() < 8 + block_len {
return None;
}
let s = &data[8..8 + 34];
// sample_rate: 20 bits: bytes 10..12
let sample_rate =
((s[10] as u32) << 12) | ((s[11] as u32) << 4) | ((s[12] as u32 & 0xF0) >> 4);
// bits_per_sample: 5 bits spanning byte 12 (lsb) and byte 13 (msb)
let bps_raw = (((s[12] & 0x01) as u8) << 4) | ((s[13] & 0xF0) >> 4);
let bits_per_sample = bps_raw.saturating_add(1);
// total_samples: 36 bits: lower 4 bits of byte 13 + bytes 14..17
let total_samples = (((s[13] & 0x0F) as u64) << 32)
| ((s[14] as u64) << 24)
| ((s[15] as u64) << 16)
| ((s[16] as u64) << 8)
| (s[17] as u64);
Some((sample_rate, bits_per_sample, total_samples))
}