diff --git a/MediaBrowser.Common/Json/Converters/GuidConverter.cs b/MediaBrowser.Common/Json/Converters/JsonGuidConverter.cs
similarity index 91%
rename from MediaBrowser.Common/Json/Converters/GuidConverter.cs
rename to MediaBrowser.Common/Json/Converters/JsonGuidConverter.cs
index 3081e12ee..d35a761f3 100644
--- a/MediaBrowser.Common/Json/Converters/GuidConverter.cs
+++ b/MediaBrowser.Common/Json/Converters/JsonGuidConverter.cs
@@ -7,7 +7,7 @@ namespace MediaBrowser.Common.Json.Converters
///
/// Converts a GUID object or value to/from JSON.
///
- public class GuidConverter : JsonConverter
+ public class JsonGuidConverter : JsonConverter
{
///
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
diff --git a/MediaBrowser.Common/Json/Converters/JsonInt32Converter.cs b/MediaBrowser.Common/Json/Converters/JsonInt32Converter.cs
new file mode 100644
index 000000000..fe5dd6cd4
--- /dev/null
+++ b/MediaBrowser.Common/Json/Converters/JsonInt32Converter.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Buffers;
+using System.Buffers.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.Common.Json.Converters
+{
+ ///
+ /// Converts a GUID object or value to/from JSON.
+ ///
+ public class JsonInt32Converter : JsonConverter
+ {
+ ///
+ public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ static void ThrowFormatException() => throw new FormatException("Invalid format for an integer.");
+ ReadOnlySpan span = stackalloc byte[0];
+
+ if (reader.HasValueSequence)
+ {
+ long sequenceLength = reader.ValueSequence.Length;
+ Span stackSpan = stackalloc byte[(int)sequenceLength];
+ reader.ValueSequence.CopyTo(stackSpan);
+ span = stackSpan;
+ }
+ else
+ {
+ span = reader.ValueSpan;
+ }
+
+ if (!Utf8Parser.TryParse(span, out int number, out _))
+ {
+ ThrowFormatException();
+ }
+
+ return number;
+ }
+
+ ///
+ public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
+ {
+ static void ThrowInvalidOperationException() => throw new InvalidOperationException();
+ Span span = stackalloc byte[16];
+ if (Utf8Formatter.TryFormat(value, span, out int bytesWritten))
+ {
+ writer.WriteStringValue(span.Slice(0, bytesWritten));
+ }
+
+ ThrowInvalidOperationException();
+ }
+ }
+}
diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs
index 4ba0d5a1a..4a6ee0a79 100644
--- a/MediaBrowser.Common/Json/JsonDefaults.cs
+++ b/MediaBrowser.Common/Json/JsonDefaults.cs
@@ -21,7 +21,7 @@ namespace MediaBrowser.Common.Json
WriteIndented = false
};
- options.Converters.Add(new GuidConverter());
+ options.Converters.Add(new JsonGuidConverter());
options.Converters.Add(new JsonStringEnumConverter());
return options;
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 6bcd6cd46..e0f7b992c 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -397,7 +397,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
try
{
result = await JsonSerializer.DeserializeAsync(
- process.StandardOutput.BaseStream).ConfigureAwait(false);
+ process.StandardOutput.BaseStream,
+ cancellationToken: cancellationToken).ConfigureAwait(false);
}
catch
{
@@ -406,24 +407,24 @@ namespace MediaBrowser.MediaEncoding.Encoder
throw;
}
- if (result == null || (result.streams == null && result.format == null))
+ if (result == null || (result.Streams == null && result.Format == null))
{
throw new Exception("ffprobe failed - streams and format are both null.");
}
- if (result.streams != null)
+ if (result.Streams != null)
{
// Normalize aspect ratio if invalid
- foreach (var stream in result.streams)
+ foreach (var stream in result.Streams)
{
- if (string.Equals(stream.display_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(stream.DisplayAspectRatio, "0:1", StringComparison.OrdinalIgnoreCase))
{
- stream.display_aspect_ratio = string.Empty;
+ stream.DisplayAspectRatio = string.Empty;
}
- if (string.Equals(stream.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(stream.SampleAspectRatio, "0:1", StringComparison.OrdinalIgnoreCase))
{
- stream.sample_aspect_ratio = string.Empty;
+ stream.SampleAspectRatio = string.Empty;
}
}
}
@@ -778,6 +779,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_runningProcesses.Add(process);
}
}
+
private void StopProcess(ProcessWrapper process, int waitTimeMs)
{
try
@@ -786,18 +788,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
return;
}
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error in WaitForExit");
- }
- try
- {
_logger.LogInformation("Killing ffmpeg process");
process.Process.Kill();
}
+ catch (InvalidOperationException)
+ {
+ // The process has already exited or
+ // there is no process associated with this Process object.
+ }
catch (Exception ex)
{
_logger.LogError(ex, "Error killing process");
diff --git a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
index e4eabaf38..78dc7b607 100644
--- a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
+++ b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
@@ -16,24 +16,19 @@ namespace MediaBrowser.MediaEncoding.Probing
throw new ArgumentNullException(nameof(result));
}
- if (result.format != null && result.format.tags != null)
+ if (result.Format != null && result.Format.Tags != null)
{
- result.format.tags = ConvertDictionaryToCaseInSensitive(result.format.tags);
+ result.Format.Tags = ConvertDictionaryToCaseInsensitive(result.Format.Tags);
}
- if (result.streams != null)
+ if (result.Streams != null)
{
// Convert all dictionaries to case insensitive
- foreach (var stream in result.streams)
+ foreach (var stream in result.Streams)
{
- if (stream.tags != null)
+ if (stream.Tags != null)
{
- stream.tags = ConvertDictionaryToCaseInSensitive(stream.tags);
- }
-
- if (stream.disposition != null)
- {
- stream.disposition = ConvertDictionaryToCaseInSensitive(stream.disposition);
+ stream.Tags = ConvertDictionaryToCaseInsensitive(stream.Tags);
}
}
}
@@ -45,7 +40,7 @@ namespace MediaBrowser.MediaEncoding.Probing
/// The tags.
/// The key.
/// System.String.
- public static string GetDictionaryValue(Dictionary tags, string key)
+ public static string GetDictionaryValue(IReadOnlyDictionary tags, string key)
{
if (tags == null)
{
@@ -103,7 +98,7 @@ namespace MediaBrowser.MediaEncoding.Probing
///
/// The dict.
/// Dictionary{System.StringSystem.String}.
- private static Dictionary ConvertDictionaryToCaseInSensitive(Dictionary dict)
+ private static Dictionary ConvertDictionaryToCaseInsensitive(IReadOnlyDictionary dict)
{
return new Dictionary(dict, StringComparer.OrdinalIgnoreCase);
}
diff --git a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs
index cc9d27608..0e319c1a8 100644
--- a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs
+++ b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs
@@ -1,9 +1,10 @@
using System.Collections.Generic;
+using System.Text.Json.Serialization;
namespace MediaBrowser.MediaEncoding.Probing
{
///
- /// Class MediaInfoResult
+ /// Class MediaInfoResult.
///
public class InternalMediaInfoResult
{
@@ -11,331 +12,21 @@ namespace MediaBrowser.MediaEncoding.Probing
/// Gets or sets the streams.
///
/// The streams.
- public MediaStreamInfo[] streams { get; set; }
+ [JsonPropertyName("streams")]
+ public IReadOnlyList Streams { get; set; }
///
/// Gets or sets the format.
///
/// The format.
- public MediaFormatInfo format { get; set; }
+ [JsonPropertyName("format")]
+ public MediaFormatInfo Format { get; set; }
///
/// Gets or sets the chapters.
///
/// The chapters.
- public MediaChapter[] Chapters { get; set; }
- }
-
- public class MediaChapter
- {
- public int id { get; set; }
- public string time_base { get; set; }
- public long start { get; set; }
- public string start_time { get; set; }
- public long end { get; set; }
- public string end_time { get; set; }
- public Dictionary tags { get; set; }
- }
-
- ///
- /// Represents a stream within the output
- ///
- public class MediaStreamInfo
- {
- ///
- /// Gets or sets the index.
- ///
- /// The index.
- public int index { get; set; }
-
- ///
- /// Gets or sets the profile.
- ///
- /// The profile.
- public string profile { get; set; }
-
- ///
- /// Gets or sets the codec_name.
- ///
- /// The codec_name.
- public string codec_name { get; set; }
-
- ///
- /// Gets or sets the codec_long_name.
- ///
- /// The codec_long_name.
- public string codec_long_name { get; set; }
-
- ///
- /// Gets or sets the codec_type.
- ///
- /// The codec_type.
- public string codec_type { get; set; }
-
- ///
- /// Gets or sets the sample_rate.
- ///
- /// The sample_rate.
- public string sample_rate { get; set; }
-
- ///
- /// Gets or sets the channels.
- ///
- /// The channels.
- public int channels { get; set; }
-
- ///
- /// Gets or sets the channel_layout.
- ///
- /// The channel_layout.
- public string channel_layout { get; set; }
-
- ///
- /// Gets or sets the avg_frame_rate.
- ///
- /// The avg_frame_rate.
- public string avg_frame_rate { get; set; }
-
- ///
- /// Gets or sets the duration.
- ///
- /// The duration.
- public string duration { get; set; }
-
- ///
- /// Gets or sets the bit_rate.
- ///
- /// The bit_rate.
- public string bit_rate { get; set; }
-
- ///
- /// Gets or sets the width.
- ///
- /// The width.
- public int width { get; set; }
-
- ///
- /// Gets or sets the refs.
- ///
- /// The refs.
- public int refs { get; set; }
-
- ///
- /// Gets or sets the height.
- ///
- /// The height.
- public int height { get; set; }
-
- ///
- /// Gets or sets the display_aspect_ratio.
- ///
- /// The display_aspect_ratio.
- public string display_aspect_ratio { get; set; }
-
- ///
- /// Gets or sets the tags.
- ///
- /// The tags.
- public Dictionary tags { get; set; }
-
- ///
- /// Gets or sets the bits_per_sample.
- ///
- /// The bits_per_sample.
- public int bits_per_sample { get; set; }
-
- ///
- /// Gets or sets the bits_per_raw_sample.
- ///
- /// The bits_per_raw_sample.
- public int bits_per_raw_sample { get; set; }
-
- ///
- /// Gets or sets the r_frame_rate.
- ///
- /// The r_frame_rate.
- public string r_frame_rate { get; set; }
-
- ///
- /// Gets or sets the has_b_frames.
- ///
- /// The has_b_frames.
- public int has_b_frames { get; set; }
-
- ///
- /// Gets or sets the sample_aspect_ratio.
- ///
- /// The sample_aspect_ratio.
- public string sample_aspect_ratio { get; set; }
-
- ///
- /// Gets or sets the pix_fmt.
- ///
- /// The pix_fmt.
- public string pix_fmt { get; set; }
-
- ///
- /// Gets or sets the level.
- ///
- /// The level.
- public int level { get; set; }
-
- ///
- /// Gets or sets the time_base.
- ///
- /// The time_base.
- public string time_base { get; set; }
-
- ///
- /// Gets or sets the start_time.
- ///
- /// The start_time.
- public string start_time { get; set; }
-
- ///
- /// Gets or sets the codec_time_base.
- ///
- /// The codec_time_base.
- public string codec_time_base { get; set; }
-
- ///
- /// Gets or sets the codec_tag.
- ///
- /// The codec_tag.
- public string codec_tag { get; set; }
-
- ///
- /// Gets or sets the codec_tag_string.
- ///
- /// The codec_tag_string.
- public string codec_tag_string { get; set; }
-
- ///
- /// Gets or sets the sample_fmt.
- ///
- /// The sample_fmt.
- public string sample_fmt { get; set; }
-
- ///
- /// Gets or sets the dmix_mode.
- ///
- /// The dmix_mode.
- public string dmix_mode { get; set; }
-
- ///
- /// Gets or sets the start_pts.
- ///
- /// The start_pts.
- public string start_pts { get; set; }
-
- ///
- /// Gets or sets the is_avc.
- ///
- /// The is_avc.
- public string is_avc { get; set; }
-
- ///
- /// Gets or sets the nal_length_size.
- ///
- /// The nal_length_size.
- public string nal_length_size { get; set; }
-
- ///
- /// Gets or sets the ltrt_cmixlev.
- ///
- /// The ltrt_cmixlev.
- public string ltrt_cmixlev { get; set; }
-
- ///
- /// Gets or sets the ltrt_surmixlev.
- ///
- /// The ltrt_surmixlev.
- public string ltrt_surmixlev { get; set; }
-
- ///
- /// Gets or sets the loro_cmixlev.
- ///
- /// The loro_cmixlev.
- public string loro_cmixlev { get; set; }
-
- ///
- /// Gets or sets the loro_surmixlev.
- ///
- /// The loro_surmixlev.
- public string loro_surmixlev { get; set; }
-
- public string field_order { get; set; }
-
- ///
- /// Gets or sets the disposition.
- ///
- /// The disposition.
- public Dictionary disposition { get; set; }
- }
-
- ///
- /// Class MediaFormat
- ///
- public class MediaFormatInfo
- {
- ///
- /// Gets or sets the filename.
- ///
- /// The filename.
- public string filename { get; set; }
-
- ///
- /// Gets or sets the nb_streams.
- ///
- /// The nb_streams.
- public int nb_streams { get; set; }
-
- ///
- /// Gets or sets the format_name.
- ///
- /// The format_name.
- public string format_name { get; set; }
-
- ///
- /// Gets or sets the format_long_name.
- ///
- /// The format_long_name.
- public string format_long_name { get; set; }
-
- ///
- /// Gets or sets the start_time.
- ///
- /// The start_time.
- public string start_time { get; set; }
-
- ///
- /// Gets or sets the duration.
- ///
- /// The duration.
- public string duration { get; set; }
-
- ///
- /// Gets or sets the size.
- ///
- /// The size.
- public string size { get; set; }
-
- ///
- /// Gets or sets the bit_rate.
- ///
- /// The bit_rate.
- public string bit_rate { get; set; }
-
- ///
- /// Gets or sets the probe_score.
- ///
- /// The probe_score.
- public int probe_score { get; set; }
-
- ///
- /// Gets or sets the tags.
- ///
- /// The tags.
- public Dictionary tags { get; set; }
+ [JsonPropertyName("chapters")]
+ public IReadOnlyList Chapters { get; set; }
}
}
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs b/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
new file mode 100644
index 000000000..6a45ccf49
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.MediaEncoding.Probing
+{
+ ///
+ /// Class MediaChapter.
+ ///
+ public class MediaChapter
+ {
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ [JsonPropertyName("time_base")]
+ public string TimeBase { get; set; }
+
+ [JsonPropertyName("start")]
+ public long Start { get; set; }
+
+ [JsonPropertyName("start_time")]
+ public string StartTime { get; set; }
+
+ [JsonPropertyName("end")]
+ public long End { get; set; }
+
+ [JsonPropertyName("end_time")]
+ public string EndTime { get; set; }
+
+ [JsonPropertyName("tags")]
+ public IReadOnlyDictionary Tags { get; set; }
+ }
+}
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs
new file mode 100644
index 000000000..8af122ef9
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs
@@ -0,0 +1,81 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.MediaEncoding.Probing
+{
+ ///
+ /// Class MediaFormat.
+ ///
+ public class MediaFormatInfo
+ {
+ ///
+ /// Gets or sets the filename.
+ ///
+ /// The filename.
+ [JsonPropertyName("filename")]
+ public string FileName { get; set; }
+
+ ///
+ /// Gets or sets the nb_streams.
+ ///
+ /// The nb_streams.
+ [JsonPropertyName("nb_streams")]
+ public int NbStreams { get; set; }
+
+ ///
+ /// Gets or sets the format_name.
+ ///
+ /// The format_name.
+ [JsonPropertyName("format_name")]
+ public string FormatName { get; set; }
+
+ ///
+ /// Gets or sets the format_long_name.
+ ///
+ /// The format_long_name.
+ [JsonPropertyName("format_long_name")]
+ public string FormatLongName { get; set; }
+
+ ///
+ /// Gets or sets the start_time.
+ ///
+ /// The start_time.
+ [JsonPropertyName("start_time")]
+ public string StartTime { get; set; }
+
+ ///
+ /// Gets or sets the duration.
+ ///
+ /// The duration.
+ [JsonPropertyName("duration")]
+ public string Duration { get; set; }
+
+ ///
+ /// Gets or sets the size.
+ ///
+ /// The size.
+ [JsonPropertyName("size")]
+ public string Size { get; set; }
+
+ ///
+ /// Gets or sets the bit_rate.
+ ///
+ /// The bit_rate.
+ [JsonPropertyName("bit_rate")]
+ public string BitRate { get; set; }
+
+ ///
+ /// Gets or sets the probe_score.
+ ///
+ /// The probe_score.
+ [JsonPropertyName("probe_score")]
+ public int ProbeScore { get; set; }
+
+ ///
+ /// Gets or sets the tags.
+ ///
+ /// The tags.
+ [JsonPropertyName("tags")]
+ public IReadOnlyDictionary Tags { get; set; }
+ }
+}
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
new file mode 100644
index 000000000..7fa7afa5b
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
@@ -0,0 +1,282 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+using MediaBrowser.Common.Json.Converters;
+
+namespace MediaBrowser.MediaEncoding.Probing
+{
+ ///
+ /// Represents a stream within the output.
+ ///
+ public class MediaStreamInfo
+ {
+ ///
+ /// Gets or sets the index.
+ ///
+ /// The index.
+ [JsonPropertyName("index")]
+ public int Index { get; set; }
+
+ ///
+ /// Gets or sets the profile.
+ ///
+ /// The profile.
+ [JsonPropertyName("profile")]
+ public string Profile { get; set; }
+
+ ///
+ /// Gets or sets the codec_name.
+ ///
+ /// The codec_name.
+ [JsonPropertyName("codec_name")]
+ public string CodecName { get; set; }
+
+ ///
+ /// Gets or sets the codec_long_name.
+ ///
+ /// The codec_long_name.
+ [JsonPropertyName("codec_long_name")]
+ public string CodecLongName { get; set; }
+
+ ///
+ /// Gets or sets the codec_type.
+ ///
+ /// The codec_type.
+ [JsonPropertyName("codec_type")]
+ public string CodecType { get; set; }
+
+ ///
+ /// Gets or sets the sample_rate.
+ ///
+ /// The sample_rate.
+ [JsonPropertyName("sample_rate")]
+ public string SampleRate { get; set; }
+
+ ///
+ /// Gets or sets the channels.
+ ///
+ /// The channels.
+ [JsonPropertyName("channels")]
+ public int Channels { get; set; }
+
+ ///
+ /// Gets or sets the channel_layout.
+ ///
+ /// The channel_layout.
+ [JsonPropertyName("channel_layout")]
+ public string ChannelLayout { get; set; }
+
+ ///
+ /// Gets or sets the avg_frame_rate.
+ ///
+ /// The avg_frame_rate.
+ [JsonPropertyName("avg_frame_rate")]
+ public string AverageFrameRate { get; set; }
+
+ ///
+ /// Gets or sets the duration.
+ ///
+ /// The duration.
+ [JsonPropertyName("duration")]
+ public string Duration { get; set; }
+
+ ///
+ /// Gets or sets the bit_rate.
+ ///
+ /// The bit_rate.
+ [JsonPropertyName("bit_rate")]
+ public string BitRate { get; set; }
+
+ ///
+ /// Gets or sets the width.
+ ///
+ /// The width.
+ [JsonPropertyName("width")]
+ public int Width { get; set; }
+
+ ///
+ /// Gets or sets the refs.
+ ///
+ /// The refs.
+ [JsonPropertyName("refs")]
+ public int Refs { get; set; }
+
+ ///
+ /// Gets or sets the height.
+ ///
+ /// The height.
+ [JsonPropertyName("height")]
+ public int Height { get; set; }
+
+ ///
+ /// Gets or sets the display_aspect_ratio.
+ ///
+ /// The display_aspect_ratio.
+ [JsonPropertyName("display_aspect_ratio")]
+ public string DisplayAspectRatio { get; set; }
+
+ ///
+ /// Gets or sets the tags.
+ ///
+ /// The tags.
+ [JsonPropertyName("tags")]
+ public IReadOnlyDictionary Tags { get; set; }
+
+ ///
+ /// Gets or sets the bits_per_sample.
+ ///
+ /// The bits_per_sample.
+ [JsonPropertyName("bits_per_sample")]
+ public int BitsPerSample { get; set; }
+
+ ///
+ /// Gets or sets the bits_per_raw_sample.
+ ///
+ /// The bits_per_raw_sample.
+ [JsonPropertyName("bits_per_raw_sample")]
+ [JsonConverter(typeof(JsonInt32Converter))]
+ public int BitsPerRawSample { get; set; }
+
+ ///
+ /// Gets or sets the r_frame_rate.
+ ///
+ /// The r_frame_rate.
+ [JsonPropertyName("r_frame_rate")]
+ public string RFrameRate { get; set; }
+
+ ///
+ /// Gets or sets the has_b_frames.
+ ///
+ /// The has_b_frames.
+ [JsonPropertyName("has_b_frames")]
+ public int HasBFrames { get; set; }
+
+ ///
+ /// Gets or sets the sample_aspect_ratio.
+ ///
+ /// The sample_aspect_ratio.
+ [JsonPropertyName("sample_aspect_ratio")]
+ public string SampleAspectRatio { get; set; }
+
+ ///
+ /// Gets or sets the pix_fmt.
+ ///
+ /// The pix_fmt.
+ [JsonPropertyName("pix_fmt")]
+ public string PixelFormat { get; set; }
+
+ ///
+ /// Gets or sets the level.
+ ///
+ /// The level.
+ [JsonPropertyName("level")]
+ public int Level { get; set; }
+
+ ///
+ /// Gets or sets the time_base.
+ ///
+ /// The time_base.
+ [JsonPropertyName("time_base")]
+ public string TimeBase { get; set; }
+
+ ///
+ /// Gets or sets the start_time.
+ ///
+ /// The start_time.
+ [JsonPropertyName("start_time")]
+ public string StartTime { get; set; }
+
+ ///
+ /// Gets or sets the codec_time_base.
+ ///
+ /// The codec_time_base.
+ [JsonPropertyName("codec_time_base")]
+ public string CodecTimeBase { get; set; }
+
+ ///
+ /// Gets or sets the codec_tag.
+ ///
+ /// The codec_tag.
+ [JsonPropertyName("codec_tag")]
+ public string CodecTag { get; set; }
+
+ ///
+ /// Gets or sets the codec_tag_string.
+ ///
+ /// The codec_tag_string.
+ [JsonPropertyName("codec_tag_string")]
+ public string CodecTagString { get; set; }
+
+ ///
+ /// Gets or sets the sample_fmt.
+ ///
+ /// The sample_fmt.
+ [JsonPropertyName("sample_fmt")]
+ public string SampleFmt { get; set; }
+
+ ///
+ /// Gets or sets the dmix_mode.
+ ///
+ /// The dmix_mode.
+ [JsonPropertyName("dmix_mode")]
+ public string DmixMode { get; set; }
+
+ ///
+ /// Gets or sets the start_pts.
+ ///
+ /// The start_pts.
+ [JsonPropertyName("start_pts")]
+ public int StartPts { get; set; }
+
+ ///
+ /// Gets or sets the is_avc.
+ ///
+ /// The is_avc.
+ [JsonPropertyName("is_avc")]
+ public string IsAvc { get; set; }
+
+ ///
+ /// Gets or sets the nal_length_size.
+ ///
+ /// The nal_length_size.
+ [JsonPropertyName("nal_length_size")]
+ public string NalLengthSize { get; set; }
+
+ ///
+ /// Gets or sets the ltrt_cmixlev.
+ ///
+ /// The ltrt_cmixlev.
+ [JsonPropertyName("ltrt_cmixlev")]
+ public string LtrtCmixlev { get; set; }
+
+ ///
+ /// Gets or sets the ltrt_surmixlev.
+ ///
+ /// The ltrt_surmixlev.
+ [JsonPropertyName("ltrt_surmixlev")]
+ public string LtrtSurmixlev { get; set; }
+
+ ///
+ /// Gets or sets the loro_cmixlev.
+ ///
+ /// The loro_cmixlev.
+ [JsonPropertyName("loro_cmixlev")]
+ public string LoroCmixlev { get; set; }
+
+ ///
+ /// Gets or sets the loro_surmixlev.
+ ///
+ /// The loro_surmixlev.
+ [JsonPropertyName("loro_surmixlev")]
+ public string LoroSurmixlev { get; set; }
+
+ [JsonPropertyName("field_order")]
+ public string FieldOrder { get; set; }
+
+ ///
+ /// Gets or sets the disposition.
+ ///
+ /// The disposition.
+ [JsonPropertyName("disposition")]
+ public IReadOnlyDictionary Disposition { get; set; }
+ }
+}
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index a46aa38d8..bd89c6cae 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -8,7 +8,6 @@ using System.Xml;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
@@ -41,9 +40,9 @@ namespace MediaBrowser.MediaEncoding.Probing
FFProbeHelpers.NormalizeFFProbeResult(data);
SetSize(data, info);
- var internalStreams = data.streams ?? new MediaStreamInfo[] { };
+ var internalStreams = data.Streams ?? new MediaStreamInfo[] { };
- info.MediaStreams = internalStreams.Select(s => GetMediaStream(isAudio, s, data.format))
+ info.MediaStreams = internalStreams.Select(s => GetMediaStream(isAudio, s, data.Format))
.Where(i => i != null)
// Drop subtitle streams if we don't know the codec because it will just cause failures if we don't know how to handle them
.Where(i => i.Type != MediaStreamType.Subtitle || !string.IsNullOrWhiteSpace(i.Codec))
@@ -53,13 +52,13 @@ namespace MediaBrowser.MediaEncoding.Probing
.Where(i => i != null)
.ToList();
- if (data.format != null)
+ if (data.Format != null)
{
- info.Container = NormalizeFormat(data.format.format_name);
+ info.Container = NormalizeFormat(data.Format.FormatName);
- if (!string.IsNullOrEmpty(data.format.bit_rate))
+ if (!string.IsNullOrEmpty(data.Format.BitRate))
{
- if (int.TryParse(data.format.bit_rate, NumberStyles.Any, _usCulture, out var value))
+ if (int.TryParse(data.Format.BitRate, NumberStyles.Any, _usCulture, out var value))
{
info.Bitrate = value;
}
@@ -69,22 +68,22 @@ namespace MediaBrowser.MediaEncoding.Probing
var tags = new Dictionary(StringComparer.OrdinalIgnoreCase);
var tagStreamType = isAudio ? "audio" : "video";
- if (data.streams != null)
+ if (data.Streams != null)
{
- var tagStream = data.streams.FirstOrDefault(i => string.Equals(i.codec_type, tagStreamType, StringComparison.OrdinalIgnoreCase));
+ var tagStream = data.Streams.FirstOrDefault(i => string.Equals(i.CodecType, tagStreamType, StringComparison.OrdinalIgnoreCase));
- if (tagStream != null && tagStream.tags != null)
+ if (tagStream != null && tagStream.Tags != null)
{
- foreach (var pair in tagStream.tags)
+ foreach (var pair in tagStream.Tags)
{
tags[pair.Key] = pair.Value;
}
}
}
- if (data.format != null && data.format.tags != null)
+ if (data.Format != null && data.Format.Tags != null)
{
- foreach (var pair in data.format.tags)
+ foreach (var pair in data.Format.Tags)
{
tags[pair.Key] = pair.Value;
}
@@ -157,9 +156,9 @@ namespace MediaBrowser.MediaEncoding.Probing
FetchFromItunesInfo(itunesXml, info);
}
- if (data.format != null && !string.IsNullOrEmpty(data.format.duration))
+ if (data.Format != null && !string.IsNullOrEmpty(data.Format.Duration))
{
- info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
+ info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.Format.Duration, _usCulture)).Ticks;
}
FetchWtvInfo(info, data);
@@ -524,27 +523,27 @@ namespace MediaBrowser.MediaEncoding.Probing
/// MediaAttachments.
private MediaAttachment GetMediaAttachment(MediaStreamInfo streamInfo)
{
- if (!string.Equals(streamInfo.codec_type, "attachment", StringComparison.OrdinalIgnoreCase))
+ if (!string.Equals(streamInfo.CodecType, "attachment", StringComparison.OrdinalIgnoreCase))
{
return null;
}
var attachment = new MediaAttachment
{
- Codec = streamInfo.codec_name,
- Index = streamInfo.index
+ Codec = streamInfo.CodecName,
+ Index = streamInfo.Index
};
- if (!string.IsNullOrWhiteSpace(streamInfo.codec_tag_string))
+ if (!string.IsNullOrWhiteSpace(streamInfo.CodecTagString))
{
- attachment.CodecTag = streamInfo.codec_tag_string;
+ attachment.CodecTag = streamInfo.CodecTagString;
}
- if (streamInfo.tags != null)
+ if (streamInfo.Tags != null)
{
- attachment.FileName = GetDictionaryValue(streamInfo.tags, "filename");
- attachment.MimeType = GetDictionaryValue(streamInfo.tags, "mimetype");
- attachment.Comment = GetDictionaryValue(streamInfo.tags, "comment");
+ attachment.FileName = GetDictionaryValue(streamInfo.Tags, "filename");
+ attachment.MimeType = GetDictionaryValue(streamInfo.Tags, "mimetype");
+ attachment.Comment = GetDictionaryValue(streamInfo.Tags, "comment");
}
return attachment;
@@ -560,7 +559,7 @@ namespace MediaBrowser.MediaEncoding.Probing
private MediaStream GetMediaStream(bool isAudio, MediaStreamInfo streamInfo, MediaFormatInfo formatInfo)
{
// These are mp4 chapters
- if (string.Equals(streamInfo.codec_name, "mov_text", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(streamInfo.CodecName, "mov_text", StringComparison.OrdinalIgnoreCase))
{
// Edit: but these are also sometimes subtitles?
//return null;
@@ -568,71 +567,71 @@ namespace MediaBrowser.MediaEncoding.Probing
var stream = new MediaStream
{
- Codec = streamInfo.codec_name,
- Profile = streamInfo.profile,
- Level = streamInfo.level,
- Index = streamInfo.index,
- PixelFormat = streamInfo.pix_fmt,
- NalLengthSize = streamInfo.nal_length_size,
- TimeBase = streamInfo.time_base,
- CodecTimeBase = streamInfo.codec_time_base
+ Codec = streamInfo.CodecName,
+ Profile = streamInfo.Profile,
+ Level = streamInfo.Level,
+ Index = streamInfo.Index,
+ PixelFormat = streamInfo.PixelFormat,
+ NalLengthSize = streamInfo.NalLengthSize,
+ TimeBase = streamInfo.TimeBase,
+ CodecTimeBase = streamInfo.CodecTimeBase
};
- if (string.Equals(streamInfo.is_avc, "true", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(streamInfo.is_avc, "1", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(streamInfo.IsAvc, "true", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(streamInfo.IsAvc, "1", StringComparison.OrdinalIgnoreCase))
{
stream.IsAVC = true;
}
- else if (string.Equals(streamInfo.is_avc, "false", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(streamInfo.is_avc, "0", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(streamInfo.IsAvc, "false", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(streamInfo.IsAvc, "0", StringComparison.OrdinalIgnoreCase))
{
stream.IsAVC = false;
}
- if (!string.IsNullOrWhiteSpace(streamInfo.field_order) && !string.Equals(streamInfo.field_order, "progressive", StringComparison.OrdinalIgnoreCase))
+ if (!string.IsNullOrWhiteSpace(streamInfo.FieldOrder) && !string.Equals(streamInfo.FieldOrder, "progressive", StringComparison.OrdinalIgnoreCase))
{
stream.IsInterlaced = true;
}
// Filter out junk
- if (!string.IsNullOrWhiteSpace(streamInfo.codec_tag_string) && streamInfo.codec_tag_string.IndexOf("[0]", StringComparison.OrdinalIgnoreCase) == -1)
+ if (!string.IsNullOrWhiteSpace(streamInfo.CodecTagString) && streamInfo.CodecTagString.IndexOf("[0]", StringComparison.OrdinalIgnoreCase) == -1)
{
- stream.CodecTag = streamInfo.codec_tag_string;
+ stream.CodecTag = streamInfo.CodecTagString;
}
- if (streamInfo.tags != null)
+ if (streamInfo.Tags != null)
{
- stream.Language = GetDictionaryValue(streamInfo.tags, "language");
- stream.Comment = GetDictionaryValue(streamInfo.tags, "comment");
- stream.Title = GetDictionaryValue(streamInfo.tags, "title");
+ stream.Language = GetDictionaryValue(streamInfo.Tags, "language");
+ stream.Comment = GetDictionaryValue(streamInfo.Tags, "comment");
+ stream.Title = GetDictionaryValue(streamInfo.Tags, "title");
}
- if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(streamInfo.CodecType, "audio", StringComparison.OrdinalIgnoreCase))
{
stream.Type = MediaStreamType.Audio;
- stream.Channels = streamInfo.channels;
+ stream.Channels = streamInfo.Channels;
- if (!string.IsNullOrEmpty(streamInfo.sample_rate))
+ if (!string.IsNullOrEmpty(streamInfo.SampleRate))
{
- if (int.TryParse(streamInfo.sample_rate, NumberStyles.Any, _usCulture, out var value))
+ if (int.TryParse(streamInfo.SampleRate, NumberStyles.Any, _usCulture, out var value))
{
stream.SampleRate = value;
}
}
- stream.ChannelLayout = ParseChannelLayout(streamInfo.channel_layout);
+ stream.ChannelLayout = ParseChannelLayout(streamInfo.ChannelLayout);
- if (streamInfo.bits_per_sample > 0)
+ if (streamInfo.BitsPerSample > 0)
{
- stream.BitDepth = streamInfo.bits_per_sample;
+ stream.BitDepth = streamInfo.BitsPerSample;
}
- else if (streamInfo.bits_per_raw_sample > 0)
+ else if (streamInfo.BitsPerRawSample > 0)
{
- stream.BitDepth = streamInfo.bits_per_raw_sample;
+ stream.BitDepth = streamInfo.BitsPerRawSample;
}
}
- else if (string.Equals(streamInfo.codec_type, "subtitle", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(streamInfo.CodecType, "subtitle", StringComparison.OrdinalIgnoreCase))
{
stream.Type = MediaStreamType.Subtitle;
stream.Codec = NormalizeSubtitleCodec(stream.Codec);
@@ -640,14 +639,14 @@ namespace MediaBrowser.MediaEncoding.Probing
stream.localizedDefault = _localization.GetLocalizedString("Default");
stream.localizedForced = _localization.GetLocalizedString("Forced");
}
- else if (string.Equals(streamInfo.codec_type, "video", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase))
{
stream.Type = isAudio || string.Equals(stream.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase) || string.Equals(stream.Codec, "gif", StringComparison.OrdinalIgnoreCase) || string.Equals(stream.Codec, "png", StringComparison.OrdinalIgnoreCase)
? MediaStreamType.EmbeddedImage
: MediaStreamType.Video;
- stream.AverageFrameRate = GetFrameRate(streamInfo.avg_frame_rate);
- stream.RealFrameRate = GetFrameRate(streamInfo.r_frame_rate);
+ stream.AverageFrameRate = GetFrameRate(streamInfo.AverageFrameRate);
+ stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate);
if (isAudio || string.Equals(stream.Codec, "gif", StringComparison.OrdinalIgnoreCase) ||
string.Equals(stream.Codec, "png", StringComparison.OrdinalIgnoreCase))
@@ -672,17 +671,17 @@ namespace MediaBrowser.MediaEncoding.Probing
stream.Type = MediaStreamType.Video;
}
- stream.Width = streamInfo.width;
- stream.Height = streamInfo.height;
+ stream.Width = streamInfo.Width;
+ stream.Height = streamInfo.Height;
stream.AspectRatio = GetAspectRatio(streamInfo);
- if (streamInfo.bits_per_sample > 0)
+ if (streamInfo.BitsPerSample > 0)
{
- stream.BitDepth = streamInfo.bits_per_sample;
+ stream.BitDepth = streamInfo.BitsPerSample;
}
- else if (streamInfo.bits_per_raw_sample > 0)
+ else if (streamInfo.BitsPerRawSample > 0)
{
- stream.BitDepth = streamInfo.bits_per_raw_sample;
+ stream.BitDepth = streamInfo.BitsPerRawSample;
}
//stream.IsAnamorphic = string.Equals(streamInfo.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase) ||
@@ -690,11 +689,11 @@ namespace MediaBrowser.MediaEncoding.Probing
// string.Equals(stream.AspectRatio, "2.40:1", StringComparison.OrdinalIgnoreCase);
// http://stackoverflow.com/questions/17353387/how-to-detect-anamorphic-video-with-ffprobe
- stream.IsAnamorphic = string.Equals(streamInfo.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase);
+ stream.IsAnamorphic = string.Equals(streamInfo.SampleAspectRatio, "0:1", StringComparison.OrdinalIgnoreCase);
- if (streamInfo.refs > 0)
+ if (streamInfo.Refs > 0)
{
- stream.RefFrames = streamInfo.refs;
+ stream.RefFrames = streamInfo.Refs;
}
}
else
@@ -705,18 +704,18 @@ namespace MediaBrowser.MediaEncoding.Probing
// Get stream bitrate
var bitrate = 0;
- if (!string.IsNullOrEmpty(streamInfo.bit_rate))
+ if (!string.IsNullOrEmpty(streamInfo.BitRate))
{
- if (int.TryParse(streamInfo.bit_rate, NumberStyles.Any, _usCulture, out var value))
+ if (int.TryParse(streamInfo.BitRate, NumberStyles.Any, _usCulture, out var value))
{
bitrate = value;
}
}
- if (bitrate == 0 && formatInfo != null && !string.IsNullOrEmpty(formatInfo.bit_rate) && stream.Type == MediaStreamType.Video)
+ if (bitrate == 0 && formatInfo != null && !string.IsNullOrEmpty(formatInfo.BitRate) && stream.Type == MediaStreamType.Video)
{
// If the stream info doesn't have a bitrate get the value from the media format info
- if (int.TryParse(formatInfo.bit_rate, NumberStyles.Any, _usCulture, out var value))
+ if (int.TryParse(formatInfo.BitRate, NumberStyles.Any, _usCulture, out var value))
{
bitrate = value;
}
@@ -727,14 +726,18 @@ namespace MediaBrowser.MediaEncoding.Probing
stream.BitRate = bitrate;
}
- if (streamInfo.disposition != null)
+ var disposition = streamInfo.Disposition;
+ if (disposition != null)
{
- var isDefault = GetDictionaryValue(streamInfo.disposition, "default");
- var isForced = GetDictionaryValue(streamInfo.disposition, "forced");
+ if (disposition.GetValueOrDefault("default") == 1)
+ {
+ stream.IsDefault = true;
+ }
- stream.IsDefault = string.Equals(isDefault, "1", StringComparison.OrdinalIgnoreCase);
-
- stream.IsForced = string.Equals(isForced, "1", StringComparison.OrdinalIgnoreCase);
+ if (disposition.GetValueOrDefault("forced") == 1)
+ {
+ stream.IsForced = true;
+ }
}
NormalizeStreamTitle(stream);
@@ -761,7 +764,7 @@ namespace MediaBrowser.MediaEncoding.Probing
/// The tags.
/// The key.
/// System.String.
- private string GetDictionaryValue(Dictionary tags, string key)
+ private string GetDictionaryValue(IReadOnlyDictionary tags, string key)
{
if (tags == null)
{
@@ -784,7 +787,7 @@ namespace MediaBrowser.MediaEncoding.Probing
private string GetAspectRatio(MediaStreamInfo info)
{
- var original = info.display_aspect_ratio;
+ var original = info.DisplayAspectRatio;
var parts = (original ?? string.Empty).Split(':');
if (!(parts.Length == 2 &&
@@ -793,8 +796,8 @@ namespace MediaBrowser.MediaEncoding.Probing
width > 0 &&
height > 0))
{
- width = info.width;
- height = info.height;
+ width = info.Width;
+ height = info.Height;
}
if (width > 0 && height > 0)
@@ -887,20 +890,20 @@ namespace MediaBrowser.MediaEncoding.Probing
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data)
{
- if (result.streams != null)
+ if (result.Streams != null)
{
// Get the first info stream
- var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
+ var stream = result.Streams.FirstOrDefault(s => string.Equals(s.CodecType, "audio", StringComparison.OrdinalIgnoreCase));
if (stream != null)
{
// Get duration from stream properties
- var duration = stream.duration;
+ var duration = stream.Duration;
// If it's not there go into format properties
if (string.IsNullOrEmpty(duration))
{
- duration = result.format.duration;
+ duration = result.Format.Duration;
}
// If we got something, parse it
@@ -914,11 +917,11 @@ namespace MediaBrowser.MediaEncoding.Probing
private void SetSize(InternalMediaInfoResult data, MediaInfo info)
{
- if (data.format != null)
+ if (data.Format != null)
{
- if (!string.IsNullOrEmpty(data.format.size))
+ if (!string.IsNullOrEmpty(data.Format.Size))
{
- info.Size = long.Parse(data.format.size, _usCulture);
+ info.Size = long.Parse(data.Format.Size, _usCulture);
}
else
{
@@ -1231,16 +1234,16 @@ namespace MediaBrowser.MediaEncoding.Probing
{
var info = new ChapterInfo();
- if (chapter.tags != null)
+ if (chapter.Tags != null)
{
- if (chapter.tags.TryGetValue("title", out string name))
+ if (chapter.Tags.TryGetValue("title", out string name))
{
info.Name = name;
}
}
// Limit accuracy to milliseconds to match xml saving
- var secondsString = chapter.start_time;
+ var secondsString = chapter.StartTime;
if (double.TryParse(secondsString, NumberStyles.Any, CultureInfo.InvariantCulture, out var seconds))
{
@@ -1255,12 +1258,12 @@ namespace MediaBrowser.MediaEncoding.Probing
private void FetchWtvInfo(MediaInfo video, InternalMediaInfoResult data)
{
- if (data.format == null || data.format.tags == null)
+ if (data.Format == null || data.Format.Tags == null)
{
return;
}
- var genres = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/Genre");
+ var genres = FFProbeHelpers.GetDictionaryValue(data.Format.Tags, "WM/Genre");
if (!string.IsNullOrWhiteSpace(genres))
{
@@ -1276,14 +1279,14 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
- var officialRating = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/ParentalRating");
+ var officialRating = FFProbeHelpers.GetDictionaryValue(data.Format.Tags, "WM/ParentalRating");
if (!string.IsNullOrWhiteSpace(officialRating))
{
video.OfficialRating = officialRating;
}
- var people = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/MediaCredits");
+ var people = FFProbeHelpers.GetDictionaryValue(data.Format.Tags, "WM/MediaCredits");
if (!string.IsNullOrEmpty(people))
{
@@ -1293,7 +1296,7 @@ namespace MediaBrowser.MediaEncoding.Probing
.ToArray();
}
- var year = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/OriginalReleaseTime");
+ var year = FFProbeHelpers.GetDictionaryValue(data.Format.Tags, "WM/OriginalReleaseTime");
if (!string.IsNullOrWhiteSpace(year))
{
if (int.TryParse(year, NumberStyles.Integer, _usCulture, out var val))
@@ -1302,7 +1305,7 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
- var premiereDateString = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/MediaOriginalBroadcastDateTime");
+ var premiereDateString = FFProbeHelpers.GetDictionaryValue(data.Format.Tags, "WM/MediaOriginalBroadcastDateTime");
if (!string.IsNullOrWhiteSpace(premiereDateString))
{
// Credit to MCEBuddy: https://mcebuddy2x.codeplex.com/
@@ -1313,9 +1316,9 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
- var description = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/SubTitleDescription");
+ var description = FFProbeHelpers.GetDictionaryValue(data.Format.Tags, "WM/SubTitleDescription");
- var subTitle = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/SubTitle");
+ var subTitle = FFProbeHelpers.GetDictionaryValue(data.Format.Tags, "WM/SubTitle");
// For below code, credit to MCEBuddy: https://mcebuddy2x.codeplex.com/