summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Cargo.lock206
-rw-r--r--Cargo.toml6
-rw-r--r--src/flac.rs149
-rw-r--r--src/main.rs4
5 files changed, 194 insertions, 175 deletions
diff --git a/.gitignore b/.gitignore
index ec31677..50319b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,4 +22,6 @@
.vscode/launch.json
target
*.flac
-*.wav \ No newline at end of file
+*.wav
+*.tmp
+
diff --git a/Cargo.lock b/Cargo.lock
index 791e294..bec0084 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -24,12 +24,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
-name = "arrayvec"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
-
-[[package]]
name = "backtrace"
version = "0.3.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -45,16 +39,29 @@ dependencies = [
]
[[package]]
-name = "bitflags"
-version = "1.3.2"
+name = "bincode"
+version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740"
+dependencies = [
+ "serde",
+ "unty",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
[[package]]
-name = "bytemuck"
-version = "1.23.0"
+name = "byteorder"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
@@ -72,6 +79,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "claxon"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688"
+
+[[package]]
name = "cmake"
version = "0.1.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -81,12 +94,23 @@ dependencies = [
]
[[package]]
-name = "encoding_rs"
-version = "0.8.35"
+name = "crypto-common"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
- "cfg-if",
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
]
[[package]]
@@ -99,16 +123,26 @@ dependencies = [
]
[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
name = "gimli"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
-name = "lazy_static"
-version = "1.5.0"
+name = "hex"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "libc"
@@ -127,10 +161,14 @@ dependencies = [
]
[[package]]
-name = "log"
-version = "0.4.27"
+name = "md-5"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
+dependencies = [
+ "cfg-if",
+ "digest",
+]
[[package]]
name = "memchr"
@@ -139,6 +177,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
+name = "metaflac"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdf25a3451319c52a4a56d956475fbbb763bfb8420e2187d802485cb0fd8d965"
+dependencies = [
+ "byteorder",
+ "hex",
+]
+
+[[package]]
name = "miniz_oxide"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -163,13 +211,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
name = "reencoder"
version = "0.1.0"
dependencies = [
"anyhow",
+ "bincode",
+ "claxon",
"flac-bound",
- "symphonia",
- "symphonia-metadata",
+ "md-5",
+ "metaflac",
"tokio",
]
@@ -180,68 +248,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
-name = "shlex"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-
-[[package]]
-name = "symphonia"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9"
-dependencies = [
- "lazy_static",
- "symphonia-bundle-flac",
- "symphonia-core",
- "symphonia-metadata",
-]
-
-[[package]]
-name = "symphonia-bundle-flac"
-version = "0.5.4"
+name = "serde"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
- "log",
- "symphonia-core",
- "symphonia-metadata",
- "symphonia-utils-xiph",
+ "serde_derive",
]
[[package]]
-name = "symphonia-core"
-version = "0.5.4"
+name = "serde_derive"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
- "arrayvec",
- "bitflags",
- "bytemuck",
- "lazy_static",
- "log",
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[package]]
-name = "symphonia-metadata"
-version = "0.5.4"
+name = "shlex"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c"
-dependencies = [
- "encoding_rs",
- "lazy_static",
- "log",
- "symphonia-core",
-]
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
-name = "symphonia-utils-xiph"
-version = "0.5.4"
+name = "syn"
+version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
- "symphonia-core",
- "symphonia-metadata",
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
]
[[package]]
@@ -255,6 +295,30 @@ dependencies = [
]
[[package]]
+name = "typenum"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "unty"
+version = "0.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 1017e32..72bc5fc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,7 +5,9 @@ edition = "2024"
[dependencies]
anyhow = "1.0.98"
+bincode = { version = "2.0.1", default-features = false, features = ["std"] }
+claxon = "0.4.3"
flac-bound = { version = "0.5.0", features = ["libflac-noogg"], default-features = false }
-symphonia = { version = "0.5.4", default-features = false, features = ["flac"] }
-symphonia-metadata = "0.5.4"
+md-5 = "0.10.6"
+metaflac = "0.2.8"
tokio = "1.45.1"
diff --git a/src/flac.rs b/src/flac.rs
index 8b03664..1881756 100644
--- a/src/flac.rs
+++ b/src/flac.rs
@@ -1,130 +1,79 @@
use anyhow::{Result, anyhow};
use flac_bound::{FlacEncoder, WriteWrapper};
+use md5::{Digest, Md5};
+use metaflac::Tag;
use std::fs::File;
-use symphonia::core::{
- audio::SampleBuffer,
- codecs::{DecoderOptions, CODEC_TYPE_NULL},
- errors::Error::DecodeError,
- formats::{FormatOptions, Track},
- io::MediaSourceStream,
- meta::MetadataOptions,
- probe::{Hint, ProbeResult},
-};
#[derive(Debug)]
struct StreamConfig {
channels: u32,
- bits_per_sample: Bps,
+ bits_per_sample: u32,
sample_rate: u32,
total_samples_estimate: u64,
}
-#[derive(Debug)]
-enum Bps {
- _16,
- _24,
- _32
-}
-
-fn get_probe(file: &std::path::Path) -> Result<ProbeResult> {
- let src = std::fs::File::open(file)?;
- let mss = MediaSourceStream::new(Box::new(src), Default::default());
- let mut hint = Hint::new();
- hint.with_extension("flac");
- let meta_opts: MetadataOptions = Default::default();
- let fmt_opts: FormatOptions = Default::default();
- Ok(symphonia::default::get_probe().format(&hint, mss, &fmt_opts, &meta_opts)?)
-}
-
-fn read_streaminfo(track: &Track) -> Result<StreamConfig> {
- let params = &track.codec_params;
-
- Ok(StreamConfig {
- channels: params.channels.unwrap().count() as u32,
- bits_per_sample: match params.bits_per_sample.unwrap() {
- 16 => Bps::_16,
- 24 => Bps::_24,
- 32 => Bps::_32,
- _ => return Err(anyhow!("invalid Bps"))
- },
- sample_rate: params.sample_rate.unwrap(),
- total_samples_estimate: params.n_frames.unwrap(),
- })
-}
-
pub fn encode_file(file: &std::path::Path) -> Result<()> {
- let probed = get_probe(file)?;
- let mut format = probed.format;
- let dec_opts: DecoderOptions = Default::default();
- let track = format
- .tracks()
- .iter()
- .find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
- .unwrap();
-
- let config = read_streaminfo(track)?;
-
- let mut outf = File::create(format!("{}.{}", file.display(), "tmp"))?;
+ let mut reader = claxon::FlacReader::open(file)?;
+ let config = StreamConfig {
+ channels: reader.streaminfo().channels,
+ bits_per_sample: reader.streaminfo().bits_per_sample,
+ sample_rate: reader.streaminfo().sample_rate,
+ total_samples_estimate: reader.streaminfo().samples.unwrap(),
+ };
+ let tempname = format!("{}.{}", file.display(), "tmp");
+ let mut outf = File::create(&tempname)?;
let mut outw = WriteWrapper(&mut outf);
let mut enc = FlacEncoder::new()
.unwrap()
.channels(config.channels)
- .bits_per_sample(match config.bits_per_sample {
- Bps::_16 => 16,
- Bps::_24 => 24,
- Bps::_32 => 32
- })
+ .bits_per_sample(config.bits_per_sample)
.sample_rate(config.sample_rate)
.total_samples_estimate(config.total_samples_estimate)
.compression_level(8)
- .verify(true)
+ .verify(false)
.init_write(&mut outw)
.unwrap();
- let mut decoder = symphonia::default::get_codecs()
- .make(&track.codec_params, &dec_opts)
- .unwrap();
- let track_id = track.id;
-
- let mut sample_buf = None;
+ let mut hasher = Md5::new();
+ let mut bytes = Vec::new();
- loop {
- let packet = format.next_packet().unwrap();
+ for samples in reader
+ .samples()
+ .map(|sample| sample.unwrap())
+ .collect::<Vec<_>>()
+ .chunks(4096)
+ {
+ enc.process_interleaved(samples, 2048).unwrap();
+ let _ = samples
+ .iter()
+ .map(|sample| {
+ for byte in sample.to_le_bytes() {
+ bytes.push(byte)
+ }
+ })
+ .collect::<Vec<_>>();
+ hasher.update(&bytes);
+ bytes.clear();
+ }
- if packet.track_id() != track_id {
- continue;
- }
+ match enc.finish() {
+ Ok(_) => {}
+ Err(enc) => return Err(anyhow!("Encoding failed:\t{:?}", enc.state())),
+ }
- match decoder.decode(&packet) {
- Ok(audio_buf) => {
- if sample_buf.is_none() {
- let spec = *audio_buf.spec();
+ /* let source_tags = Tag::read_from_path(file)?;
+ let mut target_tags = Tag::read_from_path(tempname)?;
- let duration = audio_buf.capacity() as u64;
- sample_buf = Some(SampleBuffer::<i16>::new(duration, spec));
- /* match config.bits_per_sample {
- Bps::_16 => sample_buf = Some(SampleBuffer::<i16>::new(duration, spec)),
- Bps::_24 => sample_buf = Some(SampleBuffer::<i24>::new(duration, spec)),
- Bps::_32 => sample_buf = Some(SampleBuffer::<i32>::new(duration, spec)),
- } */
- }
+ for block in source_tags.blocks() {
+ todo!()
+ } */
- if let Some(buf) = &mut sample_buf {
- buf.copy_interleaved_ref(audio_buf);
- let mut samples = Vec::new();
- _ = buf.samples().iter().map(|sample| samples.push(*sample as i32)).collect::<Vec<_>>();
- enc.process_interleaved(samples.as_slice(), samples.iter().len() as u32 / config.channels)
- .unwrap();
- }
- }
- Err(DecodeError(_)) => (),
- Err(_) => break,
- }
- }
+ let mut tags = Tag::read_from_path(tempname)?;
+ let mut streaminfo = tags.get_streaminfo().unwrap().clone();
+ streaminfo.md5 = hasher.finalize()[..].to_vec();
+ tags.set_streaminfo(streaminfo);
+ tags.save()?;
- match enc.finish() {
- Ok(_) => Ok(()),
- Err(enc) => Err(anyhow!("Encoding failed:\t{:?}", enc.state())),
- }
+ Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index 6c4cb43..ba95650 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,7 @@
mod flac;
fn main() {
- flac::encode_file(std::path::Path::new("./1.flac")).unwrap();
+ if let Err(error) = flac::encode_file(std::path::Path::new("./1.flac")) {
+ println!("{}", error)
+ };
}