From f35a527608fb3f6efde3f76042e0e701768eb3f2 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 27 Jul 2021 17:09:23 +0200 Subject: Add performers to the ffprobe normalization for audio --- .../Probing/ProbeResultNormalizer.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs') diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 875ee6f04..20dead077 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Xml; using Jellyfin.Extensions; using MediaBrowser.Controller.Library; @@ -1111,6 +1112,26 @@ namespace MediaBrowser.MediaEncoding.Probing } } + if (tags.TryGetValue("performer", out var performer) && !string.IsNullOrWhiteSpace(performer)) + { + foreach (var person in Split(performer, false)) + { + Regex pattern = new Regex(@"(?.*) \((?.*)\)"); + Match match = pattern.Match(person); + + // If the performer doesn't have any instrument/role associated, it won't match. In that case, chances are it's simply a band name, so we skip it. + if (match.Success) + { + people.Add(new BaseItemPerson + { + Name = match.Groups["name"].Value, + Type = PersonType.Actor, + Role = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(match.Groups["instrument"].Value) + }); + } + } + } + // Check for writer some music is tagged that way as alternative to composer/lyricist if (tags.TryGetValue("writer", out var writer) && !string.IsNullOrWhiteSpace(writer)) { -- cgit v1.2.3 From c9b1cd1d8cfa3764eff3dfe97baac10ce229d2e9 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 27 Jul 2021 23:52:05 +0200 Subject: Add some new music-related person types and parse from ffprobe --- .../Probing/ProbeResultNormalizer.cs | 34 ++++++++++++++++++- MediaBrowser.Model/Entities/PersonType.cs | 38 +++++++++++++++++----- .../Probing/ProbeResultNormalizerTests.cs | 2 +- 3 files changed, 63 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs') diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 20dead077..aa6674468 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -1132,7 +1132,7 @@ namespace MediaBrowser.MediaEncoding.Probing } } - // Check for writer some music is tagged that way as alternative to composer/lyricist + // In cases where there isn't sufficient information as to which role a writer performed on a recording, tagging software uses the "writer" tag. if (tags.TryGetValue("writer", out var writer) && !string.IsNullOrWhiteSpace(writer)) { foreach (var person in Split(writer, false)) @@ -1141,6 +1141,38 @@ namespace MediaBrowser.MediaEncoding.Probing } } + if (tags.TryGetValue("arranger", out var arranger) && !string.IsNullOrWhiteSpace(arranger)) + { + foreach (var person in Split(arranger, false)) + { + people.Add(new BaseItemPerson { Name = person, Type = PersonType.Arranger }); + } + } + + if (tags.TryGetValue("engineer", out var engineer) && !string.IsNullOrWhiteSpace(engineer)) + { + foreach (var person in Split(engineer, false)) + { + people.Add(new BaseItemPerson { Name = person, Type = PersonType.Engineer }); + } + } + + if (tags.TryGetValue("mixer", out var mixer) && !string.IsNullOrWhiteSpace(mixer)) + { + foreach (var person in Split(mixer, false)) + { + people.Add(new BaseItemPerson { Name = person, Type = PersonType.Mixer }); + } + } + + if (tags.TryGetValue("remixer", out var remixer) && !string.IsNullOrWhiteSpace(remixer)) + { + foreach (var person in Split(remixer, false)) + { + people.Add(new BaseItemPerson { Name = person, Type = PersonType.Remixer }); + } + } + audio.People = people.ToArray(); // Set album artist diff --git a/MediaBrowser.Model/Entities/PersonType.cs b/MediaBrowser.Model/Entities/PersonType.cs index 81db9c613..7b780f7d7 100644 --- a/MediaBrowser.Model/Entities/PersonType.cs +++ b/MediaBrowser.Model/Entities/PersonType.cs @@ -1,42 +1,42 @@ namespace MediaBrowser.Model.Entities { /// - /// Struct PersonType. + /// Types of persons. /// - public class PersonType + public static class PersonType { /// - /// The actor. + /// A person whose profession is acting on the stage, in films, or on television. /// public const string Actor = "Actor"; /// - /// The director. + /// A person who supervises the actors and other staff in a film, play, or similar production. /// public const string Director = "Director"; /// - /// The composer. + /// A person who writes music, especially as a professional occupation. /// public const string Composer = "Composer"; /// - /// The writer. + /// A writer of a book, article, or document. Can also be used as a generic term for music writer if there is a lack of specificity. /// public const string Writer = "Writer"; /// - /// The guest star. + /// A well-known actor or other performer who appears in a work in which they do not have a regular role. /// public const string GuestStar = "GuestStar"; /// - /// The producer. + /// A person responsible for the financial and managerial aspects of the making of a film or broadcast or for staging a play, opera, etc. /// public const string Producer = "Producer"; /// - /// The conductor. + /// A person who directs the performance of an orchestra or choir. /// public const string Conductor = "Conductor"; @@ -44,5 +44,25 @@ namespace MediaBrowser.Model.Entities /// The lyricist. /// public const string Lyricist = "Lyricist"; + + /// + /// A person who writes the words to a song or musical. + /// + public const string Arranger = "Arranger"; + + /// + /// An audio engineer who performed a general engineering role. + /// + public const string Engineer = "Engineer"; + + /// + /// An engineer responsible for using a mixing console to mix a recorded track into a single piece of music suitable for release. + /// + public const string Mixer = "Mixer"; + + /// + /// A person who remixed a recording by taking one or more other tracks, substantially altering them and mixing them together with other material. + /// + public const string Remixer = "Remixer"; } } diff --git a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs index 928f275d7..fcb85a3ac 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs @@ -107,7 +107,7 @@ namespace Jellyfin.MediaEncoding.Tests.Probing Assert.Equal(2020, res.ProductionYear); Assert.True(res.PremiereDate.HasValue); Assert.Equal(DateTime.Parse("2020-10-26T00:00Z", DateTimeFormatInfo.CurrentInfo).ToUniversalTime(), res.PremiereDate); - Assert.Equal(18, res.People.Length); + Assert.Equal(22, res.People.Length); Assert.Equal("Krysta Youngs", res.People[0].Name); Assert.Equal(PersonType.Composer, res.People[0].Type); Assert.Equal("Julia Ross", res.People[1].Name); -- cgit v1.2.3 From d82c2e423766566883be850d60e94cc36656f0e8 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 2 Aug 2021 03:48:45 +0200 Subject: Address comments --- MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs') diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index aa6674468..cdfdbc5da 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -28,7 +28,9 @@ namespace MediaBrowser.MediaEncoding.Probing private readonly char[] _nameDelimiters = { '/', '|', ';', '\\' }; - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + private readonly Regex _performerPattern = new (@"(?.*) \((?.*)\)"); + + private readonly CultureInfo _usCulture = new ("en-US"); private readonly ILogger _logger; private readonly ILocalizationManager _localization; @@ -1116,8 +1118,7 @@ namespace MediaBrowser.MediaEncoding.Probing { foreach (var person in Split(performer, false)) { - Regex pattern = new Regex(@"(?.*) \((?.*)\)"); - Match match = pattern.Match(person); + Match match = _performerPattern.Match(person); // If the performer doesn't have any instrument/role associated, it won't match. In that case, chances are it's simply a band name, so we skip it. if (match.Success) -- cgit v1.2.3 From 7f52cda03c9731fcbd57fd8c9ed8806c6965d054 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 7 Aug 2021 21:58:19 +0200 Subject: Make performer regex static --- MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs') diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index cdfdbc5da..e83e533c9 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.MediaEncoding.Probing private readonly char[] _nameDelimiters = { '/', '|', ';', '\\' }; - private readonly Regex _performerPattern = new (@"(?.*) \((?.*)\)"); + private static readonly Regex _performerPattern = new (@"(?.*) \((?.*)\)"); private readonly CultureInfo _usCulture = new ("en-US"); private readonly ILogger _logger; -- cgit v1.2.3