add support for mka files

add ext, minor tweaks to parse out info from matroska tags
pull/3118/head
sharinganthief 6 months ago
parent 89f3d8167b
commit 9c3495f992

@ -88,7 +88,7 @@ namespace NzbDrone.Core.Test.ParserTests
[Test]
public void should_parse_null_quality_description_as_unknown()
{
QualityParser.ParseCodec(null, null).Should().Be(Codec.Unknown);
QualityParser.ParseCodec(null).Should().Be(Codec.Unknown);
}
[TestCase("Author Title - Book Title 2017 REPACK FLAC aAF", true)]

@ -159,7 +159,7 @@ namespace NzbDrone.Core.MediaFiles
Logger.Debug("Audio Properties: " + acodec.Description + ", Bitrate: " + bitrate + ", Sample Size: " +
file.Properties.BitsPerSample + ", SampleRate: " + acodec.AudioSampleRate + ", Channels: " + acodec.AudioChannels);
Quality = QualityParser.ParseQuality(file.Name, acodec.Description);
Quality = QualityParser.ParseQuality(file.Name, acodec);
Logger.Debug($"Quality parsed: {Quality}, Source: {Quality.QualityDetectionSource}");
MediaInfo = new MediaInfoModel

@ -34,6 +34,7 @@ namespace NzbDrone.Core.MediaFiles
{ ".m4a", Quality.MP3 },
{ ".m4p", Quality.MP3 },
{ ".m4b", Quality.M4B },
{ ".mka", Quality.M4B },
{ ".aac", Quality.MP3 },
{ ".mp4a", Quality.MP3 },
{ ".ogg", Quality.MP3 },

@ -56,7 +56,7 @@ namespace NzbDrone.Core.MediaFiles
public static string FormatAudioCodec(MediaInfoModel mediaInfo)
{
var codec = QualityParser.ParseCodec(mediaInfo.AudioFormat, null);
var codec = QualityParser.ParseCodec(mediaInfo.AudioFormat);
if (CodecNames.ContainsKey(codec))
{

@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Qualities;
using TagLib;
using TagLib.Matroska;
namespace NzbDrone.Core.Parser
{
@ -26,36 +29,44 @@ namespace NzbDrone.Core.Parser
private static readonly Regex RealRegex = new Regex(@"\b(?<real>REAL)\b",
RegexOptions.Compiled);
private static readonly Regex CodecRegex = new Regex(@"\b(?:(?<PDF>PDF)|(?<MOBI>MOBI)|(?<EPUB>EPUB)|(?<AZW3>AZW3?)|(?<MP1>MPEG Version \d(.5)? Audio, Layer 1|MP1)|(?<MP2>MPEG Version \d(.5)? Audio, Layer 2|MP2)|(?<MP3VBR>MP3.*VBR|MPEG Version \d(.5)? Audio, Layer 3 vbr)|(?<MP3CBR>MP3|MPEG Version \d(.5)? Audio, Layer 3)|(?<FLAC>flac)|(?<WAVPACK>wavpack|wv)|(?<ALAC>alac)|(?<WMA>WMA\d?)|(?<WAV>WAV|PCM)|(?<AAC>M4A|M4P|M4B|AAC|mp4a|MPEG-4 Audio(?!.*alac))|(?<OGG>OGG|OGA|Vorbis))\b|(?<APE>monkey's audio|[\[|\(].*\bape\b.*[\]|\)])|(?<OPUS>Opus Version \d(.5)? Audio|[\[|\(].*\bopus\b.*[\]|\)])",
private static readonly Regex CodecRegex = new Regex(@"\b(?:(?<PDF>PDF)|(?<MOBI>MOBI)|(?<EPUB>EPUB)|(?<AZW3>AZW3?)||(?<MP1>MPEG Version \d(.5)? Audio, Layer 1|MP1)|(?<MP2>MPEG Version \d(.5)? Audio, Layer 2|MP2)|(?<MP3VBR>MP3.*VBR|MPEG Version \d(.5)? Audio, Layer 3 vbr)|(?<MP3CBR>MP3|MPEG Version \d(.5)? Audio, Layer 3)|(?<FLAC>flac)|(?<WAVPACK>wavpack|wv)|(?<ALAC>alac)|(?<WMA>WMA\d?)|(?<WAV>WAV|PCM)|(?<AAC>MKA|M4A|M4P|M4B|AAC|mp4a|MPEG-4 Audio(?!.*alac))|(?<OGG>OGG|OGA|Vorbis))\b|(?<APE>monkey's audio|[\[|\(].*\bape\b.*[\]|\)])|(?<OPUS>Opus Version \d(.5)? Audio|[\[|\(].*\bopus\b.*[\]|\)])",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static QualityModel ParseQuality(string name, string desc = null, List<int> categories = null)
public static QualityModel ParseQuality(string name, IAudioCodec audioCodec = null, List<int> categories = null)
{
Logger.Debug("Trying to parse quality for '{0}'", name);
if (name.IsNullOrWhiteSpace() && desc.IsNullOrWhiteSpace())
{
return new QualityModel { Quality = Quality.Unknown };
}
var normalizedName = name.Replace('_', ' ').Trim().ToLower();
var result = ParseQualityModifiers(name, normalizedName);
if (desc.IsNotNullOrWhiteSpace())
{
var descCodec = ParseCodec(desc, "");
Logger.Trace($"Got codec {descCodec}");
var codec = Codec.Unknown;
result.Quality = FindQuality(descCodec);
if (audioCodec != null)
{
if (audioCodec is AudioTrack matroskaCodec)
{
codec = ParseCodec(StealCodecFromMatroskaTrack(matroskaCodec));
}
if (result.Quality != Quality.Unknown)
if (codec == Codec.Unknown && audioCodec!.Description.IsNotNullOrWhiteSpace())
{
result.QualityDetectionSource = QualityDetectionSource.TagLib;
return result;
var descCodec = ParseCodec(audioCodec.Description);
Logger.Trace($"Got codec {descCodec}");
result.Quality = FindQuality(descCodec);
if (result.Quality != Quality.Unknown)
{
result.QualityDetectionSource = QualityDetectionSource.TagLib;
return result;
}
}
}
var codec = ParseCodec(normalizedName, name);
if (codec == Codec.Unknown)
{
codec = ParseCodec(normalizedName);
}
switch (codec)
{
@ -77,6 +88,7 @@ namespace NzbDrone.Core.Parser
result.Quality = Quality.FLAC;
break;
case Codec.AAC:
case Codec.AAC2:
result.Quality = Quality.M4B;
break;
case Codec.MP1:
@ -125,7 +137,21 @@ namespace NzbDrone.Core.Parser
return result;
}
public static Codec ParseCodec(string name, string origName)
private static string StealCodecFromMatroskaTrack(AudioTrack matroskaCodec)
{
var field = typeof(Track)
.GetField("track_codec_id", BindingFlags.NonPublic | BindingFlags.Instance);
if (field == null)
{
return null;
}
var val = ((string)field.GetValue(matroskaCodec) ?? string.Empty).Replace("A_", string.Empty);
return val;
}
public static Codec ParseCodec(string name)
{
if (name.IsNullOrWhiteSpace())
{
@ -179,7 +205,7 @@ namespace NzbDrone.Core.Parser
return Codec.WAV;
}
if (match.Groups["AAC"].Success)
if (match.Groups["AAC"].Success || name.Equals("AAC"))
{
return Codec.AAC;
}
@ -289,6 +315,7 @@ namespace NzbDrone.Core.Parser
WAVPACK,
WMA,
AAC,
AAC2,
AACVBR,
OGG,
OPUS,

Loading…
Cancel
Save