mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-27 12:33:00 +02:00
Fixed: Additional FileNameBuilder Tests, {MediaInfo SubtitleLanguagesAll} Token
This commit is contained in:
@@ -9,6 +9,8 @@ using NzbDrone.Core.Organizer;
|
|||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Movies;
|
using NzbDrone.Core.Movies;
|
||||||
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
||||||
{
|
{
|
||||||
@@ -305,26 +307,6 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
|||||||
.Should().Be("South.Park.3D.h264.DTS");
|
.Should().Be("South.Park.3D.h264.DTS");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_format_mediainfo_hdr_properly()
|
|
||||||
{
|
|
||||||
_namingConfig.StandardMovieFormat = "{Movie.Title}.{MEDIAINFO.HDR}.{MediaInfo.Simple}";
|
|
||||||
|
|
||||||
_movieFile.MediaInfo = new Core.MediaFiles.MediaInfo.MediaInfoModel()
|
|
||||||
{
|
|
||||||
VideoFormat = "AVC",
|
|
||||||
VideoBitDepth = 10,
|
|
||||||
VideoColourPrimaries = "BT.2020",
|
|
||||||
VideoTransferCharacteristics = "PQ",
|
|
||||||
AudioFormat = "DTS",
|
|
||||||
AudioLanguages = "English",
|
|
||||||
Subtitles = "English/Spanish/Italian"
|
|
||||||
};
|
|
||||||
|
|
||||||
Subject.BuildFileName(_movie, _movieFile)
|
|
||||||
.Should().Be("South.Park.HDR.h264.DTS");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_remove_duplicate_non_word_characters()
|
public void should_remove_duplicate_non_word_characters()
|
||||||
{
|
{
|
||||||
@@ -506,6 +488,138 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
|||||||
.Should().Be(releaseGroup);
|
.Should().Be(releaseGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("English", "")]
|
||||||
|
[TestCase("English/German", "[EN+DE]")]
|
||||||
|
public void should_format_audio_languages(string audioLanguages, string expected)
|
||||||
|
{
|
||||||
|
_movieFile.ReleaseGroup = null;
|
||||||
|
|
||||||
|
GivenMediaInfoModel(audioLanguages: audioLanguages);
|
||||||
|
|
||||||
|
|
||||||
|
_namingConfig.StandardMovieFormat = "{MediaInfo AudioLanguages}";
|
||||||
|
|
||||||
|
|
||||||
|
Subject.BuildFileName( _movie , _movieFile)
|
||||||
|
.Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("English", "[EN]")]
|
||||||
|
[TestCase("English/German", "[EN+DE]")]
|
||||||
|
public void should_format_audio_languages_all(string audioLanguages, string expected)
|
||||||
|
{
|
||||||
|
_movieFile.ReleaseGroup = null;
|
||||||
|
|
||||||
|
GivenMediaInfoModel(audioLanguages: audioLanguages);
|
||||||
|
|
||||||
|
|
||||||
|
_namingConfig.StandardMovieFormat = "{MediaInfo AudioLanguagesAll}";
|
||||||
|
|
||||||
|
|
||||||
|
Subject.BuildFileName( _movie , _movieFile)
|
||||||
|
.Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(8, "BT.601 NTSC", "BT.709", "South.Park")]
|
||||||
|
[TestCase(10, "BT.2020", "PQ", "South.Park.HDR")]
|
||||||
|
[TestCase(10, "BT.2020", "HLG", "South.Park.HDR")]
|
||||||
|
[TestCase(0, null, null, "South.Park")]
|
||||||
|
public void should_include_hdr_for_mediainfo_videodynamicrange_with_valid_properties(int bitDepth, string colourPrimaries,
|
||||||
|
string transferCharacteristics, string expectedName)
|
||||||
|
{
|
||||||
|
_namingConfig.StandardMovieFormat =
|
||||||
|
"{Movie.Title}.{MediaInfo VideoDynamicRange}";
|
||||||
|
|
||||||
|
GivenMediaInfoModel(videoBitDepth: bitDepth, videoColourPrimaries: colourPrimaries, videoTransferCharacteristics: transferCharacteristics);
|
||||||
|
|
||||||
|
Subject.BuildFileName(_movie, _movieFile)
|
||||||
|
.Should().Be(expectedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_update_media_info_if_token_configured_and_revision_is_old()
|
||||||
|
{
|
||||||
|
_namingConfig.StandardMovieFormat =
|
||||||
|
"{Movie.Title}.{MediaInfo VideoDynamicRange}";
|
||||||
|
|
||||||
|
GivenMediaInfoModel(schemaRevision: 3);
|
||||||
|
|
||||||
|
Subject.BuildFileName( _movie, _movieFile);
|
||||||
|
|
||||||
|
Mocker.GetMock<IUpdateMediaInfo>().Verify(v => v.Update(_movieFile, _movie), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_update_media_info_if_no_movie_path_available()
|
||||||
|
{
|
||||||
|
_namingConfig.StandardMovieFormat =
|
||||||
|
"{Movie.Title}.{MediaInfo VideoDynamicRange}";
|
||||||
|
|
||||||
|
GivenMediaInfoModel(schemaRevision: 3);
|
||||||
|
_movie.Path = null;
|
||||||
|
|
||||||
|
Subject.BuildFileName( _movie, _movieFile);
|
||||||
|
|
||||||
|
Mocker.GetMock<IUpdateMediaInfo>().Verify(v => v.Update(_movieFile, _movie), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_update_media_info_if_token_not_configured_and_revision_is_old()
|
||||||
|
{
|
||||||
|
_namingConfig.StandardMovieFormat =
|
||||||
|
"{Movie.Title}";
|
||||||
|
|
||||||
|
GivenMediaInfoModel(schemaRevision: 3);
|
||||||
|
|
||||||
|
Subject.BuildFileName( _movie, _movieFile);
|
||||||
|
|
||||||
|
Mocker.GetMock<IUpdateMediaInfo>().Verify(v => v.Update(_movieFile, _movie), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_update_media_info_if_token_configured_and_revision_is_current()
|
||||||
|
{
|
||||||
|
_namingConfig.StandardMovieFormat =
|
||||||
|
"{Movie.Title}.{MediaInfo VideoDynamicRange}";
|
||||||
|
|
||||||
|
GivenMediaInfoModel(schemaRevision: 5);
|
||||||
|
|
||||||
|
Subject.BuildFileName( _movie, _movieFile);
|
||||||
|
|
||||||
|
Mocker.GetMock<IUpdateMediaInfo>().Verify(v => v.Update(_movieFile, _movie), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_update_media_info_if_token_configured_and_revision_is_newer()
|
||||||
|
{
|
||||||
|
_namingConfig.StandardMovieFormat =
|
||||||
|
"{Movie.Title}.{MediaInfo VideoDynamicRange}";
|
||||||
|
|
||||||
|
GivenMediaInfoModel(schemaRevision: 8);
|
||||||
|
|
||||||
|
Subject.BuildFileName(_movie, _movieFile);
|
||||||
|
|
||||||
|
Mocker.GetMock<IUpdateMediaInfo>().Verify(v => v.Update(_movieFile, _movie), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenMediaInfoModel(string videoCodec = "AVC", string audioCodec = "DTS", int audioChannels = 6, int videoBitDepth = 8,
|
||||||
|
string videoColourPrimaries = "", string videoTransferCharacteristics = "", string audioLanguages = "English",
|
||||||
|
string subtitles = "English/Spanish/Italian", int schemaRevision = 5)
|
||||||
|
{
|
||||||
|
_movieFile.MediaInfo = new MediaInfoModel
|
||||||
|
{
|
||||||
|
VideoCodec = videoCodec,
|
||||||
|
AudioFormat = audioCodec,
|
||||||
|
AudioChannels = audioChannels,
|
||||||
|
AudioLanguages = audioLanguages,
|
||||||
|
Subtitles = subtitles,
|
||||||
|
VideoBitDepth = videoBitDepth,
|
||||||
|
VideoColourPrimaries = videoColourPrimaries,
|
||||||
|
VideoTransferCharacteristics = videoTransferCharacteristics,
|
||||||
|
SchemaRevision = schemaRevision
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,12 @@ using NzbDrone.Core.Configuration;
|
|||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
{
|
{
|
||||||
public class UpdateMediaInfoService : IHandle<MovieScannedEvent>
|
public interface IUpdateMediaInfo
|
||||||
|
{
|
||||||
|
void Update(MovieFile movieFile, Movie movie);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UpdateMediaInfoService : IHandle<MovieScannedEvent>, IUpdateMediaInfo
|
||||||
{
|
{
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
@@ -31,28 +36,6 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateMediaInfo(Movie movie, List<MovieFile> mediaFiles)
|
|
||||||
{
|
|
||||||
foreach (var mediaFile in mediaFiles)
|
|
||||||
{
|
|
||||||
var path = Path.Combine(movie.Path, mediaFile.RelativePath);
|
|
||||||
|
|
||||||
if (!_diskProvider.FileExists(path))
|
|
||||||
{
|
|
||||||
_logger.Debug("Can't update MediaInfo because '{0}' does not exist", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaFile.MediaInfo = _videoFileInfoReader.GetMediaInfo(path);
|
|
||||||
|
|
||||||
if (mediaFile.MediaInfo != null)
|
|
||||||
{
|
|
||||||
_mediaFileService.Update(mediaFile);
|
|
||||||
_logger.Debug("Updated MediaInfo for '{0}'", path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MovieScannedEvent message)
|
public void Handle(MovieScannedEvent message)
|
||||||
{
|
{
|
||||||
if (!_configService.EnableMediaInfo)
|
if (!_configService.EnableMediaInfo)
|
||||||
@@ -62,9 +45,45 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
var allMediaFiles = _mediaFileService.GetFilesByMovie(message.Movie.Id);
|
var allMediaFiles = _mediaFileService.GetFilesByMovie(message.Movie.Id);
|
||||||
var filteredMediaFiles = allMediaFiles.Where(c => c.MediaInfo == null || c.MediaInfo.SchemaRevision < VideoFileInfoReader.MINIMUM_MEDIA_INFO_SCHEMA_REVISION).ToList();
|
var filteredMediaFiles = allMediaFiles.Where(c =>
|
||||||
|
c.MediaInfo == null ||
|
||||||
|
c.MediaInfo.SchemaRevision < VideoFileInfoReader.MINIMUM_MEDIA_INFO_SCHEMA_REVISION).ToList();
|
||||||
|
|
||||||
UpdateMediaInfo(message.Movie, filteredMediaFiles);
|
foreach (var mediaFile in filteredMediaFiles)
|
||||||
|
{
|
||||||
|
UpdateMediaInfo(mediaFile, message.Movie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(MovieFile movieFile, Movie movie)
|
||||||
|
{
|
||||||
|
if (!_configService.EnableMediaInfo)
|
||||||
|
{
|
||||||
|
_logger.Debug("MediaInfo is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateMediaInfo(movieFile, movie);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateMediaInfo(MovieFile movieFile, Movie movie)
|
||||||
|
{
|
||||||
|
var path = Path.Combine(movie.Path, movieFile.RelativePath);
|
||||||
|
|
||||||
|
if (!_diskProvider.FileExists(path))
|
||||||
|
{
|
||||||
|
_logger.Debug("Can't update MediaInfo because '{0}' does not exist", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedMediaInfo = _videoFileInfoReader.GetMediaInfo(path);
|
||||||
|
|
||||||
|
if (updatedMediaInfo != null)
|
||||||
|
{
|
||||||
|
movieFile.MediaInfo = updatedMediaInfo;
|
||||||
|
_mediaFileService.Update(movieFile);
|
||||||
|
_logger.Debug("Updated MediaInfo for '{0}'", path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,7 @@ namespace NzbDrone.Core.Organizer
|
|||||||
{
|
{
|
||||||
private readonly INamingConfigService _namingConfigService;
|
private readonly INamingConfigService _namingConfigService;
|
||||||
private readonly IQualityDefinitionService _qualityDefinitionService;
|
private readonly IQualityDefinitionService _qualityDefinitionService;
|
||||||
private readonly ICached<EpisodeFormat[]> _episodeFormatCache;
|
private readonly IUpdateMediaInfo _mediaInfoUpdater;
|
||||||
private readonly ICached<AbsoluteEpisodeFormat[]> _absoluteEpisodeFormatCache;
|
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private static readonly Regex TitleRegex = new Regex(@"\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[a-z0-9]+))?(?<suffix>[- ._)\]]*)\}",
|
private static readonly Regex TitleRegex = new Regex(@"\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[a-z0-9]+))?(?<suffix>[- ._)\]]*)\}",
|
||||||
@@ -65,14 +64,12 @@ namespace NzbDrone.Core.Organizer
|
|||||||
|
|
||||||
public FileNameBuilder(INamingConfigService namingConfigService,
|
public FileNameBuilder(INamingConfigService namingConfigService,
|
||||||
IQualityDefinitionService qualityDefinitionService,
|
IQualityDefinitionService qualityDefinitionService,
|
||||||
ICacheManager cacheManager,
|
IUpdateMediaInfo mediaInfoUpdater,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_namingConfigService = namingConfigService;
|
_namingConfigService = namingConfigService;
|
||||||
_qualityDefinitionService = qualityDefinitionService;
|
_qualityDefinitionService = qualityDefinitionService;
|
||||||
//_movieFormatCache = cacheManager.GetCache<MovieFormat>(GetType(), "movieFormat");
|
_mediaInfoUpdater = mediaInfoUpdater;
|
||||||
_episodeFormatCache = cacheManager.GetCache<EpisodeFormat[]>(GetType(), "episodeFormat");
|
|
||||||
_absoluteEpisodeFormatCache = cacheManager.GetCache<AbsoluteEpisodeFormat[]>(GetType(), "absoluteEpisodeFormat");
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +88,8 @@ namespace NzbDrone.Core.Organizer
|
|||||||
var pattern = namingConfig.StandardMovieFormat;
|
var pattern = namingConfig.StandardMovieFormat;
|
||||||
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
|
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
|
||||||
|
|
||||||
|
UpdateMediaInfoIfNeeded(pattern, movieFile, movie);
|
||||||
|
|
||||||
AddMovieTokens(tokenHandlers, movie);
|
AddMovieTokens(tokenHandlers, movie);
|
||||||
AddReleaseDateTokens(tokenHandlers, movie.Year);
|
AddReleaseDateTokens(tokenHandlers, movie.Year);
|
||||||
AddImdbIdTokens(tokenHandlers, movie.ImdbId);
|
AddImdbIdTokens(tokenHandlers, movie.ImdbId);
|
||||||
@@ -312,34 +311,44 @@ namespace NzbDrone.Core.Organizer
|
|||||||
tokenHandlers["{Quality Real}"] = m => qualityReal;
|
tokenHandlers["{Quality Real}"] = m => qualityReal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const string MediaInfoVideoDynamicRangeToken = "{MediaInfo VideoDynamicRange}";
|
||||||
|
private static readonly IDictionary<string, int> MinimumMediaInfoSchemaRevisions =
|
||||||
|
new Dictionary<string, int>(FileNameBuilderTokenEqualityComparer.Instance)
|
||||||
|
{
|
||||||
|
{MediaInfoVideoDynamicRangeToken, 5}
|
||||||
|
};
|
||||||
|
|
||||||
private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, MovieFile movieFile)
|
private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, MovieFile movieFile)
|
||||||
{
|
{
|
||||||
if (movieFile.MediaInfo == null) return;
|
if (movieFile.MediaInfo == null)
|
||||||
|
{
|
||||||
|
_logger.Trace("Media info is unavailable for {0}", movieFile);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var sceneName = movieFile.GetSceneOrFileName();
|
var sceneName = movieFile.GetSceneOrFileName();
|
||||||
|
|
||||||
|
|
||||||
var videoCodec = MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, sceneName);
|
var videoCodec = MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, sceneName);
|
||||||
var audioCodec = MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, sceneName);
|
var audioCodec = MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, sceneName);
|
||||||
var audioChannels = MediaInfoFormatter.FormatAudioChannels(movieFile.MediaInfo);
|
var audioChannels = MediaInfoFormatter.FormatAudioChannels(movieFile.MediaInfo);
|
||||||
|
var audioLanguages = movieFile.MediaInfo.AudioLanguages ?? string.Empty;
|
||||||
|
var subtitles = movieFile.MediaInfo.Subtitles ?? string.Empty;
|
||||||
|
|
||||||
// Workaround until https://github.com/MediaArea/MediaInfo/issues/299 is fixed and release
|
var mediaInfoAudioLanguages = GetLanguagesToken(audioLanguages);
|
||||||
if (audioCodec.EqualsIgnoreCase("DTS-X"))
|
|
||||||
{
|
|
||||||
audioChannels = audioChannels - 1 + 0.1m;
|
|
||||||
}
|
|
||||||
|
|
||||||
var mediaInfoAudioLanguages = GetLanguagesToken(movieFile.MediaInfo.AudioLanguages);
|
|
||||||
if (!mediaInfoAudioLanguages.IsNullOrWhiteSpace())
|
if (!mediaInfoAudioLanguages.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
mediaInfoAudioLanguages = $"[{mediaInfoAudioLanguages}]";
|
mediaInfoAudioLanguages = $"[{mediaInfoAudioLanguages}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaInfoAudioLanguagesAll = mediaInfoAudioLanguages;
|
var mediaInfoAudioLanguagesAll = mediaInfoAudioLanguages;
|
||||||
if (mediaInfoAudioLanguages == "[EN]")
|
if (mediaInfoAudioLanguages == "[EN]")
|
||||||
{
|
{
|
||||||
mediaInfoAudioLanguages = string.Empty;
|
mediaInfoAudioLanguages = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaInfoSubtitleLanguages = GetLanguagesToken(movieFile.MediaInfo.Subtitles);
|
var mediaInfoSubtitleLanguages = GetLanguagesToken(subtitles);
|
||||||
if (!mediaInfoSubtitleLanguages.IsNullOrWhiteSpace())
|
if (!mediaInfoSubtitleLanguages.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
mediaInfoSubtitleLanguages = $"[{mediaInfoSubtitleLanguages}]";
|
mediaInfoSubtitleLanguages = $"[{mediaInfoSubtitleLanguages}]";
|
||||||
@@ -347,25 +356,11 @@ namespace NzbDrone.Core.Organizer
|
|||||||
|
|
||||||
var videoBitDepth = movieFile.MediaInfo.VideoBitDepth > 0 ? movieFile.MediaInfo.VideoBitDepth.ToString() : string.Empty;
|
var videoBitDepth = movieFile.MediaInfo.VideoBitDepth > 0 ? movieFile.MediaInfo.VideoBitDepth.ToString() : string.Empty;
|
||||||
var audioChannelsFormatted = audioChannels > 0 ?
|
var audioChannelsFormatted = audioChannels > 0 ?
|
||||||
audioChannels.ToString("F1", CultureInfo.InvariantCulture) :
|
audioChannels.ToString("F1", CultureInfo.InvariantCulture) :
|
||||||
string.Empty;
|
string.Empty;
|
||||||
|
|
||||||
var mediaInfo3D = movieFile.MediaInfo.VideoMultiViewCount > 1 ? "3D" : string.Empty;
|
var mediaInfo3D = movieFile.MediaInfo.VideoMultiViewCount > 1 ? "3D" : string.Empty;
|
||||||
|
|
||||||
var videoColourPrimaries = movieFile.MediaInfo.VideoColourPrimaries ?? string.Empty;
|
|
||||||
var videoTransferCharacteristics = movieFile.MediaInfo.VideoTransferCharacteristics ?? string.Empty;
|
|
||||||
var mediaInfoHDR = string.Empty;
|
|
||||||
|
|
||||||
if (movieFile.MediaInfo.VideoBitDepth >= 10 && !videoColourPrimaries.IsNullOrWhiteSpace() && !videoTransferCharacteristics.IsNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
string[] validTransferFunctions = new string[] { "PQ", "HLG" };
|
|
||||||
|
|
||||||
if (videoColourPrimaries.EqualsIgnoreCase("BT.2020") && validTransferFunctions.Any(videoTransferCharacteristics.Contains))
|
|
||||||
{
|
|
||||||
mediaInfoHDR = "HDR";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenHandlers["{MediaInfo Video}"] = m => videoCodec;
|
tokenHandlers["{MediaInfo Video}"] = m => videoCodec;
|
||||||
tokenHandlers["{MediaInfo VideoCodec}"] = m => videoCodec;
|
tokenHandlers["{MediaInfo VideoCodec}"] = m => videoCodec;
|
||||||
tokenHandlers["{MediaInfo VideoBitDepth}"] = m => videoBitDepth;
|
tokenHandlers["{MediaInfo VideoBitDepth}"] = m => videoBitDepth;
|
||||||
@@ -377,12 +372,15 @@ namespace NzbDrone.Core.Organizer
|
|||||||
tokenHandlers["{MediaInfo AudioLanguagesAll}"] = m => mediaInfoAudioLanguagesAll;
|
tokenHandlers["{MediaInfo AudioLanguagesAll}"] = m => mediaInfoAudioLanguagesAll;
|
||||||
|
|
||||||
tokenHandlers["{MediaInfo SubtitleLanguages}"] = m => mediaInfoSubtitleLanguages;
|
tokenHandlers["{MediaInfo SubtitleLanguages}"] = m => mediaInfoSubtitleLanguages;
|
||||||
|
tokenHandlers["{MediaInfo SubtitleLanguagesAll}"] = m => mediaInfoSubtitleLanguages;
|
||||||
|
|
||||||
tokenHandlers["{MediaInfo 3D}"] = m => mediaInfo3D;
|
tokenHandlers["{MediaInfo 3D}"] = m => mediaInfo3D;
|
||||||
tokenHandlers["{MediaInfo HDR}"] = m => mediaInfoHDR;
|
|
||||||
|
|
||||||
tokenHandlers["{MediaInfo Simple}"] = m => $"{videoCodec} {audioCodec}";
|
tokenHandlers["{MediaInfo Simple}"] = m => $"{videoCodec} {audioCodec}";
|
||||||
tokenHandlers["{MediaInfo Full}"] = m => $"{videoCodec} {audioCodec}{mediaInfoAudioLanguages} {mediaInfoSubtitleLanguages}";
|
tokenHandlers["{MediaInfo Full}"] = m => $"{videoCodec} {audioCodec}{mediaInfoAudioLanguages} {mediaInfoSubtitleLanguages}";
|
||||||
|
|
||||||
|
tokenHandlers[MediaInfoVideoDynamicRangeToken] =
|
||||||
|
m => MediaInfoFormatter.FormatVideoDynamicRange(movieFile.MediaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetLanguagesToken(string mediaInfoLanguages)
|
private string GetLanguagesToken(string mediaInfoLanguages)
|
||||||
@@ -394,7 +392,7 @@ namespace NzbDrone.Core.Organizer
|
|||||||
tokens.Add(item.Trim());
|
tokens.Add(item.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
var cultures = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.NeutralCultures);
|
var cultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
|
||||||
for (int i = 0; i < tokens.Count; i++)
|
for (int i = 0; i < tokens.Count; i++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -412,6 +410,26 @@ namespace NzbDrone.Core.Organizer
|
|||||||
return string.Join("+", tokens.Distinct());
|
return string.Join("+", tokens.Distinct());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateMediaInfoIfNeeded(string pattern, MovieFile movieFile, Movie movie)
|
||||||
|
{
|
||||||
|
if (movie.Path.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var schemaRevision = movieFile.MediaInfo != null ? movieFile.MediaInfo.SchemaRevision : 0;
|
||||||
|
var matches = TitleRegex.Matches(pattern);
|
||||||
|
|
||||||
|
var shouldUpdateMediaInfo = matches.Cast<Match>()
|
||||||
|
.Select(m => MinimumMediaInfoSchemaRevisions.GetValueOrDefault(m.Value, -1))
|
||||||
|
.Any(r => schemaRevision < r);
|
||||||
|
|
||||||
|
if (shouldUpdateMediaInfo)
|
||||||
|
{
|
||||||
|
_mediaInfoUpdater.Update(movieFile, movie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string ReplaceTokens(string pattern, Dictionary<string, Func<TokenMatch, string>> tokenHandlers, NamingConfig namingConfig)
|
private string ReplaceTokens(string pattern, Dictionary<string, Func<TokenMatch, string>> tokenHandlers, NamingConfig namingConfig)
|
||||||
{
|
{
|
||||||
return TitleRegex.Replace(pattern, match => ReplaceToken(match, tokenHandlers, namingConfig));
|
return TitleRegex.Replace(pattern, match => ReplaceToken(match, tokenHandlers, namingConfig));
|
||||||
|
Reference in New Issue
Block a user