mirror of
https://github.com/Lidarr/Lidarr
synced 2026-05-07 03:52:42 +02:00
Mka Support
add mka support
This commit is contained in:
parent
fd6f97640c
commit
6898ead35d
6 changed files with 68 additions and 4 deletions
|
|
@ -18,7 +18,7 @@
|
|||
<PackageReference Include="SourceGear.sqlite3" Version="3.50.4.2" />
|
||||
<PackageReference Include="System.Data.SQLite" Version="2.0.2" />
|
||||
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.6" />
|
||||
<PackageReference Include="System.Text.Json" Version="10.0.5" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.6.1" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.1" />
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ public void should_parse_quality_from_name(string title)
|
|||
|
||||
[TestCase("01. Kanye West - Ultralight Beam.mp3")]
|
||||
[TestCase("01. Kanye West - Ultralight Beam.ogg")]
|
||||
[TestCase("01. Kanye West - Ultralight Beam.mka")]
|
||||
|
||||
// These get detected by name as we are looking for the extensions as identifiers for release names
|
||||
// [TestCase("01. Kanye West - Ultralight Beam.m4a")]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<PackageReference Include="Equ" Version="2.3.0" />
|
||||
<PackageReference Include="MailKit" Version="4.15.1" />
|
||||
<PackageReference Include="Polly" Version="8.6.4" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.6" />
|
||||
<PackageReference Include="System.Text.Json" Version="10.0.5" />
|
||||
<PackageReference Include="System.Memory" Version="4.6.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.20" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.1" />
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ public void Read(string path)
|
|||
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, bitrate, file.Properties.BitsPerSample);
|
||||
Quality = QualityParser.ParseQualityFromCodec(file.Name, acodec, bitrate, file.Properties.BitsPerSample);
|
||||
Logger.Debug($"Quality parsed: {Quality}, Source: {Quality.QualityDetectionSource}");
|
||||
|
||||
MediaInfo = new MediaInfoModel
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ static MediaFileExtensions()
|
|||
{ ".m4a", Quality.Unknown },
|
||||
{ ".m4b", Quality.Unknown },
|
||||
{ ".m4p", Quality.Unknown },
|
||||
{ ".mka", Quality.Unknown },
|
||||
{ ".ogg", Quality.Unknown },
|
||||
{ ".oga", Quality.Unknown },
|
||||
{ ".opus", Quality.Unknown },
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
using System;
|
||||
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
|
||||
{
|
||||
|
|
@ -38,12 +41,46 @@ public class QualityParser
|
|||
|
||||
private static readonly Regex SampleSizeRegex = new (@"\b(?:(?<S24>24[-._ ]?bit|flac24(?:[-._ ]?bit)?|tr24|24-(?:44|48|96|192)|[\[\(].*24bit.*[\]\)]))\b", RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex CodecRegex = new (@"\b(?:(?<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>(web)?flac(?:24(?:[-._ ]?bit)?)?|TR24)|(?<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 (@"\b(?:(?<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>(web)?flac(?:24(?:[-._ ]?bit)?)?|TR24)|(?<WAVPACK>wavpack|wv)|(?<ALAC>alac)|(?<WMA>WMA\d?)|(?<WAV>WAV|PCM)|(?<AAC>M4A|M4P|M4B|AAC|mp4a|MPEG-4 Audio(?!.*alac))|(?<OGG>MKA|OGG|OGA|Vorbis))\b|(?<APE>monkey's audio|[\[|\(].*\bape\b.*[\]|\)])|(?<OPUS>Opus Version \d(.5)? Audio|[\[|\(].*\bopus\b.*[\]|\)])",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex WebRegex = new (@"\b(?<web>WEB)(?:\b|$|[ .])",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static QualityModel ParseQualityFromCodec(string name, IAudioCodec audioCodec, int fileBitrate, int fileSampleSize = 0)
|
||||
{
|
||||
var normalizedName = name.Replace('_', ' ').Trim().ToLower();
|
||||
var result = ParseQualityModifiers(name, normalizedName);
|
||||
|
||||
var codec = Codec.Unknown;
|
||||
var bitrate = ParseBitRate(normalizedName);
|
||||
var sampleSize = ParseSampleSize(normalizedName);
|
||||
|
||||
if (audioCodec != null)
|
||||
{
|
||||
if (audioCodec is AudioTrack matroskaCodec)
|
||||
{
|
||||
codec = ParseCodec(StealCodecFromMatroskaTrack(matroskaCodec), string.Empty);
|
||||
}
|
||||
|
||||
if (codec == Codec.Unknown && audioCodec!.Description.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
var descCodec = ParseCodec(audioCodec.Description, string.Empty);
|
||||
Logger.Trace($"Got codec {descCodec}");
|
||||
|
||||
result.Quality = FindQuality(descCodec, fileBitrate, fileSampleSize);
|
||||
|
||||
if (result.Quality != Quality.Unknown)
|
||||
{
|
||||
result.QualityDetectionSource = QualityDetectionSource.TagLib;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ParseQuality(result, codec, name, normalizedName, bitrate, sampleSize);
|
||||
}
|
||||
|
||||
public static QualityModel ParseQuality(string name, string desc, int fileBitrate, int fileSampleSize = 0)
|
||||
{
|
||||
Logger.Debug("Trying to parse quality for '{0}'", name);
|
||||
|
|
@ -74,6 +111,17 @@ public static QualityModel ParseQuality(string name, string desc, int fileBitrat
|
|||
var bitrate = ParseBitRate(normalizedName);
|
||||
var sampleSize = ParseSampleSize(normalizedName);
|
||||
|
||||
return ParseQuality(result, codec, name, normalizedName, bitrate, sampleSize);
|
||||
}
|
||||
|
||||
public static QualityModel ParseQuality(
|
||||
QualityModel result,
|
||||
Codec codec,
|
||||
string name,
|
||||
string normalizedName,
|
||||
BitRate bitrate,
|
||||
SampleSize sampleSize)
|
||||
{
|
||||
switch (codec)
|
||||
{
|
||||
case Codec.MP1:
|
||||
|
|
@ -333,6 +381,20 @@ public static Codec ParseCodec(string name, string origName)
|
|||
return Codec.Unknown;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private static BitRate ParseBitRate(string name)
|
||||
{
|
||||
// var nameWithNoSpaces = Regex.Replace(name, @"\s+", "");
|
||||
|
|
|
|||
Loading…
Reference in a new issue