1
0
Fork 0
mirror of https://github.com/Sonarr/Sonarr synced 2024-12-26 01:37:07 +00:00

New: Added support for DTS-HD MA and TrueHD Atmos in MediaInfo AudioCodec.

This commit is contained in:
Matt Evans 2019-02-03 16:52:37 +11:00
parent e5632019db
commit 1606ea19a8
6 changed files with 92 additions and 20 deletions

View file

@ -91,6 +91,11 @@ namespace NzbDrone.Common.Extensions
return text.StartsWith(startsWith, StringComparison.InvariantCultureIgnoreCase); return text.StartsWith(startsWith, StringComparison.InvariantCultureIgnoreCase);
} }
public static bool EndsWithIgnoreCase(this string text, string startsWith)
{
return text.EndsWith(startsWith, StringComparison.InvariantCultureIgnoreCase);
}
public static bool EqualsIgnoreCase(this string text, string equals) public static bool EqualsIgnoreCase(this string text, string equals)
{ {
return text.Equals(equals, StringComparison.InvariantCultureIgnoreCase); return text.Equals(equals, StringComparison.InvariantCultureIgnoreCase);
@ -140,5 +145,10 @@ namespace NzbDrone.Common.Extensions
{ {
return CamelCaseRegex.Replace(input, match => " " + match.Value); return CamelCaseRegex.Replace(input, match => " " + match.Value);
} }
public static bool ContainsIgnoreCase(this IEnumerable<string> source, string value)
{
return source.Contains(value, StringComparer.InvariantCultureIgnoreCase);
}
} }
} }

View file

@ -24,14 +24,26 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests
MediaInfoFormatter.FormatAudioCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat); MediaInfoFormatter.FormatAudioCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat);
} }
[TestCase("MPEG Audio, A_MPEG/L2, , ", "droned.s01e03.swedish.720p.hdtv.x264-prince", "MP2")] [TestCase("MPEG Audio, A_MPEG/L2, , , ", "droned.s01e03.swedish.720p.hdtv.x264-prince", "MP2")]
[TestCase("Vorbis, A_VORBIS, , Xiph.Org libVorbis I 20101101 (Schaufenugget)", "DB Super HDTV", "Vorbis")] [TestCase("Vorbis, A_VORBIS, , Xiph.Org libVorbis I 20101101 (Schaufenugget), ", "DB Super HDTV", "Vorbis")]
[TestCase("PCM, 1, , ", "DW DVDRip XviD-idTV", "PCM")] // Dubbed most likely [TestCase("PCM, 1, , , ", "DW DVDRip XviD-idTV, ", "PCM")] // Dubbed most likely
[TestCase("TrueHD, A_TRUEHD, , ", "", "TrueHD")] [TestCase("TrueHD, A_TRUEHD, , , ", "", "TrueHD")]
[TestCase("WMA, 161, , ", "Droned.wmv", "WMA")] [TestCase("MLP FBA, A_TRUEHD, , , ", "TrueHD", "TrueHD")]
[TestCase("WMA, 162, Pro, ", "B.N.S04E18.720p.WEB-DL", "WMA")] [TestCase("MLP FBA, A_TRUEHD, , , 16-ch", "Atmos", "TrueHD Atmos")]
[TestCase("Opus, A_OPUS, , ", "Roadkill Ep3x11 - YouTube.webm", "Opus")] [TestCase("WMA, 161, , , ", "Droned.wmv", "WMA")]
[TestCase("mp3 , 0, , ", "climbing.mp4", "MP3")] [TestCase("WMA, 162, Pro, , ", "B.N.S04E18.720p.WEB-DL", "WMA")]
[TestCase("Opus, A_OPUS, , , ", "Roadkill Ep3x11 - YouTube.webm", "Opus")]
[TestCase("mp3 , 0, , , ", "climbing.mp4", "MP3")]
[TestCase("DTS, A_DTS, , , XLL", "DTS-HD.MA", "DTS-HD MA")]
[TestCase("DTS, A_DTS, , , XLL X", "DTS-X", "DTS-X")]
[TestCase("DTS, A_DTS, , , ES XLL", "DTS-HD.MA", "DTS-HD MA")]
[TestCase("DTS, A_DTS, , , ES", "DTS-ES", "DTS-ES")]
[TestCase("DTS, A_DTS, , , ES XXCH", "DTS", "DTS-ES")]
[TestCase("DTS, A_DTS, , , XBR", "DTSHD-HRA", "DTS-HD HRA")]
[TestCase("DTS, A_DTS, , , DTS", "DTS", "DTS")]
[TestCase("E-AC-3, A_EAC3, , , JOC", "EAC3", "EAC3")]
[TestCase("E-AC-3, A_EAC3, , , ", "DD5.1", "EAC3")]
[TestCase("AC-3, A_AC3, , , ", "DD5.1", "AC3")]
public void should_format_audio_format(string audioFormatPack, string sceneName, string expectedFormat) public void should_format_audio_format(string audioFormatPack, string sceneName, string expectedFormat)
{ {
var split = audioFormatPack.Split(new string[] { ", " }, System.StringSplitOptions.None); var split = audioFormatPack.Split(new string[] { ", " }, System.StringSplitOptions.None);
@ -40,7 +52,8 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests
AudioFormat = split[0], AudioFormat = split[0],
AudioCodecID = split[1], AudioCodecID = split[1],
AudioProfile = split[2], AudioProfile = split[2],
AudioCodecLibrary = split[3] AudioCodecLibrary = split[3],
AudioAdditionalFeatures = split[4]
}; };
MediaInfoFormatter.FormatAudioCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat); MediaInfoFormatter.FormatAudioCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat);

View file

@ -59,6 +59,9 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
info.VideoBitrate.Should().Be(193329); info.VideoBitrate.Should().Be(193329);
info.VideoFps.Should().Be(24); info.VideoFps.Should().Be(24);
info.Width.Should().Be(480); info.Width.Should().Be(480);
info.VideoColourPrimaries.Should().Be("BT.601 NTSC");
info.VideoTransferCharacteristics.Should().Be("BT.709");
info.AudioAdditionalFeatures.Should().Be("");
} }
@ -95,6 +98,9 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
info.VideoBitrate.Should().Be(193329); info.VideoBitrate.Should().Be(193329);
info.VideoFps.Should().Be(24); info.VideoFps.Should().Be(24);
info.Width.Should().Be(480); info.Width.Should().Be(480);
info.VideoColourPrimaries.Should().Be("BT.601 NTSC");
info.VideoTransferCharacteristics.Should().Be("BT.709");
info.AudioAdditionalFeatures.Should().Be("");
} }
[Test] [Test]

View file

@ -43,6 +43,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
var audioCodecID = mediaInfo.AudioCodecID ?? string.Empty; var audioCodecID = mediaInfo.AudioCodecID ?? string.Empty;
var audioProfile = mediaInfo.AudioProfile ?? string.Empty; var audioProfile = mediaInfo.AudioProfile ?? string.Empty;
var audioCodecLibrary = mediaInfo.AudioCodecLibrary ?? string.Empty; var audioCodecLibrary = mediaInfo.AudioCodecLibrary ?? string.Empty;
var splitAdditionalFeatures = (mediaInfo.AudioAdditionalFeatures ?? string.Empty).Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
if (audioFormat.IsNullOrWhiteSpace()) if (audioFormat.IsNullOrWhiteSpace())
{ {
@ -71,6 +72,25 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
if (audioFormat.EqualsIgnoreCase("DTS")) if (audioFormat.EqualsIgnoreCase("DTS"))
{ {
if (splitAdditionalFeatures.ContainsIgnoreCase("XLL"))
{
if (splitAdditionalFeatures.ContainsIgnoreCase("X"))
{
return "DTS-X";
}
return "DTS-HD MA";
}
if (splitAdditionalFeatures.ContainsIgnoreCase("ES"))
{
return "DTS-ES";
}
if (splitAdditionalFeatures.ContainsIgnoreCase("XBR"))
{
return "DTS-HD HRA";
}
return "DTS"; return "DTS";
} }
@ -112,6 +132,16 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
return "TrueHD"; return "TrueHD";
} }
if (audioFormat.EqualsIgnoreCase("MLP FBA"))
{
if (splitAdditionalFeatures.ContainsIgnoreCase("16-ch"))
{
return "TrueHD Atmos";
}
return "TrueHD";
}
if (audioFormat.EqualsIgnoreCase("Vorbis")) if (audioFormat.EqualsIgnoreCase("Vorbis"))
{ {
return "Vorbis"; return "Vorbis";
@ -373,13 +403,16 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
.Sum(s => decimal.Parse(s.Trim(), CultureInfo.InvariantCulture)); .Sum(s => decimal.Parse(s.Trim(), CultureInfo.InvariantCulture));
} }
if (audioChannelPositions.Contains("/"))
return Regex.Replace(audioChannelPositions, @"^\d+\sobjects", "", RegexOptions.Compiled | RegexOptions.IgnoreCase) {
.Replace("Object Based / ", "") return Regex.Replace(audioChannelPositions, @"^\d+\sobjects", "",
.Split(new string[] { " / " }, StringSplitOptions.RemoveEmptyEntries) RegexOptions.Compiled | RegexOptions.IgnoreCase)
.FirstOrDefault() .Replace("Object Based / ", "")
?.Split('/') .Split(new string[] {" / "}, StringSplitOptions.RemoveEmptyEntries)
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture)); .FirstOrDefault()
?.Split('/')
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture));
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -401,7 +434,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
try try
{ {
return mediaInfo.AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? audioChannels - 1 + 0.1m : audioChannels; return audioChannelPositionsText.ContainsIgnoreCase("LFE") ? audioChannels - 1 + 0.1m : audioChannels;
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -18,11 +18,15 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
public string VideoCodecLibrary { get; set; } public string VideoCodecLibrary { get; set; }
public int VideoBitrate { get; set; } public int VideoBitrate { get; set; }
public int VideoBitDepth { get; set; } public int VideoBitDepth { get; set; }
public int VideoMultiViewCount { get; set; }
public string VideoColourPrimaries { get; set; }
public string VideoTransferCharacteristics { get; set; }
public int Width { get; set; } public int Width { get; set; }
public int Height { get; set; } public int Height { get; set; }
public string AudioFormat { get; set; } public string AudioFormat { get; set; }
public string AudioCodecID { get; set; } public string AudioCodecID { get; set; }
public string AudioCodecLibrary { get; set; } public string AudioCodecLibrary { get; set; }
public string AudioAdditionalFeatures { get; set; }
public int AudioBitrate { get; set; } public int AudioBitrate { get; set; }
public TimeSpan RunTime { get; set; } public TimeSpan RunTime { get; set; }
public int AudioStreamCount { get; set; } public int AudioStreamCount { get; set; }

View file

@ -18,7 +18,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
private readonly Logger _logger; private readonly Logger _logger;
public const int MINIMUM_MEDIA_INFO_SCHEMA_REVISION = 3; public const int MINIMUM_MEDIA_INFO_SCHEMA_REVISION = 3;
public const int CURRENT_MEDIA_INFO_SCHEMA_REVISION = 4; public const int CURRENT_MEDIA_INFO_SCHEMA_REVISION = 5;
public VideoFileInfoReader(IDiskProvider diskProvider, Logger logger) public VideoFileInfoReader(IDiskProvider diskProvider, Logger logger)
{ {
@ -94,18 +94,20 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
int audioChannels; int audioChannels;
int videoBitDepth; int videoBitDepth;
decimal videoFrameRate; decimal videoFrameRate;
int videoMultiViewCount;
string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List"); string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
string scanType = mediaInfo.Get(StreamKind.Video, 0, "ScanType"); string scanType = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width); int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height); int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate_Nominal"), out videoBitRate); int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);
if (videoBitRate <= 0) if (videoBitRate <= 0)
{ {
int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate); int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate_Nominal"), out videoBitRate);
} }
decimal.TryParse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out videoFrameRate); decimal.TryParse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out videoFrameRate);
int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitDepth"), out videoBitDepth); int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitDepth"), out videoBitDepth);
int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "MultiView_Count"), out videoMultiViewCount);
//Runtime //Runtime
int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime); int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
@ -138,12 +140,16 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
VideoCodecLibrary = mediaInfo.Get(StreamKind.Video, 0, "Encoded_Library"), VideoCodecLibrary = mediaInfo.Get(StreamKind.Video, 0, "Encoded_Library"),
VideoBitrate = videoBitRate, VideoBitrate = videoBitRate,
VideoBitDepth = videoBitDepth, VideoBitDepth = videoBitDepth,
VideoMultiViewCount = videoMultiViewCount,
VideoColourPrimaries = mediaInfo.Get(StreamKind.Video, 0, "colour_primaries"),
VideoTransferCharacteristics = mediaInfo.Get(StreamKind.Video, 0, "transfer_characteristics"),
Height = height, Height = height,
Width = width, Width = width,
AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"), AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
AudioCodecID = mediaInfo.Get(StreamKind.Audio, 0, "CodecID"), AudioCodecID = mediaInfo.Get(StreamKind.Audio, 0, "CodecID"),
AudioProfile = audioProfile, AudioProfile = audioProfile,
AudioCodecLibrary = mediaInfo.Get(StreamKind.Audio, 0, "Encoded_Library"), AudioCodecLibrary = mediaInfo.Get(StreamKind.Audio, 0, "Encoded_Library"),
AudioAdditionalFeatures = mediaInfo.Get(StreamKind.Audio, 0, "Format_AdditionalFeatures"),
AudioBitrate = audioBitRate, AudioBitrate = audioBitRate,
RunTime = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime), RunTime = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime),
AudioStreamCount = streamCount, AudioStreamCount = streamCount,