Have ffmpeg output to a pipe, and read from that - saves creating temp

files.
This commit is contained in:
CDrummond 2025-03-02 08:57:08 +00:00
parent 5fa745975c
commit e23aba88e3
3 changed files with 29 additions and 29 deletions

15
Cargo.lock generated
View File

@ -117,16 +117,15 @@ dependencies = [
"anyhow",
"argparse",
"bliss-audio",
"byteorder",
"chrono",
"configparser",
"dirs",
"env_logger",
"hound",
"if_chain",
"indicatif",
"lofty",
"log",
"md5",
"num_cpus",
"regex",
"rusqlite",
@ -454,12 +453,6 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
[[package]]
name = "hound"
version = "3.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f"
[[package]]
name = "humantime"
version = "2.1.0"
@ -615,12 +608,6 @@ dependencies = [
"rawpointer",
]
[[package]]
name = "md5"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
[[package]]
name = "memchr"
version = "2.4.1"

View File

@ -25,9 +25,8 @@ ureq = "2.4.0"
configparser = "3.0.0"
if_chain = "1.0.2"
num_cpus = "1.13.0"
md5 = "0.7.0"
hound = "3.5.1"
which = "7.0.2"
byteorder = "1.4"
[dependencies.bliss-audio]
default-features = false

View File

@ -9,26 +9,40 @@
use bliss_audio::decoder::Decoder as DecoderTrait;
use bliss_audio::decoder::PreAnalyzedSong;
use bliss_audio::BlissResult;
use std::fs;
use byteorder::{LittleEndian, ReadBytesExt};
use std::path::Path;
use std::process::Command;
use md5;
use std::process::{Command, Stdio};
use std::io;
pub struct FFmpegCmdDecoder;
impl DecoderTrait for FFmpegCmdDecoder {
fn decode(path: &Path) -> BlissResult<PreAnalyzedSong> {
let mut decoded_song = PreAnalyzedSong::default();
let digest = md5::compute(path.to_str().unwrap_or("null").as_bytes().to_vec());
let tmp_path = format!("/tmp/{:x}.wav", digest);
let _ = Command::new("ffmpeg").arg("-i").arg(path).arg("-ar").arg("22050").arg("-ac").arg("1").arg("-c:a").arg("pcm_f32le").arg(tmp_path.clone()).output();
let cloned_path = tmp_path.clone();
let wav_file = Path::new(&cloned_path);
if wav_file.exists() {
let mut reader = hound::WavReader::open(tmp_path).unwrap();
decoded_song.sample_array = reader.samples::<f32>().flatten().collect();
let _ = fs::remove_file(wav_file);
if let Ok(mut child) = Command::new("ffmpeg")
.arg("-hide_banner")
.arg("-loglevel").arg("panic")
.arg("-i").arg(path)
.arg("-ar").arg("22050")
.arg("-ac").arg("1")
.arg("-c:a")
.arg("pcm_f32le")
.arg("-f").arg("f32le")
.arg("pipe:1")
.stdout(Stdio::piped())
.spawn() {
let stdout = child.stdout.as_mut().expect("Failed to capture stdout");
let mut reader = io::BufReader::new(stdout);
let mut buffer: Vec<f32> = Vec::new();
while let Ok(sample) = reader.read_f32::<LittleEndian>() {
buffer.push(sample);
}
if let Ok(_) = child.wait() {
decoded_song.sample_array = buffer;
}
}
Ok(decoded_song)
}
}