Fixed: Import failures when audio channels are in an unexpected format

Fixes #2318
This commit is contained in:
Mark McDowall 2017-12-03 19:58:31 -08:00
parent 9d7547e941
commit 4399d272dc
No known key found for this signature in database
GPG Key ID: D4CEFA9A718052E0
2 changed files with 108 additions and 29 deletions

View File

@ -145,5 +145,33 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(2.0m);
}
[Test]
public void should_use_AudioChannelPositionText_when_AudioChannelChannelPosition_is_invalid()
{
var mediaInfoModel = new MediaInfoModel
{
AudioChannels = 6,
AudioChannelPositions = "15 objects",
AudioChannelPositionsText = "15 objects / Front: L C R, Side: L R, LFE",
SchemaRevision = 3
};
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
}
[Test]
public void should_remove_atmos_objects_from_AudioChannelPostions()
{
var mediaInfoModel = new MediaInfoModel
{
AudioChannels = 2,
AudioChannelPositions = "15 objects / 3/2.1",
AudioChannelPositionsText = null,
SchemaRevision = 3
};
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
}
}
}

View File

@ -2,6 +2,7 @@ using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NLog;
using NLog.Fluent;
using NzbDrone.Common.Extensions;
@ -16,42 +17,19 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
public static decimal FormatAudioChannels(MediaInfoModel mediaInfo)
{
var audioChannelPositions = mediaInfo.AudioChannelPositions;
var audioChannelPositionsText = mediaInfo.AudioChannelPositionsText;
var audioChannels = mediaInfo.AudioChannels;
var audioChannels = FormatAudioChannelsFromAudioChannelPositions(mediaInfo);
if (audioChannelPositions.IsNullOrWhiteSpace())
if (audioChannels == null)
{
if (audioChannelPositionsText.IsNullOrWhiteSpace())
{
if (mediaInfo.SchemaRevision >= 3)
{
Logger.Debug("Formatiting audio channels using 'AudioChannels', with a value of: '{0}'", audioChannels);
return audioChannels;
audioChannels = FormatAudioChannelsFromAudioChannelPositionsText(mediaInfo);
}
return 0;
}
Logger.Debug("Formatiting audio channels using 'AudioChannelPositionsText', with a value of: '{0}'", audioChannelPositionsText);
return mediaInfo.AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? audioChannels - 1 + 0.1m : audioChannels;
}
Logger.Debug("Formatiting audio channels using 'AudioChannelPositions', with a value of: '{0}'", audioChannelPositions);
if (audioChannelPositions.Contains("+"))
if (audioChannels == null)
{
return audioChannelPositions.Split('+')
.Sum(s => decimal.Parse(s.Trim(), CultureInfo.InvariantCulture));
audioChannels = FormatAudioChannelsFromAudioChannels(mediaInfo);
}
return audioChannelPositions.Replace("Object Based / ", "")
.Split(new string[] { " / " }, StringSplitOptions.RemoveEmptyEntries)
.First()
.Split('/')
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture));
return audioChannels ?? 0;
}
public static string FormatAudioCodec(MediaInfoModel mediaInfo, string sceneName)
@ -360,6 +338,79 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
return videoCodec;
}
private static decimal? FormatAudioChannelsFromAudioChannelPositions(MediaInfoModel mediaInfo)
{
var audioChannelPositions = mediaInfo.AudioChannelPositions;
if (audioChannelPositions.IsNullOrWhiteSpace())
{
return null;
}
try
{
Logger.Debug("Formatiting audio channels using 'AudioChannelPositions', with a value of: '{0}'", audioChannelPositions);
if (audioChannelPositions.Contains("+"))
{
return audioChannelPositions.Split('+')
.Sum(s => decimal.Parse(s.Trim(), CultureInfo.InvariantCulture));
}
return Regex.Replace(audioChannelPositions, @"^\d+\sobjects", "", RegexOptions.Compiled | RegexOptions.IgnoreCase)
.Replace("Object Based / ", "")
.Split(new string[] { " / " }, StringSplitOptions.RemoveEmptyEntries)
.FirstOrDefault()
?.Split('/')
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture));
}
catch (Exception e)
{
Logger.Warn(e, "Unable to format audio channels using 'AudioChannelPositions'");
}
return null;
}
private static decimal? FormatAudioChannelsFromAudioChannelPositionsText(MediaInfoModel mediaInfo)
{
var audioChannelPositionsText = mediaInfo.AudioChannelPositionsText;
var audioChannels = mediaInfo.AudioChannels;
if (audioChannelPositionsText.IsNullOrWhiteSpace())
{
return null;
}
try
{
Logger.Debug("Formatiting audio channels using 'AudioChannelPositionsText', with a value of: '{0}'", audioChannelPositionsText);
return mediaInfo.AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? audioChannels - 1 + 0.1m : audioChannels;
}
catch (Exception e)
{
Logger.Warn(e, "Unable to format audio channels using 'AudioChannelPositionsText'");
}
return null;
}
private static decimal? FormatAudioChannelsFromAudioChannels(MediaInfoModel mediaInfo)
{
var audioChannels = mediaInfo.AudioChannels;
if (mediaInfo.SchemaRevision >= 3)
{
Logger.Debug("Formatiting audio channels using 'AudioChannels', with a value of: '{0}'", audioChannels);
return audioChannels;
}
return null;
}
private static string GetSceneNameMatch(string sceneName, params string[] tokens)
{
sceneName = sceneName.IsNotNullOrWhiteSpace() ? Path.GetFileNameWithoutExtension(sceneName) : string.Empty;