//
//
// To parse this JSON data, add NuGet 'System.Text.Json' then do:
//
// using ErsatzTV.Core.Next.Config;
//
// var channelConfig = ChannelConfig.FromJson(jsonString);
#nullable enable
#pragma warning disable CS8618
#pragma warning disable CS8601
#pragma warning disable CS8602
#pragma warning disable CS8603
namespace ErsatzTV.Core.Next.Config
{
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Globalization;
public partial class ChannelConfig
{
[JsonPropertyName("ffmpeg")]
public Ffmpeg Ffmpeg { get; set; }
[JsonPropertyName("normalization")]
public Normalization Normalization { get; set; }
[JsonPropertyName("playout")]
public Playout Playout { get; set; }
}
public partial class Ffmpeg
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("disabled_filters")]
public List? DisabledFilters { get; set; }
[JsonPropertyName("ffmpeg_path")]
public string? FfmpegPath { get; set; }
[JsonPropertyName("ffprobe_path")]
public string? FfprobePath { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("preferred_filters")]
public List? PreferredFilters { get; set; }
[JsonPropertyName("reports_folder")]
public string? ReportsFolder { get; set; }
}
public partial class Normalization
{
[JsonPropertyName("audio")]
public Audio Audio { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("subtitle")]
public Subtitle? Subtitle { get; set; }
[JsonPropertyName("video")]
public Video Video { get; set; }
}
public partial class Audio
{
[JsonPropertyName("bitrate_kbps")]
public long? BitrateKbps { get; set; }
[JsonPropertyName("buffer_kbps")]
public long? BufferKbps { get; set; }
[JsonPropertyName("channels")]
public long? Channels { get; set; }
[JsonPropertyName("format")]
public AudioFormat? Format { get; set; }
[JsonPropertyName("loudness")]
public LoudnessClass? Loudness { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("normalize_loudness")]
public bool? NormalizeLoudness { get; set; }
[JsonPropertyName("sample_rate_hz")]
public long? SampleRateHz { get; set; }
}
public partial class LoudnessClass
{
[JsonPropertyName("integrated_target")]
public double? IntegratedTarget { get; set; }
[JsonPropertyName("range_target")]
public double? RangeTarget { get; set; }
[JsonPropertyName("true_peak")]
public double? TruePeak { get; set; }
}
public partial class Subtitle
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("mode")]
public Mode? Mode { get; set; }
}
public partial class Video
{
[JsonPropertyName("accel")]
public AccelEnum? Accel { get; set; }
[JsonPropertyName("bit_depth")]
public long? BitDepth { get; set; }
[JsonPropertyName("bitrate_kbps")]
public long? BitrateKbps { get; set; }
[JsonPropertyName("buffer_kbps")]
public long? BufferKbps { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("deinterlace")]
public bool? Deinterlace { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("filters")]
public Filters? Filters { get; set; }
[JsonPropertyName("format")]
public VideoFormat? Format { get; set; }
[JsonPropertyName("height")]
public long? Height { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("scaling_mode")]
public ScalingMode? ScalingMode { get; set; }
[JsonPropertyName("vaapi_device")]
public string? VaapiDevice { get; set; }
[JsonPropertyName("vaapi_driver")]
public VaapiDriverEnum? VaapiDriver { get; set; }
[JsonPropertyName("width")]
public long? Width { get; set; }
}
public partial class Filters
{
[JsonPropertyName("bwdif")]
public BwdifClass? Bwdif { get; set; }
[JsonPropertyName("bwdif_cuda")]
public BwdifCudaClass? BwdifCuda { get; set; }
[JsonPropertyName("deinterlace_qsv")]
public DeinterlaceQsvClass? DeinterlaceQsv { get; set; }
[JsonPropertyName("deinterlace_vaapi")]
public DeinterlaceVaapiClass? DeinterlaceVaapi { get; set; }
[JsonPropertyName("libplacebo")]
public LibplaceboClass? Libplacebo { get; set; }
[JsonPropertyName("tonemap")]
public TonemapClass? Tonemap { get; set; }
[JsonPropertyName("tonemap_opencl")]
public TonemapOpenclClass? TonemapOpencl { get; set; }
[JsonPropertyName("w3fdif")]
public W3FdifClass? W3Fdif { get; set; }
[JsonPropertyName("yadif")]
public YadifClass? Yadif { get; set; }
[JsonPropertyName("yadif_cuda")]
public YadifCudaClass? YadifCuda { get; set; }
}
public partial class BwdifClass
{
[JsonPropertyName("mode")]
public string? Mode { get; set; }
}
public partial class BwdifCudaClass
{
[JsonPropertyName("mode")]
public string? Mode { get; set; }
}
public partial class DeinterlaceQsvClass
{
[JsonPropertyName("mode")]
public string? Mode { get; set; }
}
public partial class DeinterlaceVaapiClass
{
[JsonPropertyName("mode")]
public string? Mode { get; set; }
}
public partial class LibplaceboClass
{
[JsonPropertyName("tonemapping")]
public string? Tonemapping { get; set; }
}
public partial class TonemapClass
{
[JsonPropertyName("tonemap")]
public string? Tonemap { get; set; }
}
public partial class TonemapOpenclClass
{
[JsonPropertyName("tonemap")]
public string? Tonemap { get; set; }
}
public partial class W3FdifClass
{
[JsonPropertyName("mode")]
public string? Mode { get; set; }
}
public partial class YadifClass
{
[JsonPropertyName("mode")]
public string? Mode { get; set; }
}
public partial class YadifCudaClass
{
[JsonPropertyName("mode")]
public string? Mode { get; set; }
}
public partial class Playout
{
[JsonPropertyName("folder")]
public string Folder { get; set; }
///
/// RFC3339 formatted date/time, e.g. 2026-04-13T00:24:21.527-05:00
///
[JsonPropertyName("virtual_start")]
public string? VirtualStart { get; set; }
}
public enum AudioFormat { Aac, Ac3 };
public enum Mode { Burn, Convert };
public enum AccelEnum { Amf, Cuda, Qsv, Rkmpp, Vaapi, Videotoolbox, Vulkan };
public enum VideoFormat { H264, Hevc };
public enum ScalingMode { Crop, ScaleAndPad, Stretch };
public enum VaapiDriverEnum { I965, Ihd, Radeonsi };
public partial class ChannelConfig
{
public static ChannelConfig FromJson(string json) => JsonSerializer.Deserialize(json, ErsatzTV.Core.Next.Config.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this ChannelConfig self) => JsonSerializer.Serialize(self, ErsatzTV.Core.Next.Config.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters =
{
AudioFormatConverter.Singleton,
ModeConverter.Singleton,
AccelEnumConverter.Singleton,
VideoFormatConverter.Singleton,
ScalingModeConverter.Singleton,
VaapiDriverEnumConverter.Singleton,
new DateOnlyConverter(),
new TimeOnlyConverter(),
IsoDateTimeOffsetConverter.Singleton
},
};
}
internal class AudioFormatConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(AudioFormat);
public override AudioFormat Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
switch (value)
{
case "aac":
return AudioFormat.Aac;
case "ac3":
return AudioFormat.Ac3;
}
throw new Exception("Cannot unmarshal type AudioFormat");
}
public override void Write(Utf8JsonWriter writer, AudioFormat value, JsonSerializerOptions options)
{
switch (value)
{
case AudioFormat.Aac:
JsonSerializer.Serialize(writer, "aac", options);
return;
case AudioFormat.Ac3:
JsonSerializer.Serialize(writer, "ac3", options);
return;
}
throw new Exception("Cannot marshal type AudioFormat");
}
public static readonly AudioFormatConverter Singleton = new AudioFormatConverter();
}
internal class ModeConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(Mode);
public override Mode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
switch (value)
{
case "burn":
return Mode.Burn;
case "convert":
return Mode.Convert;
}
throw new Exception("Cannot unmarshal type Mode");
}
public override void Write(Utf8JsonWriter writer, Mode value, JsonSerializerOptions options)
{
switch (value)
{
case Mode.Burn:
JsonSerializer.Serialize(writer, "burn", options);
return;
case Mode.Convert:
JsonSerializer.Serialize(writer, "convert", options);
return;
}
throw new Exception("Cannot marshal type Mode");
}
public static readonly ModeConverter Singleton = new ModeConverter();
}
internal class AccelEnumConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(AccelEnum);
public override AccelEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
switch (value)
{
case "amf":
return AccelEnum.Amf;
case "cuda":
return AccelEnum.Cuda;
case "qsv":
return AccelEnum.Qsv;
case "rkmpp":
return AccelEnum.Rkmpp;
case "vaapi":
return AccelEnum.Vaapi;
case "videotoolbox":
return AccelEnum.Videotoolbox;
case "vulkan":
return AccelEnum.Vulkan;
}
throw new Exception("Cannot unmarshal type AccelEnum");
}
public override void Write(Utf8JsonWriter writer, AccelEnum value, JsonSerializerOptions options)
{
switch (value)
{
case AccelEnum.Amf:
JsonSerializer.Serialize(writer, "amf", options);
return;
case AccelEnum.Cuda:
JsonSerializer.Serialize(writer, "cuda", options);
return;
case AccelEnum.Qsv:
JsonSerializer.Serialize(writer, "qsv", options);
return;
case AccelEnum.Rkmpp:
JsonSerializer.Serialize(writer, "rkmpp", options);
return;
case AccelEnum.Vaapi:
JsonSerializer.Serialize(writer, "vaapi", options);
return;
case AccelEnum.Videotoolbox:
JsonSerializer.Serialize(writer, "videotoolbox", options);
return;
case AccelEnum.Vulkan:
JsonSerializer.Serialize(writer, "vulkan", options);
return;
}
throw new Exception("Cannot marshal type AccelEnum");
}
public static readonly AccelEnumConverter Singleton = new AccelEnumConverter();
}
internal class VideoFormatConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(VideoFormat);
public override VideoFormat Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
switch (value)
{
case "h264":
return VideoFormat.H264;
case "hevc":
return VideoFormat.Hevc;
}
throw new Exception("Cannot unmarshal type VideoFormat");
}
public override void Write(Utf8JsonWriter writer, VideoFormat value, JsonSerializerOptions options)
{
switch (value)
{
case VideoFormat.H264:
JsonSerializer.Serialize(writer, "h264", options);
return;
case VideoFormat.Hevc:
JsonSerializer.Serialize(writer, "hevc", options);
return;
}
throw new Exception("Cannot marshal type VideoFormat");
}
public static readonly VideoFormatConverter Singleton = new VideoFormatConverter();
}
internal class ScalingModeConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ScalingMode);
public override ScalingMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
switch (value)
{
case "crop":
return ScalingMode.Crop;
case "scale_and_pad":
return ScalingMode.ScaleAndPad;
case "stretch":
return ScalingMode.Stretch;
}
throw new Exception("Cannot unmarshal type ScalingMode");
}
public override void Write(Utf8JsonWriter writer, ScalingMode value, JsonSerializerOptions options)
{
switch (value)
{
case ScalingMode.Crop:
JsonSerializer.Serialize(writer, "crop", options);
return;
case ScalingMode.ScaleAndPad:
JsonSerializer.Serialize(writer, "scale_and_pad", options);
return;
case ScalingMode.Stretch:
JsonSerializer.Serialize(writer, "stretch", options);
return;
}
throw new Exception("Cannot marshal type ScalingMode");
}
public static readonly ScalingModeConverter Singleton = new ScalingModeConverter();
}
internal class VaapiDriverEnumConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(VaapiDriverEnum);
public override VaapiDriverEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
switch (value)
{
case "i965":
return VaapiDriverEnum.I965;
case "ihd":
return VaapiDriverEnum.Ihd;
case "radeonsi":
return VaapiDriverEnum.Radeonsi;
}
throw new Exception("Cannot unmarshal type VaapiDriverEnum");
}
public override void Write(Utf8JsonWriter writer, VaapiDriverEnum value, JsonSerializerOptions options)
{
switch (value)
{
case VaapiDriverEnum.I965:
JsonSerializer.Serialize(writer, "i965", options);
return;
case VaapiDriverEnum.Ihd:
JsonSerializer.Serialize(writer, "ihd", options);
return;
case VaapiDriverEnum.Radeonsi:
JsonSerializer.Serialize(writer, "radeonsi", options);
return;
}
throw new Exception("Cannot marshal type VaapiDriverEnum");
}
public static readonly VaapiDriverEnumConverter Singleton = new VaapiDriverEnumConverter();
}
public class DateOnlyConverter : JsonConverter
{
private readonly string serializationFormat;
public DateOnlyConverter() : this(null) { }
public DateOnlyConverter(string? serializationFormat)
{
this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
}
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
return DateOnly.Parse(value!);
}
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString(serializationFormat));
}
public class TimeOnlyConverter : JsonConverter
{
private readonly string serializationFormat;
public TimeOnlyConverter() : this(null) { }
public TimeOnlyConverter(string? serializationFormat)
{
this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
}
public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
return TimeOnly.Parse(value!);
}
public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString(serializationFormat));
}
internal class IsoDateTimeOffsetConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);
private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
private string? _dateTimeFormat;
private CultureInfo? _culture;
public DateTimeStyles DateTimeStyles
{
get => _dateTimeStyles;
set => _dateTimeStyles = value;
}
public string? DateTimeFormat
{
get => _dateTimeFormat ?? string.Empty;
set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
}
public CultureInfo Culture
{
get => _culture ?? CultureInfo.CurrentCulture;
set => _culture = value;
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
string text;
if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
{
value = value.ToUniversalTime();
}
text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
writer.WriteStringValue(text);
}
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string? dateText = reader.GetString();
if (string.IsNullOrEmpty(dateText) == false)
{
if (!string.IsNullOrEmpty(_dateTimeFormat))
{
return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
}
else
{
return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
}
}
else
{
return default(DateTimeOffset);
}
}
public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
}
}
#pragma warning restore CS8618
#pragma warning restore CS8601
#pragma warning restore CS8602
#pragma warning restore CS8603