* New: MediaInfo -> FFProbe * Detect HDR format * Fix migration for users that tested early ffmpegpull/4947/head
parent
e7ff13085e
commit
f0f8a4ffaf
@ -1,321 +0,0 @@
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class FormatAudioChannelsFixture : TestBase
|
||||
{
|
||||
[Test]
|
||||
public void should_subtract_one_from_AudioChannels_as_total_channels_if_LFE_in_AudioChannelPositionsText()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 6,
|
||||
AudioChannelPositions = null,
|
||||
AudioChannelPositionsTextContainer = "Front: L C R, Side: L R, LFE"
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_AudioChannels_as_total_channels_if_LFE_not_in_AudioChannelPositionsText()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = null,
|
||||
AudioChannelPositionsTextContainer = "Front: L R"
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_0_if_schema_revision_is_less_than_3_and_other_properties_are_null()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = null,
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 2
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_AudioChannels_if_schema_revision_is_3_and_other_properties_are_null()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = null,
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_AudioChannels_if_schema_revision_is_3_and_AudioChannelPositions_is_0()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioFormat = "FLAC",
|
||||
AudioChannelsContainer = 6,
|
||||
AudioChannelPositions = "0/0/0",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_sum_AudioChannelPositions()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "2/0/0",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_sum_AudioChannelPositions_including_decimal()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "3/2/0.1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_8_channel_object_based_as_71_if_dtsx()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 8,
|
||||
AudioChannelsStream = 0,
|
||||
AudioFormat = "DTS",
|
||||
AudioAdditionalFeatures = "XLL X",
|
||||
AudioChannelPositions = "Object Based",
|
||||
AudioChannelPositionsTextContainer = "Object Based",
|
||||
AudioChannelPositionsTextStream = "Object Based",
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(7.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_8_channel_blank_as_71_if_dtsx()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 8,
|
||||
AudioChannelsStream = 0,
|
||||
AudioFormat = "DTS",
|
||||
AudioAdditionalFeatures = "XLL X",
|
||||
AudioChannelPositions = "",
|
||||
AudioChannelPositionsTextContainer = "",
|
||||
AudioChannelPositionsTextStream = "Object Based",
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(7.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_6_channel_zero_as_51_if_flac()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioFormat = "FLAC",
|
||||
AudioChannelsContainer = 6,
|
||||
AudioChannelPositions = "0/0/0",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_ignore_culture_on_channel_summary()
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
|
||||
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "3/2/0.1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_handle_AudioChannelPositions_three_digits()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "3/2/0.2.1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(7.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_cleanup_extraneous_text_from_AudioChannelPositions()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "Object Based / 3/2/2.1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(7.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_skip_empty_groups_in_AudioChannelPositions()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = " / 2/0/0.0",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_sum_first_series_of_numbers_from_AudioChannelPositions()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "3/2/2.1 / 3/2/2.1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(7.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_sum_first_series_of_numbers_from_AudioChannelPositions_with_three_digits()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "3/2/0.2.1 / 3/2/0.1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(7.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_sum_dual_mono_representation_AudioChannelPositions()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "1+1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(2.0m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_AudioChannelPositionText_when_AudioChannelChannelPosition_is_invalid()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 6,
|
||||
AudioChannelPositions = "15 objects",
|
||||
AudioChannelPositionsTextContainer = "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
|
||||
{
|
||||
AudioChannelsContainer = 2,
|
||||
AudioChannelPositions = "15 objects / 3/2.1",
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
SchemaRevision = 3
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(5.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_audio_stream_text_when_exists()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 6,
|
||||
AudioChannelsStream = 8,
|
||||
AudioChannelPositions = null,
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
AudioChannelPositionsTextStream = "Front: L C R, Side: L R, Back: L R, LFE",
|
||||
SchemaRevision = 6
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(7.1m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_audio_stream_channels_when_exists()
|
||||
{
|
||||
var mediaInfoModel = new MediaInfoModel
|
||||
{
|
||||
AudioChannelsContainer = 6,
|
||||
AudioChannelsStream = 8,
|
||||
AudioChannelPositions = null,
|
||||
AudioChannelPositionsTextContainer = null,
|
||||
AudioChannelPositionsTextStream = null,
|
||||
SchemaRevision = 6
|
||||
};
|
||||
|
||||
MediaInfoFormatter.FormatAudioChannels(mediaInfoModel).Should().Be(8m);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,903 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dapper;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(199)]
|
||||
public class mediainfo_to_ffmpeg : NzbDroneMigrationBase
|
||||
{
|
||||
private readonly JsonSerializerOptions _serializerSettings;
|
||||
|
||||
public mediainfo_to_ffmpeg()
|
||||
{
|
||||
var serializerSettings = new JsonSerializerOptions
|
||||
{
|
||||
AllowTrailingCommas = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
serializerSettings.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, true));
|
||||
serializerSettings.Converters.Add(new STJTimeSpanConverter());
|
||||
serializerSettings.Converters.Add(new STJUtcConverter());
|
||||
|
||||
_serializerSettings = serializerSettings;
|
||||
}
|
||||
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Execute.WithConnection(MigrateToFfprobe);
|
||||
}
|
||||
|
||||
private void MigrateToFfprobe(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
var existing = conn.Query<MediaInfoRaw>("SELECT Id, MediaInfo, SceneName FROM MovieFiles");
|
||||
|
||||
var updated = new List<MediaInfoRaw>();
|
||||
|
||||
foreach (var row in existing)
|
||||
{
|
||||
if (row.MediaInfo.IsNullOrWhiteSpace())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// basic parse to check schema revision
|
||||
// in case user already tested ffmpeg branch
|
||||
var mediaInfoVersion = JsonSerializer.Deserialize<MediaInfoBase>(row.MediaInfo, _serializerSettings);
|
||||
if (mediaInfoVersion.SchemaRevision >= 8)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse and migrate
|
||||
var mediaInfo = JsonSerializer.Deserialize<MediaInfo198>(row.MediaInfo, _serializerSettings);
|
||||
|
||||
var ffprobe = MigrateMediaInfo(mediaInfo, row.SceneName);
|
||||
|
||||
updated.Add(new MediaInfoRaw
|
||||
{
|
||||
Id = row.Id,
|
||||
MediaInfo = JsonSerializer.Serialize(ffprobe, _serializerSettings)
|
||||
});
|
||||
}
|
||||
|
||||
var updateSql = "UPDATE MovieFiles SET MediaInfo = @MediaInfo WHERE Id = @Id";
|
||||
conn.Execute(updateSql, updated, transaction: tran);
|
||||
}
|
||||
|
||||
public MediaInfo199 MigrateMediaInfo(MediaInfo198 old, string sceneName)
|
||||
{
|
||||
var m = new MediaInfo199
|
||||
{
|
||||
SchemaRevision = old.SchemaRevision,
|
||||
ContainerFormat = old.ContainerFormat,
|
||||
VideoProfile = old.VideoProfile,
|
||||
VideoBitrate = old.VideoBitrate,
|
||||
VideoBitDepth = old.VideoBitDepth,
|
||||
VideoMultiViewCount = old.VideoMultiViewCount,
|
||||
VideoColourPrimaries = MigratePrimaries(old.VideoColourPrimaries),
|
||||
VideoTransferCharacteristics = MigrateTransferCharacteristics(old.VideoTransferCharacteristics),
|
||||
Height = old.Height,
|
||||
Width = old.Width,
|
||||
AudioBitrate = old.AudioBitrate,
|
||||
RunTime = old.RunTime,
|
||||
AudioStreamCount = old.AudioStreamCount,
|
||||
VideoFps = old.VideoFps,
|
||||
ScanType = old.ScanType,
|
||||
AudioLanguages = MigrateLanguages(old.AudioLanguages),
|
||||
Subtitles = MigrateLanguages(old.Subtitles)
|
||||
};
|
||||
|
||||
m.VideoHdrFormat = MigrateHdrFormat(old);
|
||||
|
||||
MigrateVideoCodec(old, m, sceneName);
|
||||
MigrateAudioCodec(old, m);
|
||||
MigrateAudioChannelPositions(old, m);
|
||||
|
||||
m.AudioChannels = old.AudioChannelsStream > 0 ? old.AudioChannelsStream : old.AudioChannelsContainer;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
private void MigrateVideoCodec(MediaInfo198 mediaInfo, MediaInfo199 m, string sceneName)
|
||||
{
|
||||
if (mediaInfo.VideoFormat == null)
|
||||
{
|
||||
MigrateVideoCodecLegacy(mediaInfo, m, sceneName);
|
||||
return;
|
||||
}
|
||||
|
||||
var videoFormat = mediaInfo.VideoFormat.Trim().Split(new[] { " / " }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var videoCodecID = mediaInfo.VideoCodecID ?? string.Empty;
|
||||
var videoCodecLibrary = mediaInfo.VideoCodecLibrary ?? string.Empty;
|
||||
|
||||
var result = mediaInfo.VideoFormat.Trim();
|
||||
|
||||
m.VideoFormat = result;
|
||||
m.VideoCodecID = null;
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("x264"))
|
||||
{
|
||||
m.VideoFormat = "h264";
|
||||
m.VideoCodecID = "x264";
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("AVC") || videoFormat.ContainsIgnoreCase("V.MPEG4/ISO/AVC"))
|
||||
{
|
||||
m.VideoFormat = "h264";
|
||||
|
||||
if (videoCodecLibrary.StartsWithIgnoreCase("x264"))
|
||||
{
|
||||
m.VideoCodecID = "x264";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("HEVC") || videoFormat.ContainsIgnoreCase("V_MPEGH/ISO/HEVC"))
|
||||
{
|
||||
m.VideoFormat = "hevc";
|
||||
if (videoCodecLibrary.StartsWithIgnoreCase("x265"))
|
||||
{
|
||||
m.VideoCodecID = "x265";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("MPEG Video"))
|
||||
{
|
||||
if (videoCodecID == "2" || videoCodecID == "V_MPEG2")
|
||||
{
|
||||
m.VideoFormat = "mpeg2video";
|
||||
}
|
||||
|
||||
if (videoCodecID.IsNullOrWhiteSpace())
|
||||
{
|
||||
m.VideoFormat = "MPEG";
|
||||
}
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("MPEG-2 Video"))
|
||||
{
|
||||
m.VideoFormat = "mpeg2video";
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("MPEG-4 Visual"))
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
|
||||
if (videoCodecID.ContainsIgnoreCase("XVID") ||
|
||||
videoCodecLibrary.StartsWithIgnoreCase("XviD"))
|
||||
{
|
||||
m.VideoCodecID = "XVID";
|
||||
}
|
||||
|
||||
if (videoCodecID.ContainsIgnoreCase("DIV3") ||
|
||||
videoCodecID.ContainsIgnoreCase("DIVX") ||
|
||||
videoCodecID.ContainsIgnoreCase("DX50") ||
|
||||
videoCodecLibrary.StartsWithIgnoreCase("DivX"))
|
||||
{
|
||||
m.VideoCodecID = "DIVX";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("MPEG-4 Visual") || videoFormat.ContainsIgnoreCase("mp4v"))
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
|
||||
result = GetSceneNameMatch(sceneName, "XviD", "DivX", "");
|
||||
|
||||
if (result == "XviD")
|
||||
{
|
||||
m.VideoCodecID = "XVID";
|
||||
}
|
||||
|
||||
if (result == "DivX")
|
||||
{
|
||||
m.VideoCodecID = "DIVX";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("VC-1"))
|
||||
{
|
||||
m.VideoFormat = "vc1";
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("AV1"))
|
||||
{
|
||||
m.VideoFormat = "av1";
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("VP6") || videoFormat.ContainsIgnoreCase("VP7") ||
|
||||
videoFormat.ContainsIgnoreCase("VP8") || videoFormat.ContainsIgnoreCase("VP9"))
|
||||
{
|
||||
m.VideoFormat = videoFormat.First().ToLowerInvariant();
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("WMV1") || videoFormat.ContainsIgnoreCase("WMV2"))
|
||||
{
|
||||
m.VideoFormat = "WMV";
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("DivX") || videoFormat.ContainsIgnoreCase("div3"))
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
m.VideoCodecID = "DIVX";
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("XviD"))
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
m.VideoCodecID = "XVID";
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("V_QUICKTIME") ||
|
||||
videoFormat.ContainsIgnoreCase("RealVideo 4"))
|
||||
{
|
||||
m.VideoFormat = "qtrle";
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoFormat.ContainsIgnoreCase("mp42") ||
|
||||
videoFormat.ContainsIgnoreCase("mp43"))
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void MigrateVideoCodecLegacy(MediaInfo198 mediaInfo, MediaInfo199 m, string sceneName)
|
||||
{
|
||||
var videoCodec = mediaInfo.VideoCodec;
|
||||
|
||||
m.VideoFormat = videoCodec;
|
||||
m.VideoCodecID = null;
|
||||
|
||||
if (videoCodec.IsNullOrWhiteSpace())
|
||||
{
|
||||
m.VideoFormat = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (videoCodec == "AVC")
|
||||
{
|
||||
m.VideoFormat = "h264";
|
||||
}
|
||||
|
||||
if (videoCodec == "V_MPEGH/ISO/HEVC" || videoCodec == "HEVC")
|
||||
{
|
||||
m.VideoFormat = "hevc";
|
||||
}
|
||||
|
||||
if (videoCodec == "MPEG-2 Video")
|
||||
{
|
||||
m.VideoFormat = "mpeg2video";
|
||||
}
|
||||
|
||||
if (videoCodec == "MPEG-4 Visual")
|
||||
{
|
||||
var result = GetSceneNameMatch(sceneName, "DivX", "XviD");
|
||||
if (result == "DivX")
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
m.VideoCodecID = "DIVX";
|
||||
}
|
||||
|
||||
m.VideoFormat = "mpeg4";
|
||||
m.VideoCodecID = "XVID";
|
||||
}
|
||||
|
||||
if (videoCodec.StartsWithIgnoreCase("XviD"))
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
m.VideoCodecID = "XVID";
|
||||
}
|
||||
|
||||
if (videoCodec.StartsWithIgnoreCase("DivX"))
|
||||
{
|
||||
m.VideoFormat = "mpeg4";
|
||||
m.VideoCodecID = "DIVX";
|
||||
}
|
||||
|
||||
if (videoCodec.EqualsIgnoreCase("VC-1"))
|
||||
{
|
||||
m.VideoFormat = "vc1";
|
||||
}
|
||||
}
|
||||
|
||||
private HdrFormat MigrateHdrFormat(MediaInfo198 mediaInfo)
|
||||
{
|
||||
if (mediaInfo.VideoHdrFormatCompatibility.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
if (mediaInfo.VideoHdrFormatCompatibility.ContainsIgnoreCase("HLG"))
|
||||
{
|
||||
return HdrFormat.Hlg10;
|
||||
}
|
||||
|
||||
if (mediaInfo.VideoHdrFormatCompatibility.ContainsIgnoreCase("dolby"))
|
||||
{
|
||||
return HdrFormat.DolbyVision;
|
||||
}
|
||||
|
||||
if (mediaInfo.VideoHdrFormatCompatibility.ContainsIgnoreCase("dolby"))
|
||||
{
|
||||
return HdrFormat.DolbyVision;
|
||||
}
|
||||
|
||||
if (mediaInfo.VideoHdrFormatCompatibility.ContainsIgnoreCase("hdr10+"))
|
||||
{
|
||||
return HdrFormat.Hdr10Plus;
|
||||
}
|
||||
|
||||
if (mediaInfo.VideoHdrFormatCompatibility.ContainsIgnoreCase("hdr10"))
|
||||
{
|
||||
return HdrFormat.Hdr10;
|
||||
}
|
||||
}
|
||||
|
||||
return VideoFileInfoReader.GetHdrFormat(mediaInfo.VideoBitDepth, mediaInfo.VideoColourPrimaries, mediaInfo.VideoTransferCharacteristics, new ());
|
||||
}
|
||||
|
||||
private void MigrateAudioCodec(MediaInfo198 mediaInfo, MediaInfo199 m)
|
||||
{
|
||||
if (mediaInfo.AudioCodecID == null)
|
||||
{
|
||||
MigrateAudioCodecLegacy(mediaInfo, m);
|
||||
return;
|
||||
}
|
||||
|
||||
var audioFormat = mediaInfo.AudioFormat.Trim().Split(new[] { " / " }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var audioCodecID = mediaInfo.AudioCodecID ?? string.Empty;
|
||||
var splitAdditionalFeatures = (mediaInfo.AudioAdditionalFeatures ?? string.Empty).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
m.AudioFormat = "";
|
||||
|
||||
if (audioFormat.Empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("Atmos"))
|
||||
{
|
||||
m.AudioFormat = "truehd";
|
||||
m.AudioCodecID = "thd+";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("MLP FBA"))
|
||||
{
|
||||
m.AudioFormat = "truehd";
|
||||
|
||||
if (splitAdditionalFeatures.ContainsIgnoreCase("16-ch"))
|
||||
{
|
||||
m.AudioCodecID = "thd+";
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("TrueHD"))
|
||||
{
|
||||
m.AudioFormat = "truehd";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("FLAC"))
|
||||
{
|
||||
m.AudioFormat = "flac";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("DTS"))
|
||||
{
|
||||
m.AudioFormat = "dts";
|
||||
|
||||
if (splitAdditionalFeatures.ContainsIgnoreCase("XLL"))
|
||||
{
|
||||
if (splitAdditionalFeatures.ContainsIgnoreCase("X"))
|
||||
{
|
||||
m.AudioProfile = "DTS:X";
|
||||
return;
|
||||
}
|
||||
|
||||
m.AudioProfile = "DTS-HD MA";
|
||||
return;
|
||||
}
|
||||
|
||||
if (splitAdditionalFeatures.ContainsIgnoreCase("ES"))
|
||||
{
|
||||
m.AudioProfile = "DTS-ES";
|
||||
return;
|
||||
}
|
||||
|
||||
if (splitAdditionalFeatures.ContainsIgnoreCase("XBR"))
|
||||
{
|
||||
m.AudioProfile = "DTS-HD HRA";
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("E-AC-3"))
|
||||
{
|
||||
m.AudioFormat = "eac3";
|
||||
|
||||
if (splitAdditionalFeatures.ContainsIgnoreCase("JOC"))
|
||||
{
|
||||
m.AudioCodecID = "ec+3";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("AC-3"))
|
||||
{
|
||||
m.AudioFormat = "ac3";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("AAC"))
|
||||
{
|
||||
m.AudioFormat = "aac";
|
||||
|
||||
if (audioCodecID == "A_AAC/MPEG4/LC/SBR")
|
||||
{
|
||||
m.AudioCodecID = audioCodecID;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("mp3"))
|
||||
{
|
||||
m.AudioFormat = "mp3";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("MPEG Audio"))
|
||||
{
|
||||
if (mediaInfo.AudioCodecID == "55" || mediaInfo.AudioCodecID == "A_MPEG/L3" || mediaInfo.AudioProfile == "Layer 3")
|
||||
{
|
||||
m.AudioFormat = "mp3";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mediaInfo.AudioCodecID == "A_MPEG/L2" || mediaInfo.AudioProfile == "Layer 2")
|
||||
{
|
||||
m.AudioFormat = "mp2";
|
||||
}
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("Opus"))
|
||||
{
|
||||
m.AudioFormat = "opus";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("PCM"))
|
||||
{
|
||||
m.AudioFormat = "pcm_s16le";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("ADPCM"))
|
||||
{
|
||||
m.AudioFormat = "pcm_s16le";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("Vorbis"))
|
||||
{
|
||||
m.AudioFormat = "vorbis";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.ContainsIgnoreCase("WMA"))
|
||||
{
|
||||
m.AudioFormat = "wmav1";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void MigrateAudioCodecLegacy(MediaInfo198 mediaInfo, MediaInfo199 m)
|
||||
{
|
||||
var audioFormat = mediaInfo.AudioFormat;
|
||||
|
||||
m.AudioFormat = audioFormat;
|
||||
|
||||
if (audioFormat.IsNullOrWhiteSpace())
|
||||
{
|
||||
m.AudioFormat = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("AC-3"))
|
||||
{
|
||||
m.AudioFormat = "ac3";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("E-AC-3"))
|
||||
{
|
||||
m.AudioFormat = "eac3";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("AAC"))
|
||||
{
|
||||
m.AudioFormat = "aac";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("MPEG Audio") && mediaInfo.AudioProfile == "Layer 3")
|
||||
{
|
||||
m.AudioFormat = "mp3";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("DTS"))
|
||||
{
|
||||
m.AudioFormat = "DTS";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("TrueHD"))
|
||||
{
|
||||
m.AudioFormat = "truehd";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("FLAC"))
|
||||
{
|
||||
m.AudioFormat = "flac";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("Vorbis"))
|
||||
{
|
||||
m.AudioFormat = "vorbis";
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioFormat.EqualsIgnoreCase("Opus"))
|
||||
{
|
||||
m.AudioFormat = "opus";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void MigrateAudioChannelPositions(MediaInfo198 mediaInfo, MediaInfo199 m)
|
||||
{
|
||||
var audioChannels = FormatAudioChannelsFromAudioChannelPositions(mediaInfo);
|
||||
|
||||
if (audioChannels == null || audioChannels == 0.0m)
|
||||
{
|
||||
audioChannels = FormatAudioChannelsFromAudioChannelPositionsText(mediaInfo);
|
||||
}
|
||||
|
||||
if (audioChannels == null || audioChannels == 0.0m)
|
||||
{
|
||||
audioChannels = FormatAudioChannelsFromAudioChannels(mediaInfo);
|
||||
}
|
||||
|
||||
audioChannels ??= 0;
|
||||
|
||||
m.AudioChannelPositions = audioChannels.ToString();
|
||||
}
|
||||
|
||||
private decimal? FormatAudioChannelsFromAudioChannelPositions(MediaInfo198 mediaInfo)
|
||||
{
|
||||
var audioChannelPositions = mediaInfo.AudioChannelPositions;
|
||||
|
||||
if (audioChannelPositions.IsNullOrWhiteSpace())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (audioChannelPositions.Contains("+"))
|
||||
{
|
||||
return audioChannelPositions.Split('+')
|
||||
.Sum(s => decimal.Parse(s.Trim(), CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (audioChannelPositions.Contains("/"))
|
||||
{
|
||||
var channelStringList = Regex.Replace(audioChannelPositions,
|
||||
@"^\d+\sobjects",
|
||||
"",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase)
|
||||
.Replace("Object Based / ", "")
|
||||
.Split(new string[] { " / " }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.FirstOrDefault()
|
||||
?.Split('/');
|
||||
|
||||
var positions = default(decimal);
|
||||
|
||||
if (channelStringList == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach (var channel in channelStringList)
|
||||
{
|
||||
var channelSplit = channel.Split(new string[] { "." }, StringSplitOptions.None);
|
||||
|
||||
if (channelSplit.Length == 3)
|
||||
{
|
||||
positions += decimal.Parse(string.Format("{0}.{1}", channelSplit[1], channelSplit[2]), CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
positions += decimal.Parse(channel, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private decimal? FormatAudioChannelsFromAudioChannelPositionsText(MediaInfo198 mediaInfo)
|
||||
{
|
||||
var audioChannelPositionsTextContainer = mediaInfo.AudioChannelPositionsTextContainer;
|
||||
var audioChannelPositionsTextStream = mediaInfo.AudioChannelPositionsTextStream;
|
||||
var audioChannelsContainer = mediaInfo.AudioChannelsContainer;
|
||||
var audioChannelsStream = mediaInfo.AudioChannelsStream;
|
||||
|
||||
//Skip if the positions texts give us nothing
|
||||
if ((audioChannelPositionsTextContainer.IsNullOrWhiteSpace() || audioChannelPositionsTextContainer == "Object Based") &&
|
||||
(audioChannelPositionsTextStream.IsNullOrWhiteSpace() || audioChannelPositionsTextStream == "Object Based"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (audioChannelsStream > 0)
|
||||
{
|
||||
return audioChannelPositionsTextStream.ContainsIgnoreCase("LFE") ? audioChannelsStream - 1 + 0.1m : audioChannelsStream;
|
||||
}
|
||||
|
||||
return audioChannelPositionsTextContainer.ContainsIgnoreCase("LFE") ? audioChannelsContainer - 1 + 0.1m : audioChannelsContainer;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private decimal? FormatAudioChannelsFromAudioChannels(MediaInfo198 mediaInfo)
|
||||
{
|
||||
var audioChannelsContainer = mediaInfo.AudioChannelsContainer;
|
||||
var audioChannelsStream = mediaInfo.AudioChannelsStream;
|
||||
|
||||
var audioFormat = (mediaInfo.AudioFormat ?? string.Empty).Trim().Split(new[] { " / " }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var splitAdditionalFeatures = (mediaInfo.AudioAdditionalFeatures ?? string.Empty).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// Workaround https://github.com/MediaArea/MediaInfo/issues/299 for DTS-X Audio
|
||||
if (audioFormat.ContainsIgnoreCase("DTS") &&
|
||||
splitAdditionalFeatures.ContainsIgnoreCase("XLL") &&
|
||||
splitAdditionalFeatures.ContainsIgnoreCase("X") &&
|
||||
audioChannelsContainer > 0)
|
||||
{
|
||||
return audioChannelsContainer - 1 + 0.1m;
|
||||
}
|
||||
|
||||
// FLAC 6 channels is likely 5.1
|
||||
if (audioFormat.ContainsIgnoreCase("FLAC") && audioChannelsContainer == 6)
|
||||
{
|
||||
return 5.1m;
|
||||
}
|
||||
|
||||
if (mediaInfo.SchemaRevision > 5)
|
||||
{
|
||||
return audioChannelsStream > 0 ? audioChannelsStream : audioChannelsContainer;
|
||||
}
|
||||
|
||||
if (mediaInfo.SchemaRevision >= 3)
|
||||
{
|
||||
return audioChannelsContainer;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<string> MigrateLanguages(string mediaInfoLanguages)
|
||||
{
|
||||
var languages = new List<string>();
|
||||
|
||||
var tokens = mediaInfoLanguages.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList();
|
||||
|
||||
var cultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
|
||||
for (int i = 0; i < tokens.Count; i++)
|
||||
{
|
||||
if (tokens[i] == "Swedis")
|
||||
{
|
||||
// Probably typo in mediainfo (should be 'Swedish')
|
||||
languages.Add("swe");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tokens[i] == "Chinese" && OsInfo.IsNotWindows)
|
||||
{
|
||||
// Mono only has 'Chinese (Simplified)' & 'Chinese (Traditional)'
|
||||
languages.Add("zho");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tokens[i] == "Norwegian")
|
||||
{
|
||||
languages.Add("nor");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var cultureInfo = cultures.FirstOrDefault(p => p.EnglishName.RemoveAccent() == tokens[i]);
|
||||
|
||||
if (cultureInfo != null)
|
||||
{
|
||||
languages.Add(cultureInfo.ThreeLetterISOLanguageName.ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
private string MigratePrimaries(string primary)
|
||||
{
|
||||
return primary.Replace("BT.", "bt");
|
||||
}
|
||||
|
||||
private string MigrateTransferCharacteristics(string transferCharacteristics)
|
||||
{
|
||||
if (transferCharacteristics == "PQ")
|
||||
{
|
||||
return "smpte2084";
|
||||
}
|
||||
|
||||
if (transferCharacteristics == "HLG")
|
||||
{
|
||||
return "arib-std-b67";
|
||||
}
|
||||
|
||||
return "bt709";
|
||||
}
|
||||
|
||||
private static string GetSceneNameMatch(string sceneName, params string[] tokens)
|
||||
{
|
||||
sceneName = sceneName.IsNotNullOrWhiteSpace() ? Parser.Parser.RemoveFileExtension(sceneName) : string.Empty;
|
||||
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (sceneName.ContainsIgnoreCase(token))
|
||||
{
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
// Last token is the default.
|
||||
return tokens.Last();
|
||||
}
|
||||
|
||||
public class MediaInfoRaw : ModelBase
|
||||
{
|
||||
public string MediaInfo { get; set; }
|
||||
public string SceneName { get; set; }
|
||||
}
|
||||
|
||||
public class MediaInfoBase
|
||||
{
|
||||
public int SchemaRevision { get; set; }
|
||||
}
|
||||
|
||||
public class MediaInfo198 : MediaInfoBase
|
||||
{
|
||||
public string ContainerFormat { get; set; }
|
||||
|
||||
// Deprecated according to MediaInfo
|
||||
public string VideoCodec { get; set; }
|
||||
public string VideoFormat { get; set; }
|
||||
public string VideoCodecID { get; set; }
|
||||
public string VideoProfile { get; set; }
|
||||
public string VideoCodecLibrary { get; set; }
|
||||
public int VideoBitrate { get; set; }
|
||||
public int VideoBitDepth { get; set; }
|
||||
public int VideoMultiViewCount { get; set; }
|
||||
public string VideoColourPrimaries { get; set; }
|
||||
public string VideoTransferCharacteristics { get; set; }
|
||||
public string VideoHdrFormat { get; set; }
|
||||
public string VideoHdrFormatCompatibility { get; set; }
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
public string AudioFormat { get; set; }
|
||||
public string AudioCodecID { get; set; }
|
||||
public string AudioCodecLibrary { get; set; }
|
||||
public string AudioAdditionalFeatures { get; set; }
|
||||
public int AudioBitrate { get; set; }
|
||||
public TimeSpan RunTime { get; set; }
|
||||
public int AudioStreamCount { get; set; }
|
||||
public int AudioChannelsContainer { get; set; }
|
||||
public int AudioChannelsStream { get; set; }
|
||||
public string AudioChannelPositions { get; set; }
|
||||
public string AudioChannelPositionsTextContainer { get; set; }
|
||||
public string AudioChannelPositionsTextStream { get; set; }
|
||||
public string AudioProfile { get; set; }
|
||||
public decimal VideoFps { get; set; }
|
||||
public string AudioLanguages { get; set; }
|
||||
public string Subtitles { get; set; }
|
||||
public string ScanType { get; set; }
|
||||
}
|
||||
|
||||
public class MediaInfo199 : MediaInfoBase
|
||||
{
|
||||
public string ContainerFormat { get; set; }
|
||||
public string VideoFormat { get; set; }
|
||||
public string VideoCodecID { get; set; }
|
||||
public string VideoProfile { get; set; }
|
||||
public int VideoBitrate { get; set; }
|
||||
public int VideoBitDepth { get; set; }
|
||||
public int VideoMultiViewCount { get; set; }
|
||||
public string VideoColourPrimaries { get; set; }
|
||||
public string VideoTransferCharacteristics { get; set; }
|
||||
public HdrFormat VideoHdrFormat { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int Width { get; set; }
|
||||
public string AudioFormat { get; set; }
|
||||
public string AudioCodecID { get; set; }
|
||||
public string AudioProfile { get; set; }
|
||||
public int AudioBitrate { get; set; }
|
||||
public TimeSpan RunTime { get; set; }
|
||||
public int AudioStreamCount { get; set; }
|
||||
public int AudioChannels { get; set; }
|
||||
public string AudioChannelPositions { get; set; }
|
||||
public decimal VideoFps { get; set; }
|
||||
public List<string> AudioLanguages { get; set; }
|
||||
public List<string> Subtitles { get; set; }
|
||||
public string ScanType { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using NzbDrone.Core.Localization;
|
||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
|
||||
namespace NzbDrone.Core.HealthCheck.Checks
|
||||
{
|
||||
public class MediaInfoDllCheck : HealthCheckBase
|
||||
{
|
||||
public MediaInfoDllCheck(ILocalizationService localizationService)
|
||||
: base(localizationService)
|
||||
{
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoOptimization)]
|
||||
public override HealthCheck Check()
|
||||
{
|
||||
try
|
||||
{
|
||||
var mediaInfo = new MediaInfo();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Warning, string.Format(_localizationService.GetLocalizedString("MediaInfoDllCheckMessage"), e.Message), "#mediainfo-not-loaded");
|
||||
}
|
||||
|
||||
return new HealthCheck(GetType());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||
{
|
||||
public enum HdrFormat
|
||||
{
|
||||
None,
|
||||
Pq10,
|
||||
Hdr10,
|
||||
Hdr10Plus,
|
||||
Hlg10,
|
||||
DolbyVision
|
||||
}
|
||||
}
|
@ -1,44 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using FFMpegCore;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||
{
|
||||
public class MediaInfoModel : IEmbeddedDocument
|
||||
{
|
||||
public string ContainerFormat { get; set; }
|
||||
public string RawStreamData { get; set; }
|
||||
public string RawFrameData { get; set; }
|
||||
public int SchemaRevision { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public IMediaAnalysis Analysis => FFProbe.Analyse(RawStreamData);
|
||||
|
||||
// Deprecated according to MediaInfo
|
||||
public string VideoCodec { get; set; }
|
||||
[JsonIgnore]
|
||||
public IMediaAnalysis Frames => FFProbe.Analyse(RawFrameData);
|
||||
|
||||
public string ContainerFormat { get; set; }
|
||||
public string VideoFormat { get; set; }
|
||||
|
||||
public string VideoCodecID { get; set; }
|
||||
|
||||
public string VideoProfile { get; set; }
|
||||
public string VideoCodecLibrary { get; set; }
|
||||
|
||||
public int VideoBitrate { get; set; }
|
||||
|
||||
public int VideoBitDepth { get; set; }
|
||||
|
||||
public int VideoMultiViewCount { get; set; }
|
||||
|
||||
public string VideoColourPrimaries { get; set; }
|
||||
|
||||
public string VideoTransferCharacteristics { get; set; }
|
||||
public string VideoHdrFormat { get; set; }
|
||||
public string VideoHdrFormatCompatibility { get; set; }
|
||||
public int Width { get; set; }
|
||||
|
||||
public DoviConfigurationRecordSideData DoviConfigurationRecord { get; set; }
|
||||
|
||||
public HdrFormat VideoHdrFormat { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
|
||||
public string AudioFormat { get; set; }
|
||||
|
||||
public string AudioCodecID { get; set; }
|
||||
public string AudioCodecLibrary { get; set; }
|
||||
public string AudioAdditionalFeatures { get; set; }
|
||||
|
||||
public string AudioProfile { get; set; }
|
||||
|
||||
public int AudioBitrate { get; set; }
|
||||
|
||||
public TimeSpan RunTime { get; set; }
|
||||
|
||||
public int AudioStreamCount { get; set; }
|
||||
public int AudioChannelsContainer { get; set; }
|
||||
public int AudioChannelsStream { get; set; }
|
||||
|
||||
public int AudioChannels { get; set; }
|
||||
|
||||
public string AudioChannelPositions { get; set; }
|
||||
public string AudioChannelPositionsTextContainer { get; set; }
|
||||
public string AudioChannelPositionsTextStream { get; set; }
|
||||
public string AudioProfile { get; set; }
|
||||
|
||||
public decimal VideoFps { get; set; }
|
||||
public string AudioLanguages { get; set; }
|
||||
public string Subtitles { get; set; }
|
||||
|
||||
public List<string> AudioLanguages { get; set; }
|
||||
|
||||
public List<string> Subtitles { get; set; }
|
||||
|
||||
public string ScanType { get; set; }
|
||||
public int SchemaRevision { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<dllmap os="osx" dll="mediainfo" target="libmediainfo.dylib"/>
|
||||
<dllmap os="linux" dll="mediainfo" target="libmediainfo.so.0" />
|
||||
<dllmap os="freebsd" dll="mediainfo" target="libmediainfo.so.0" />
|
||||
<dllmap os="solaris" dll="mediainfo" target="libmediainfo.so.0.0.0" />
|
||||
</configuration>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue