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

Fix up MusicBrainz reading #186

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 10 additions & 23 deletions symphonia-core/src/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ pub enum StandardTagKey {
MusicBrainzRecordingId,
MusicBrainzReleaseGroupId,
MusicBrainzReleaseStatus,
MusicBrainzReleaseTrackId,
MusicBrainzReleaseType,
MusicBrainzTrackId,
MusicBrainzWorkId,
Expand Down Expand Up @@ -391,26 +390,9 @@ pub struct VendorData {
/// `Metadata` is a container for a single discrete revision of metadata information.
#[derive(Clone, Debug, Default)]
pub struct MetadataRevision {
tags: Vec<Tag>,
visuals: Vec<Visual>,
vendor_data: Vec<VendorData>,
}

impl MetadataRevision {
/// Gets an immutable slice to the `Tag`s in this revision.
pub fn tags(&self) -> &[Tag] {
&self.tags
}

/// Gets an immutable slice to the `Visual`s in this revision.
pub fn visuals(&self) -> &[Visual] {
&self.visuals
}

/// Gets an immutable slice to the `VendorData` in this revision.
pub fn vendor_data(&self) -> &[VendorData] {
&self.vendor_data
}
pub tags: Vec<Tag>,
pub visuals: Vec<Visual>,
pub vendor_data: Vec<VendorData>,
}

/// `MetadataBuilder` is the builder for `Metadata` revisions.
Expand Down Expand Up @@ -461,19 +443,24 @@ impl<'a> Metadata<'a> {
self.revisions.len() <= 1
}

/// Gets a mutable reference to the current, and therefore oldest, revision of the metadata.
pub fn current_mut(&mut self) -> Option<&mut MetadataRevision> {
self.revisions.front_mut()
}

/// Gets an immutable reference to the current, and therefore oldest, revision of the metadata.
pub fn current(&self) -> Option<&MetadataRevision> {
self.revisions.front()
}

/// Skips to, and gets an immutable reference to the latest, and therefore newest, revision of the metadata.
pub fn skip_to_latest(&mut self) -> Option<&MetadataRevision> {
pub fn skip_to_latest(&mut self) -> Option<&mut MetadataRevision> {
loop {
if self.pop().is_none() {
break;
}
}
self.current()
self.current_mut()
}

/// If there are newer `Metadata` revisions, advances the `MetadataLog` by discarding the
Expand Down
55 changes: 47 additions & 8 deletions symphonia-metadata/src/id3v2/frames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ lazy_static! {
m.insert(b"TSST", (read_text_frame, None));
m.insert(b"TXXX", (read_txxx_frame, None));
m.insert(b"TYER", (read_text_frame, Some(StandardTagKey::Date)));
// m.insert(b"UFID", read_null_frame);
m.insert(b"UFID", (read_ufid_frame, None));
// m.insert(b"USER", read_null_frame);
m.insert(b"USLT", (read_comm_uslt_frame, Some(StandardTagKey::Lyrics)));
m.insert(b"WCOM", (read_url_frame, Some(StandardTagKey::UrlPurchase)));
Expand Down Expand Up @@ -366,16 +366,21 @@ lazy_static! {
lazy_static! {
static ref TXXX_FRAME_STD_KEYS: HashMap<&'static str, StandardTagKey> = {
let mut m = HashMap::new();
m.insert("ACOUSTID FINGERPRINT", StandardTagKey::AcoustidFingerprint);
m.insert("ACOUSTID ID", StandardTagKey::AcoustidId);
m.insert("Acoustid Fingerprint", StandardTagKey::AcoustidFingerprint);
m.insert("Acoustid Id", StandardTagKey::AcoustidId);
m.insert("BARCODE", StandardTagKey::IdentBarcode);
m.insert("CATALOGNUMBER", StandardTagKey::IdentCatalogNumber);
m.insert("LICENSE", StandardTagKey::License);
m.insert("MUSICBRAINZ ALBUM ARTIST ID", StandardTagKey::MusicBrainzAlbumArtistId);
m.insert("MUSICBRAINZ ALBUM ID", StandardTagKey::MusicBrainzAlbumId);
m.insert("MUSICBRAINZ ARTIST ID", StandardTagKey::MusicBrainzArtistId);
m.insert("MUSICBRAINZ RELEASE GROUP ID", StandardTagKey::MusicBrainzReleaseGroupId);
m.insert("MUSICBRAINZ WORK ID", StandardTagKey::MusicBrainzWorkId);
m.insert("MusicBrainz Album Artist Id", StandardTagKey::MusicBrainzAlbumArtistId);
m.insert("MusicBrainz Album Id", StandardTagKey::MusicBrainzAlbumId);
m.insert("MusicBrainz Artist Id", StandardTagKey::MusicBrainzArtistId);
m.insert("MusicBrainz Disc Id", StandardTagKey::MusicBrainzDiscId);
m.insert("MusicBrainz Original Album Id", StandardTagKey::MusicBrainzOriginalAlbumId);
m.insert("MusicBrainz Original Artist Id", StandardTagKey::MusicBrainzOriginalArtistId);
m.insert("MusicBrainz Release Group Id", StandardTagKey::MusicBrainzReleaseGroupId);
m.insert("MusicBrainz Album Status", StandardTagKey::MusicBrainzReleaseStatus);
m.insert("MusicBrainz Release Track Id", StandardTagKey::MusicBrainzTrackId);
m.insert("MusicBrainz Work Id", StandardTagKey::MusicBrainzWorkId);
m.insert("REPLAYGAIN_ALBUM_GAIN", StandardTagKey::ReplayGainAlbumGain);
m.insert("REPLAYGAIN_ALBUM_PEAK", StandardTagKey::ReplayGainAlbumPeak);
m.insert("REPLAYGAIN_TRACK_GAIN", StandardTagKey::ReplayGainTrackGain);
Expand Down Expand Up @@ -708,6 +713,40 @@ fn read_txxx_frame(
Ok(FrameResult::MultipleTags(tags))
}

fn read_ufid_frame(
reader: &mut BufReader<'_>,
_: Option<StandardTagKey>,
_: &str,
) -> Result<FrameResult> {
// UFID frames are always encoded as Latin-1
/*
// The first byte of the frame is the encoding.
let encoding = match Encoding::parse(reader.read_byte()?) {
Some(encoding) => encoding,
_ => return decode_error("id3v2: invalid UFID text encoding"),
};
*/

// Read the description string.
let desc = scan_text(reader, Encoding::Iso8859_1, reader.bytes_available() as usize)?;

let std_key = if desc.as_ref() == "http://musicbrainz.org" {
Some(StandardTagKey::MusicBrainzRecordingId)
}
else {
None
};

// Generate a key name using the description.
let key = format!("UFID:{}", desc);

// Read the actual tag data
let data = reader.read_boxed_slice_exact(reader.bytes_available() as usize).unwrap();
let tag = Tag::new(std_key, &key, Value::Binary(data));

Ok(FrameResult::Tag(tag))
}

/// Reads all URL frames except for `WXXX`.
fn read_url_frame(
reader: &mut BufReader<'_>,
Expand Down
4 changes: 2 additions & 2 deletions symphonia-metadata/src/itunes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ lazy_static! {
);
m.insert(
"com.apple.iTunes:MusicBrainz Release Track Id",
StandardTagKey::MusicBrainzReleaseTrackId,
StandardTagKey::MusicBrainzTrackId,
);
m.insert("com.apple.iTunes:MusicBrainz Track Id", StandardTagKey::MusicBrainzTrackId);
m.insert("com.apple.iTunes:MusicBrainz Track Id", StandardTagKey::MusicBrainzRecordingId);
m.insert("com.apple.iTunes:MusicBrainz Work Id", StandardTagKey::MusicBrainzWorkId);
m.insert("com.apple.iTunes:originaldate", StandardTagKey::OriginalDate);
m.insert("com.apple.iTunes:PRODUCER", StandardTagKey::Producer);
Expand Down
4 changes: 2 additions & 2 deletions symphonia-metadata/src/vorbis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ lazy_static! {
m.insert("musicbrainz_originalartistid", StandardTagKey::MusicBrainzOriginalArtistId);
m.insert("musicbrainz_recordingid" , StandardTagKey::MusicBrainzRecordingId);
m.insert("musicbrainz_releasegroupid" , StandardTagKey::MusicBrainzReleaseGroupId);
m.insert("musicbrainz_releasetrackid" , StandardTagKey::MusicBrainzReleaseTrackId);
m.insert("musicbrainz_trackid" , StandardTagKey::MusicBrainzTrackId);
m.insert("musicbrainz_trackid" , StandardTagKey::MusicBrainzRecordingId);
m.insert("musicbrainz_releasetrackid" , StandardTagKey::MusicBrainzTrackId);
m.insert("musicbrainz_workid" , StandardTagKey::MusicBrainzWorkId);
m.insert("opus" , StandardTagKey::Opus);
m.insert("organization" , StandardTagKey::Label);
Expand Down
12 changes: 6 additions & 6 deletions symphonia-play/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,8 @@ fn print_format(path: &str, probed: &mut ProbeResult) {
// Prefer metadata that's provided in the container format, over other tags found during the
// probe operation.
if let Some(metadata_rev) = probed.format.metadata().current() {
print_tags(metadata_rev.tags());
print_visuals(metadata_rev.visuals());
print_tags(metadata_rev.tags.as_ref());
print_visuals(metadata_rev.visuals.as_ref());

// Warn that certain tags are preferred.
if probed.metadata.get().as_ref().is_some() {
Expand All @@ -444,8 +444,8 @@ fn print_format(path: &str, probed: &mut ProbeResult) {
}
}
else if let Some(metadata_rev) = probed.metadata.get().as_ref().and_then(|m| m.current()) {
print_tags(metadata_rev.tags());
print_visuals(metadata_rev.visuals());
print_tags(metadata_rev.tags.as_ref());
print_visuals(metadata_rev.visuals.as_ref());
}

print_cues(probed.format.cues());
Expand All @@ -454,8 +454,8 @@ fn print_format(path: &str, probed: &mut ProbeResult) {
}

fn print_update(rev: &MetadataRevision) {
print_tags(rev.tags());
print_visuals(rev.visuals());
print_tags(rev.tags.as_ref());
print_visuals(rev.visuals.as_ref());
println!(":");
println!();
}
Expand Down