aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers/MediaInfo
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Providers/MediaInfo')
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioFileProber.cs56
-rw-r--r--MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs4
2 files changed, 42 insertions, 18 deletions
diff --git a/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs b/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs
index b504da48f..916e2625b 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs
@@ -20,6 +20,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.MediaInfo;
using Microsoft.Extensions.Logging;
+using static Jellyfin.Extensions.StringExtensions;
namespace MediaBrowser.Providers.MediaInfo
{
@@ -175,11 +176,15 @@ namespace MediaBrowser.Providers.MediaInfo
_logger.LogWarning("File {File} only has ID3v1 tags, some fields may be truncated", audio.Path);
}
- track.Title = string.IsNullOrEmpty(track.Title) ? mediaInfo.Name : track.Title;
- track.Album = string.IsNullOrEmpty(track.Album) ? mediaInfo.Album : track.Album;
- track.Year ??= mediaInfo.ProductionYear;
- track.TrackNumber ??= mediaInfo.IndexNumber;
- track.DiscNumber ??= mediaInfo.ParentIndexNumber;
+ // We should never use the property setter of the ATL.Track class.
+ // That setter is meant for its own tag parser and external editor usage and will have unwanted side effects
+ // For example, setting the Year property will also set the Date property, which is not what we want here.
+ // To properly handle fallback values, we make a clone of those fields when valid.
+ var trackTitle = (string.IsNullOrEmpty(track.Title) ? mediaInfo.Name : track.Title).Trim();
+ var trackAlbum = (string.IsNullOrEmpty(track.Album) ? mediaInfo.Album : track.Album).Trim();
+ var trackYear = track.Year is null or 0 ? mediaInfo.ProductionYear : track.Year;
+ var trackTrackNumber = track.TrackNumber is null or 0 ? mediaInfo.IndexNumber : track.TrackNumber;
+ var trackDiscNumber = track.DiscNumber is null or 0 ? mediaInfo.ParentIndexNumber : track.DiscNumber;
if (audio.SupportsPeople && !audio.LockedFields.Contains(MetadataField.Cast))
{
@@ -276,22 +281,22 @@ namespace MediaBrowser.Providers.MediaInfo
}
}
- if (!audio.LockedFields.Contains(MetadataField.Name) && !string.IsNullOrEmpty(track.Title))
+ if (!audio.LockedFields.Contains(MetadataField.Name) && !string.IsNullOrEmpty(trackTitle))
{
- audio.Name = track.Title;
+ audio.Name = trackTitle;
}
if (options.ReplaceAllMetadata)
{
- audio.Album = track.Album.Trim();
- audio.IndexNumber = track.TrackNumber;
- audio.ParentIndexNumber = track.DiscNumber;
+ audio.Album = trackAlbum;
+ audio.IndexNumber = trackTrackNumber;
+ audio.ParentIndexNumber = trackDiscNumber;
}
else
{
- audio.Album ??= track.Album.Trim();
- audio.IndexNumber ??= track.TrackNumber;
- audio.ParentIndexNumber ??= track.DiscNumber;
+ audio.Album ??= trackAlbum;
+ audio.IndexNumber ??= trackTrackNumber;
+ audio.ParentIndexNumber ??= trackDiscNumber;
}
if (track.Date.HasValue)
@@ -299,11 +304,12 @@ namespace MediaBrowser.Providers.MediaInfo
audio.PremiereDate = track.Date;
}
- if (track.Year.HasValue)
+ if (trackYear.HasValue)
{
- var year = track.Year.Value;
+ var year = trackYear.Value;
audio.ProductionYear = year;
+ // ATL library handles such fallback this with its own internal logic, but we also need to handle it here for the ffprobe fallbacks.
if (!audio.PremiereDate.HasValue)
{
try
@@ -312,7 +318,7 @@ namespace MediaBrowser.Providers.MediaInfo
}
catch (ArgumentOutOfRangeException ex)
{
- _logger.LogError(ex, "Error parsing YEAR tag in {File}. '{TagValue}' is an invalid year", audio.Path, track.Year);
+ _logger.LogError(ex, "Error parsing YEAR tag in {File}. '{TagValue}' is an invalid year", audio.Path, trackYear);
}
}
}
@@ -403,6 +409,24 @@ namespace MediaBrowser.Providers.MediaInfo
}
}
+ if (options.ReplaceAllMetadata || !audio.TryGetProviderId(MetadataProvider.MusicBrainzRecording, out _))
+ {
+ if ((track.AdditionalFields.TryGetValue("MUSICBRAINZ_TRACKID", out var recordingMbId)
+ || track.AdditionalFields.TryGetValue("MusicBrainz Track Id", out recordingMbId))
+ && !string.IsNullOrEmpty(recordingMbId))
+ {
+ audio.TrySetProviderId(MetadataProvider.MusicBrainzRecording, recordingMbId);
+ }
+ else if (track.AdditionalFields.TryGetValue("UFID", out var ufIdValue) && !string.IsNullOrEmpty(ufIdValue))
+ {
+ // If tagged with MB Picard, the format is 'http://musicbrainz.org\0<recording MBID>'
+ if (ufIdValue.Contains("musicbrainz.org", StringComparison.OrdinalIgnoreCase))
+ {
+ audio.TrySetProviderId(MetadataProvider.MusicBrainzRecording, ufIdValue.AsSpan().RightPart('\0').ToString());
+ }
+ }
+ }
+
// Save extracted lyrics if they exist,
// and if the audio doesn't yet have lyrics.
var lyrics = track.Lyrics.SynchronizedLyrics.Count > 0 ? track.Lyrics.FormatSynchToLRC() : track.Lyrics.UnsynchronizedLyrics;
diff --git a/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs b/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs
index f12390bc2..0716cdfa0 100644
--- a/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs
+++ b/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs
@@ -119,9 +119,9 @@ namespace MediaBrowser.Providers.MediaInfo
|| (mediaStream.Type == MediaStreamType.Subtitle && _type == DlnaProfileType.Subtitle))
{
mediaStream.Index = startIndex++;
- mediaStream.IsDefault = pathInfo.IsDefault || mediaStream.IsDefault;
+ mediaStream.IsDefault = pathInfo.IsDefault;
mediaStream.IsForced = pathInfo.IsForced || mediaStream.IsForced;
- mediaStream.IsHearingImpaired = pathInfo.IsHearingImpaired || mediaStream.IsHearingImpaired.GetValueOrDefault();
+ mediaStream.IsHearingImpaired = pathInfo.IsHearingImpaired || mediaStream.IsHearingImpaired;
mediaStreams.Add(MergeMetadata(mediaStream, pathInfo));
}