aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBond_009 <bond.009@outlook.com>2023-02-01 14:58:04 +0100
committerBond_009 <bond.009@outlook.com>2023-02-01 14:58:04 +0100
commit65d605b17dfc978ebc089b7500a5aacd8fcd863f (patch)
tree45b9b6716ba7ff27b302e04925b2952005d510b3
parent992b460912f3100f126bc4db0fe042fd4aefee7c (diff)
Improve ffprobe json parsing and don't log error for Codec Type attachment
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs4
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs5
-rw-r--r--MediaBrowser.MediaEncoding/Probing/CodecType.cs32
-rw-r--r--MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs99
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonBoolStringConverter.cs34
-rw-r--r--src/Jellyfin.Extensions/Json/JsonDefaults.cs1
-rw-r--r--tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs37
-rw-r--r--tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs25
-rw-r--r--tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs22
-rw-r--r--tests/Jellyfin.MediaEncoding.Tests/Test Data/Probing/video_ts.json (renamed from tests/Jellyfin.MediaEncoding.Tests/Test Data/ffprobe1.json)0
11 files changed, 169 insertions, 96 deletions
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 5327b3d74..98bbc1540 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -14,6 +14,7 @@ using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Extensions;
using Jellyfin.Extensions.Json;
+using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
@@ -58,7 +59,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
_socketFactory = socketFactory;
_streamHelper = streamHelper;
- _jsonOptions = JsonDefaults.Options;
+ _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options);
+ _jsonOptions.Converters.Add(new JsonBoolNumberConverter());
}
public string Name => "HD Homerun";
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index d2240b5af..cef02d5f8 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -12,6 +12,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Extensions.Json;
+using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
@@ -105,7 +106,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
_config = config;
_serverConfig = serverConfig;
_startupOptionFFmpegPath = config.GetValue<string>(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty;
- _jsonSerializerOptions = JsonDefaults.Options;
+
+ _jsonSerializerOptions = new JsonSerializerOptions(JsonDefaults.Options);
+ _jsonSerializerOptions.Converters.Add(new JsonBoolStringConverter());
}
/// <inheritdoc />
diff --git a/MediaBrowser.MediaEncoding/Probing/CodecType.cs b/MediaBrowser.MediaEncoding/Probing/CodecType.cs
new file mode 100644
index 000000000..d7c68e5f3
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/Probing/CodecType.cs
@@ -0,0 +1,32 @@
+namespace MediaBrowser.MediaEncoding.Probing;
+
+/// <summary>
+/// FFmpeg Codec Type.
+/// </summary>
+public enum CodecType
+{
+ /// <summary>
+ /// Video.
+ /// </summary>
+ Video,
+
+ /// <summary>
+ /// Audio.
+ /// </summary>
+ Audio,
+
+ /// <summary>
+ /// Opaque data information usually continuous.
+ /// </summary>
+ Data,
+
+ /// <summary>
+ /// Subtitles.
+ /// </summary>
+ Subtitle,
+
+ /// <summary>
+ /// Opaque data information usually sparse.
+ /// </summary>
+ Attachment
+}
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
index eab8f79bb..294442324 100644
--- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
+++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
@@ -43,7 +43,7 @@ namespace MediaBrowser.MediaEncoding.Probing
/// </summary>
/// <value>The codec_type.</value>
[JsonPropertyName("codec_type")]
- public string CodecType { get; set; }
+ public CodecType CodecType { get; set; }
/// <summary>
/// Gets or sets the sample_rate.
@@ -228,11 +228,11 @@ namespace MediaBrowser.MediaEncoding.Probing
public long StartPts { get; set; }
/// <summary>
- /// Gets or sets the is_avc.
+ /// Gets or sets a value indicating whether the stream is AVC.
/// </summary>
/// <value>The is_avc.</value>
[JsonPropertyName("is_avc")]
- public string IsAvc { get; set; }
+ public bool IsAvc { get; set; }
/// <summary>
/// Gets or sets the nal_length_size.
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index c667f5f57..99310a75d 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -107,9 +107,9 @@ namespace MediaBrowser.MediaEncoding.Probing
}
var tags = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- var tagStreamType = isAudio ? "audio" : "video";
+ var tagStreamType = isAudio ? CodecType.Audio : CodecType.Video;
- var tagStream = data.Streams?.FirstOrDefault(i => string.Equals(i.CodecType, tagStreamType, StringComparison.OrdinalIgnoreCase));
+ var tagStream = data.Streams?.FirstOrDefault(i => i.CodecType == tagStreamType);
if (tagStream?.Tags is not null)
{
@@ -599,7 +599,7 @@ namespace MediaBrowser.MediaEncoding.Probing
/// <returns>MediaAttachments.</returns>
private MediaAttachment GetMediaAttachment(MediaStreamInfo streamInfo)
{
- if (!string.Equals(streamInfo.CodecType, "attachment", StringComparison.OrdinalIgnoreCase)
+ if (streamInfo.CodecType != CodecType.Attachment
&& streamInfo.Disposition?.GetValueOrDefault("attached_pic") != 1)
{
return null;
@@ -651,20 +651,10 @@ namespace MediaBrowser.MediaEncoding.Probing
PixelFormat = streamInfo.PixelFormat,
NalLengthSize = streamInfo.NalLengthSize,
TimeBase = streamInfo.TimeBase,
- CodecTimeBase = streamInfo.CodecTimeBase
+ CodecTimeBase = streamInfo.CodecTimeBase,
+ IsAVC = streamInfo.IsAvc
};
- if (string.Equals(streamInfo.IsAvc, "true", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(streamInfo.IsAvc, "1", StringComparison.OrdinalIgnoreCase))
- {
- stream.IsAVC = true;
- }
- else if (string.Equals(streamInfo.IsAvc, "false", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(streamInfo.IsAvc, "0", StringComparison.OrdinalIgnoreCase))
- {
- stream.IsAVC = false;
- }
-
// Filter out junk
if (!string.IsNullOrWhiteSpace(streamInfo.CodecTagString) && !streamInfo.CodecTagString.Contains("[0]", StringComparison.OrdinalIgnoreCase))
{
@@ -678,18 +668,15 @@ namespace MediaBrowser.MediaEncoding.Probing
stream.Title = GetDictionaryValue(streamInfo.Tags, "title");
}
- if (string.Equals(streamInfo.CodecType, "audio", StringComparison.OrdinalIgnoreCase))
+ if (streamInfo.CodecType == CodecType.Audio)
{
stream.Type = MediaStreamType.Audio;
stream.Channels = streamInfo.Channels;
- if (!string.IsNullOrEmpty(streamInfo.SampleRate))
+ if (int.TryParse(streamInfo.SampleRate, NumberStyles.Any, CultureInfo.InvariantCulture, out var value))
{
- if (int.TryParse(streamInfo.SampleRate, NumberStyles.Any, CultureInfo.InvariantCulture, out var value))
- {
- stream.SampleRate = value;
- }
+ stream.SampleRate = value;
}
stream.ChannelLayout = ParseChannelLayout(streamInfo.ChannelLayout);
@@ -713,7 +700,7 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
}
- else if (string.Equals(streamInfo.CodecType, "subtitle", StringComparison.OrdinalIgnoreCase))
+ else if (streamInfo.CodecType == CodecType.Subtitle)
{
stream.Type = MediaStreamType.Subtitle;
stream.Codec = NormalizeSubtitleCodec(stream.Codec);
@@ -733,7 +720,7 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
}
- else if (string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase))
+ else if (streamInfo.CodecType == CodecType.Video)
{
stream.AverageFrameRate = GetFrameRate(streamInfo.AverageFrameRate);
stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate);
@@ -854,13 +841,12 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
}
- else if (string.Equals(streamInfo.CodecType, "data", StringComparison.OrdinalIgnoreCase))
+ else if (streamInfo.CodecType == CodecType.Data)
{
stream.Type = MediaStreamType.Data;
}
else
{
- _logger.LogError("Codec Type {CodecType} unknown. The stream (index: {Index}) will be ignored. Warning: Subsequential streams will have a wrong stream specifier!", streamInfo.CodecType, streamInfo.Index);
return null;
}
@@ -895,29 +881,26 @@ namespace MediaBrowser.MediaEncoding.Probing
// Extract bitrate info from tag "BPS" if possible.
if (!stream.BitRate.HasValue
- && (string.Equals(streamInfo.CodecType, "audio", StringComparison.OrdinalIgnoreCase)
- || string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase)))
+ && (streamInfo.CodecType == CodecType.Audio
+ || streamInfo.CodecType == CodecType.Video))
{
var bps = GetBPSFromTags(streamInfo);
if (bps > 0)
{
stream.BitRate = bps;
}
- }
-
- // Get average bitrate info from tag "NUMBER_OF_BYTES" and "DURATION" if possible.
- if (!stream.BitRate.HasValue
- && (string.Equals(streamInfo.CodecType, "audio", StringComparison.OrdinalIgnoreCase)
- || string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase)))
- {
- var durationInSeconds = GetRuntimeSecondsFromTags(streamInfo);
- var bytes = GetNumberOfBytesFromTags(streamInfo);
- if (durationInSeconds is not null && bytes is not null)
+ else
{
- var bps = Convert.ToInt32(bytes * 8 / durationInSeconds, CultureInfo.InvariantCulture);
- if (bps > 0)
+ // Get average bitrate info from tag "NUMBER_OF_BYTES" and "DURATION" if possible.
+ var durationInSeconds = GetRuntimeSecondsFromTags(streamInfo);
+ var bytes = GetNumberOfBytesFromTags(streamInfo);
+ if (durationInSeconds is not null && bytes is not null)
{
- stream.BitRate = bps;
+ bps = Convert.ToInt32(bytes * 8 / durationInSeconds, CultureInfo.InvariantCulture);
+ if (bps > 0)
+ {
+ stream.BitRate = bps;
+ }
}
}
}
@@ -948,12 +931,8 @@ namespace MediaBrowser.MediaEncoding.Probing
private void NormalizeStreamTitle(MediaStream stream)
{
- if (string.Equals(stream.Title, "cc", StringComparison.OrdinalIgnoreCase))
- {
- stream.Title = null;
- }
-
- if (stream.Type == MediaStreamType.EmbeddedImage)
+ if (string.Equals(stream.Title, "cc", StringComparison.OrdinalIgnoreCase)
+ || stream.Type == MediaStreamType.EmbeddedImage)
{
stream.Title = null;
}
@@ -984,7 +963,7 @@ namespace MediaBrowser.MediaEncoding.Probing
return null;
}
- return input.Split('(').FirstOrDefault();
+ return input.AsSpan().LeftPart('(').ToString();
}
private string GetAspectRatio(MediaStreamInfo info)
@@ -992,11 +971,11 @@ namespace MediaBrowser.MediaEncoding.Probing
var original = info.DisplayAspectRatio;
var parts = (original ?? string.Empty).Split(':');
- if (!(parts.Length == 2 &&
- int.TryParse(parts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out var width) &&
- int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out var height) &&
- width > 0 &&
- height > 0))
+ if (!(parts.Length == 2
+ && int.TryParse(parts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out var width)
+ && int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out var height)
+ && width > 0
+ && height > 0))
{
width = info.Width;
height = info.Height;
@@ -1077,12 +1056,6 @@ namespace MediaBrowser.MediaEncoding.Probing
int index = value.IndexOf('/');
if (index == -1)
{
- // REVIEW: is this branch actually required? (i.e. does ffprobe ever output something other than a fraction?)
- if (float.TryParse(value, NumberStyles.AllowThousands | NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
-
return null;
}
@@ -1098,7 +1071,7 @@ namespace MediaBrowser.MediaEncoding.Probing
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data)
{
// Get the first info stream
- var stream = result.Streams?.FirstOrDefault(s => string.Equals(s.CodecType, "audio", StringComparison.OrdinalIgnoreCase));
+ var stream = result.Streams?.FirstOrDefault(s => s.CodecType == CodecType.Audio);
if (stream is null)
{
return;
@@ -1128,8 +1101,7 @@ namespace MediaBrowser.MediaEncoding.Probing
}
var bps = GetDictionaryValue(streamInfo.Tags, "BPS-eng") ?? GetDictionaryValue(streamInfo.Tags, "BPS");
- if (!string.IsNullOrEmpty(bps)
- && int.TryParse(bps, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBps))
+ if (int.TryParse(bps, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBps))
{
return parsedBps;
}
@@ -1162,8 +1134,7 @@ namespace MediaBrowser.MediaEncoding.Probing
var numberOfBytes = GetDictionaryValue(streamInfo.Tags, "NUMBER_OF_BYTES-eng")
?? GetDictionaryValue(streamInfo.Tags, "NUMBER_OF_BYTES");
- if (!string.IsNullOrEmpty(numberOfBytes)
- && long.TryParse(numberOfBytes, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBytes))
+ if (long.TryParse(numberOfBytes, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBytes))
{
return parsedBytes;
}
@@ -1455,7 +1426,7 @@ namespace MediaBrowser.MediaEncoding.Probing
{
var disc = tags.GetValueOrDefault(tagName);
- if (!string.IsNullOrEmpty(disc) && int.TryParse(disc.AsSpan().LeftPart('/'), out var discNum))
+ if (int.TryParse(disc.AsSpan().LeftPart('/'), out var discNum))
{
return discNum;
}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonBoolStringConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonBoolStringConverter.cs
new file mode 100644
index 000000000..2936fe4d6
--- /dev/null
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonBoolStringConverter.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Buffers;
+using System.Buffers.Text;
+using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Jellyfin.Extensions.Json.Converters;
+
+/// <summary>
+/// Converts a string to a boolean.
+/// This is needed for FFprobe.
+/// </summary>
+public class JsonBoolStringConverter : JsonConverter<bool>
+{
+ /// <inheritdoc />
+ public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ if (reader.TokenType == JsonTokenType.String)
+ {
+ ReadOnlySpan<byte> utf8Span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
+ if (Utf8Parser.TryParse(utf8Span, out bool val, out _, 'l'))
+ {
+ return val;
+ }
+ }
+
+ return reader.GetBoolean();
+ }
+
+ /// <inheritdoc />
+ public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
+ => writer.WriteBooleanValue(value);
+}
diff --git a/src/Jellyfin.Extensions/Json/JsonDefaults.cs b/src/Jellyfin.Extensions/Json/JsonDefaults.cs
index 97cbee971..4d56ca615 100644
--- a/src/Jellyfin.Extensions/Json/JsonDefaults.cs
+++ b/src/Jellyfin.Extensions/Json/JsonDefaults.cs
@@ -39,7 +39,6 @@ namespace Jellyfin.Extensions.Json
new JsonFlagEnumConverterFactory(),
new JsonStringEnumConverter(),
new JsonNullableStructConverterFactory(),
- new JsonBoolNumberConverter(),
new JsonDateTimeConverter(),
new JsonStringConverter()
}
diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs
new file mode 100644
index 000000000..be256da2e
--- /dev/null
+++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs
@@ -0,0 +1,37 @@
+using System.Text.Json;
+using Jellyfin.Extensions.Json.Converters;
+using Xunit;
+
+namespace Jellyfin.Extensions.Tests.Json.Converters
+{
+ public class JsonBoolStringTests
+ {
+ private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions()
+ {
+ Converters =
+ {
+ new JsonBoolStringConverter()
+ }
+ };
+
+ [Theory]
+ [InlineData(@"{ ""Value"": ""true"" }", true)]
+ [InlineData(@"{ ""Value"": ""false"" }", false)]
+ public void Deserialize_String_Valid_Success(string input, bool output)
+ {
+ var s = JsonSerializer.Deserialize<TestStruct>(input, _jsonOptions);
+ Assert.Equal(s.Value, output);
+ }
+
+ [Theory]
+ [InlineData(true, "true")]
+ [InlineData(false, "false")]
+ public void Serialize_Bool_Success(bool input, string output)
+ {
+ var value = JsonSerializer.Serialize(input, _jsonOptions);
+ Assert.Equal(value, output);
+ }
+
+ private readonly record struct TestStruct(bool Value);
+ }
+}
diff --git a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs
deleted file mode 100644
index 97dbb3be0..000000000
--- a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.IO;
-using System.Text.Json;
-using System.Threading.Tasks;
-using Jellyfin.Extensions.Json;
-using MediaBrowser.MediaEncoding.Probing;
-using MediaBrowser.Model.IO;
-using Xunit;
-
-namespace Jellyfin.MediaEncoding.Tests
-{
- public class FFprobeParserTests
- {
- [Theory]
- [InlineData("ffprobe1.json")]
- public async Task Test(string fileName)
- {
- var path = Path.Join("Test Data", fileName);
- await using (var stream = AsyncFile.OpenRead(path))
- {
- var res = await JsonSerializer.DeserializeAsync<InternalMediaInfoResult>(stream, JsonDefaults.Options).ConfigureAwait(false);
- Assert.NotNull(res);
- }
- }
- }
-}
diff --git a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs
index a64604e99..6cb98b2b8 100644
--- a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs
+++ b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs
@@ -3,6 +3,7 @@ using System.Globalization;
using System.IO;
using System.Text.Json;
using Jellyfin.Extensions.Json;
+using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.MediaEncoding.Probing;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
@@ -15,9 +16,15 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
{
public class ProbeResultNormalizerTests
{
- private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
+ private readonly JsonSerializerOptions _jsonOptions;
private readonly ProbeResultNormalizer _probeResultNormalizer = new ProbeResultNormalizer(new NullLogger<EncoderValidatorTests>(), null);
+ public ProbeResultNormalizerTests()
+ {
+ _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options);
+ _jsonOptions.Converters.Add(new JsonBoolStringConverter());
+ }
+
[Theory]
[InlineData("2997/125", 23.976f)]
[InlineData("1/50", 0.02f)]
@@ -149,6 +156,19 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
}
[Fact]
+ public void GetMediaInfo_TS_Success()
+ {
+ var bytes = File.ReadAllBytes("Test Data/Probing/video_ts.json");
+ var internalMediaInfoResult = JsonSerializer.Deserialize<InternalMediaInfoResult>(bytes, _jsonOptions);
+
+ MediaInfo res = _probeResultNormalizer.GetMediaInfo(internalMediaInfoResult, VideoType.VideoFile, false, "Test Data/Probing/video_metadata.mkv", MediaProtocol.File);
+
+ Assert.Equal(2, res.MediaStreams.Count);
+
+ Assert.False(res.MediaStreams[0].IsAVC);
+ }
+
+ [Fact]
public void GetMediaInfo_ProgressiveVideoNoFieldOrder_Success()
{
var bytes = File.ReadAllBytes("Test Data/Probing/video_progressive_no_field_order.json");
diff --git a/tests/Jellyfin.MediaEncoding.Tests/Test Data/ffprobe1.json b/tests/Jellyfin.MediaEncoding.Tests/Test Data/Probing/video_ts.json
index cdad5df50..cdad5df50 100644
--- a/tests/Jellyfin.MediaEncoding.Tests/Test Data/ffprobe1.json
+++ b/tests/Jellyfin.MediaEncoding.Tests/Test Data/Probing/video_ts.json