Symphonia
Symphonia copied to clipboard
How to load Metadate from the Files?
I want to load ID3 other Audio Metadata from a File.
title, artists, bpm, etc...
use symphonia::core::codecs::{CODEC_TYPE_NULL, DecoderOptions};
use symphonia::core::errors::Error;
use symphonia::core::formats::FormatOptions;
use symphonia::core::meta::MetadataOptions;
use symphonia::core::io::MediaSourceStream;
use symphonia::core::probe::Hint;
pub fn main() {
let path: String = "D:\\Downloads\\twenor-libary\\public\\audio_2.wav".to_string();
// Open the media source.
let src = std::fs::File::open(&path).expect("failed to open media");
// Create the media source stream.
let mss = MediaSourceStream::new(Box::new(src), Default::default());
// Create a probe hint using the file's extension. [Optional]
let mut hint = Hint::new();
hint.with_extension("mp3");
// Use the default options for metadata and format readers.
let meta_opts: MetadataOptions = Default::default();
let fmt_opts: FormatOptions = Default::default();
// Probe the media source.
let probed = symphonia::default::get_probe().format(&hint, mss, &fmt_opts, &meta_opts)
.expect("unsupported format");
// Get the instantiated format reader.
let mut format = probed.format;
// Find the first audio track with a known (decodeable) codec.
let track = format.tracks()
.iter()
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
.expect("no supported audio tracks");
// Use the default options for the decoder.
let dec_opts: DecoderOptions = Default::default();
// Create a decoder for the track.
let mut decoder = symphonia::default::get_codecs().make(&track.codec_params, &dec_opts)
.expect("unsupported codec");
// Store the track identifier, it will be used to filter packets.
let track_id = track.id;
// The decode loop.
loop {
// Get the next packet from the media format.
let packet = match format.next_packet() {
Ok(packet) => packet,
Err(Error::ResetRequired) => {
// The track list has been changed. Re-examine it and create a new set of decoders,
// then restart the decode loop. This is an advanced feature and it is not
// unreasonable to consider this "the end." As of v0.5.0, the only usage of this is
// for chained OGG physical streams.
unimplemented!();
}
Err(err) => {
// A unrecoverable error occured, halt decoding.
panic!("{}", err);
}
};
// Consume any new metadata that has been read since the last packet.
while !format.metadata().is_latest() {
// Pop the old head of the metadata queue.
format.metadata().pop();
// Consume the new metadata at the head of the metadata queue.
}
// If the packet does not belong to the selected track, skip over it.
if packet.track_id() != track_id {
continue;
}
// Decode the packet into audio samples.
match decoder.decode(&packet) {
Ok(_decoded) => {
// Consume the decoded audio samples (see below).
}
Err(Error::IoError(_)) => {
// The packet failed to decode due to an IO error, skip the packet.
continue;
}
Err(Error::DecodeError(_)) => {
// The packet failed to decode due to invalid data, skip the packet.
continue;
}
Err(err) => {
// An unrecoverable error occured, halt decoding.
panic!("{}", err);
}
}
}
}
thread` 'main' panicked at 'end of stream', src\test_read.rs:62:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Repository has symphonia-play, there is an example of what you are looking for (probe-only) link
I had tryed to get into the Code but in my Tests it wont work. If someone could pase a Example Code for following case:
- Load a Audio File by defined Path variable
- Print out the Title of the Audio File in Console
- Set Album of Audio File to the String "Test"
If anyone could wrap smt around this, you could also add it to the Documentation^^.
I want to edit these Metadata + if possible ID3 and EXIFF later on
OK that code is working in my env for reading metadata!!
use symphonia::core::formats::FormatOptions;
use symphonia::core::io::MediaSourceStream;
use symphonia::core::meta::{MetadataOptions, MetadataRevision};
use symphonia::core::probe::Hint;
pub fn main() {
let path: String = "D:\\Downloads\\twenor-libary\\public\\rick.mp3".to_string();
let src = std::fs::File::open(&path).expect("failed to open media");
let mss = MediaSourceStream::new(Box::new(src), Default::default());
let mut hint = Hint::new();
hint.with_extension("mp3");
let meta_opts: MetadataOptions = Default::default();
let fmt_opts: FormatOptions = Default::default();
let mut probed = symphonia::default::get_probe()
.format(&hint, mss, &fmt_opts, &meta_opts)
.expect("unsupported format");
if let Some(metadata_rev) = probed.format.metadata().current() {
print_tags(&metadata_rev);
if probed.metadata.get().as_ref().is_some() {
println!("tags that are part of the container format are preferentially printed.");
println!("not printing additional tags that were found while probing.");
}
} else if let Some(metadata_rev) = probed.metadata.get().as_ref().and_then(|m| m.current()) {
print_tags(&metadata_rev);
}
}
fn print_tags(metadata_rev: &MetadataRevision) {
let tags = metadata_rev.tags();
for (index, tag) in tags.iter().enumerate() {
if tag.to_string().len() > 400 {
continue;
}
println!("{}: {:?}", index, tag);
}
}
So how now to Edit Metadata
How to rewrite A Tag for Example this one?
5: Tag { std_key: Some(Genre), key: "TCON", value: String("Rap") }
How to rewrite
Symphonia doesn't support writing metadata (?), but alternatively you can look at this lofty-rs
Thank you @SuisChan for answering @cherob's question!
I'm going to close this, but feel free to re-open if there's any further problems.
Hi @pdeljanov ! Isn't it worth to create an example out of this to put in here?