Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapping metadata to struct #184

Open
112RG opened this issue Feb 4, 2023 · 3 comments
Open

Mapping metadata to struct #184

112RG opened this issue Feb 4, 2023 · 3 comments

Comments

@112RG
Copy link

112RG commented Feb 4, 2023

I am currently using metaflac in my project Deaftone. I am wanting to try out Symphonia to map tags from files into a struct I have but I am unsure how todo that with the examples and docs given.

In metaflac I simply

    let metadata: AudioMetadata = AudioMetadata {
        name: vorbis
            .title()
            .map(|v| v[0].clone())
            .unwrap_or_else(|| "FAILED TO READ TITLE DEAFTONE".to_string()),
        album: vorbis
            .album()
            .map(|v| v[0].clone())
            .unwrap_or_else(|| "FAILED TO READ ALBUM DEAFTONE".to_string()),
        album_artist: match vorbis.album_artist().map(|v| v[0].clone()) {
            Some(e) => e,
            None => vorbis
                .artist()
                .map(|v| v[0].clone())
                .unwrap_or_else(|| "FAILED TO READ ARTIST DEAFTONE".to_string()),
        },
        year: get_year(vorbis),
        track: vorbis.track().unwrap_or(0),
        path,
        lossless: true,
        duration: duration.unwrap_or_default(),
    };

But I am unsure how todo that with the library currently. Here is my struct defined below

pub struct AudioMetadata {
    pub name: String,
    pub artist: String,
    pub artist_sort: Option<String>,
    pub album_name: String,
    pub album_artist: String,
    pub album_sort: Option<String>,
    pub genre: Option<Vec<String>>,
    pub style: Option<Vec<String>>,
    pub discogs_albumid: Option<String>,
    pub discogs_artistid: Option<String>,
    pub discogs_labelid: Option<String>,
    pub lyricist: Option<String>,
    pub composer: Option<String>,
    pub composer_sort: Option<String>,
    pub work: Option<String>,
    pub mb_workid: Option<String>,
    pub arranger: Option<String>,
    pub grouping: Option<String>,
    pub year: i32,
    pub lyrics: Option<String>,
    pub comments: Option<String>,
    pub bpm: Option<String>,
    pub compilation: Option<String>,
    pub mb_track_id: Option<String>,
    pub mb_album_id: Option<String>,
    pub mb_artist_id: Option<String>,
    pub mb_albumartist_id: Option<String>,
    pub mb_releasetrack_id: Option<String>,
    pub mb_releasegroup_id: Option<String>,
    pub trackdisambig: Option<String>,
    pub album_type: Option<String>,
    pub acoustid_fingerprint: Option<String>,
    pub acoustid_id: Option<String>,
    pub asin: Option<String>,
    pub isrc: Option<String>,
    pub catalog_num: Option<String>,
    pub script: Option<String>,
    pub country: Option<String>,
    pub albumstatus: Option<String>,
    pub media: Option<String>,
    pub album_disambig: Option<String>,
    pub release_group_disambig: Option<String>,
    pub encodedby: Option<String>,
    pub original_year: Option<String>,
    pub initial_key: Option<String>,
    pub bit_rate: Option<i64>,
    pub encoder_settings: Option<String>,
    pub channels: Option<u8>,
    pub bit_depth: Option<u8>,
    pub sample_rate: Option<u32>,
    pub track: u32,
    pub disc: u32,
    pub length: u32,
    pub label: Option<String>,
    pub path: String,
    pub parent_path: String,
}
@pdeljanov
Copy link
Owner

If you don't need playback, then I'd recommend using the lofty crate instead of Symphonia since it's more comprehensive and simpler. Symphonia's metadata system is more complex because it has to deal with mid-stream changes to metadata.


Once you have a FormatReader, call the FormatReader::metadata function to get access to the metadata log. This is basically of a queue of MetadataRevisions with functions to iterate over and consume the revisions. Each MetadataRevision provides access to Tags, and Visuals (pictures). Looping through those slices will get you what you are looking for. My recommendation is to use the standard tag and visual key fields to match tags to your data structure.

One thing to note is that metadata can also be found while probing the file. This famously happens with ID3v2 tags since those are just binary blobs at the start of the file. The ProbeResult returned after the probe operation also returns a metadata log that should be consumed in the same way.

It's up to the application to decide how to interpret these revisions (i.e., whether one replaces another completely, or simply updates an older revision).

@112RG
Copy link
Author

112RG commented Feb 5, 2023

I will be using playback my project https://github.com/Ortygia/Deaftone is a music server. But I am still looking for a fast tag scanner solution metaflac is currently the fastest and from this discussion here Deaftone/Deaftone#8 (comment) metaflac is beating out lofty-rs on my testing. So I wanted to test out Symphonia as I am looking to squeeze the most performance possible out of it

@sealter
Copy link

sealter commented Feb 14, 2023

If you don't need playback, then I'd recommend using the lofty crate instead of Symphonia since it's more comprehensive and simpler. Symphonia's metadata system is more complex because it has to deal with mid-stream changes to metadata.

Once you have a FormatReader, call the FormatReader::metadata function to get access to the metadata log. This is basically of a queue of MetadataRevisions with functions to iterate over and consume the revisions. Each MetadataRevision provides access to Tags, and Visuals (pictures). Looping through those slices will get you what you are looking for. My recommendation is to use the standard tag and visual key fields to match tags to your data structure.

One thing to note is that metadata can also be found while probing the file. This famously happens with ID3v2 tags since those are just binary blobs at the start of the file. The ProbeResult returned after the probe operation also returns a metadata log that should be consumed in the same way.

It's up to the application to decide how to interpret these revisions (i.e., whether one replaces another completely, or simply updates an older revision).

What about video metadata, is there a comprehensive and simpler crate? I just want to get video metadata

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants