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:
parent
e5632019db
commit
1606ea19a8
6 changed files with 92 additions and 20 deletions
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue