mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
8.1 KiB
260 lines
8.1 KiB
// <auto-generated /> |
|
// |
|
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: |
|
// |
|
// using ErsatzTV.Core.Next; |
|
// |
|
// var playout = Playout.FromJson(jsonString); |
|
|
|
namespace ErsatzTV.Core.Next |
|
{ |
|
using System; |
|
using System.Collections.Generic; |
|
|
|
using System.Globalization; |
|
using Newtonsoft.Json; |
|
using Newtonsoft.Json.Converters; |
|
|
|
/// <summary> |
|
/// A playout schedule for a single time window. |
|
/// |
|
/// Files should be named `{start}_{finish}.json` using compact ISO 8601 |
|
/// (no separators), e.g. |
|
/// `20260413T000000.000000000-0500_20260414T002131.620000000-0500.json`, |
|
/// so that the channel can locate the correct file for the current time. |
|
/// </summary> |
|
public partial class Playout |
|
{ |
|
[JsonProperty("items")] |
|
public List<ItemElement> Items { get; set; } |
|
|
|
/// <summary> |
|
/// URI identifying the schema version, e.g. "https://ersatztv.org/playout/version/0.0.1" |
|
/// </summary> |
|
[JsonProperty("version")] |
|
public string Version { get; set; } |
|
} |
|
|
|
public partial class ItemElement |
|
{ |
|
/// <summary> |
|
/// RFC3339 formatted date/time, e.g. 2026-04-13T00:24:21.527-05:00 |
|
/// </summary> |
|
[JsonProperty("finish")] |
|
public string Finish { get; set; } |
|
|
|
[JsonProperty("id")] |
|
public string Id { get; set; } |
|
|
|
[JsonProperty("source")] |
|
public ItemSource Source { get; set; } |
|
|
|
/// <summary> |
|
/// RFC3339 formatted date/time, e.g. 2026-04-13T00:24:21.527-05:00 |
|
/// </summary> |
|
[JsonProperty("start")] |
|
public string Start { get; set; } |
|
|
|
[JsonProperty("tracks")] |
|
public TracksClass Tracks { get; set; } |
|
} |
|
|
|
public partial class ItemSource |
|
{ |
|
[JsonProperty("in_point_ms")] |
|
public long? InPointMs { get; set; } |
|
|
|
[JsonProperty("out_point_ms")] |
|
public long? OutPointMs { get; set; } |
|
|
|
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)] |
|
public string Path { get; set; } |
|
|
|
[JsonProperty("source_type")] |
|
public SourceType SourceType { get; set; } |
|
|
|
[JsonProperty("params", NullValueHandling = NullValueHandling.Ignore)] |
|
public string Params { get; set; } |
|
|
|
/// <summary> |
|
/// Custom HTTP headers, e.g. ["Authorization: Bearer {{TOKEN}}"] |
|
/// </summary> |
|
[JsonProperty("headers")] |
|
public List<string> Headers { get; set; } |
|
|
|
/// <summary> |
|
/// Enable reconnect on failure (default: true) |
|
/// </summary> |
|
[JsonProperty("reconnect")] |
|
public bool? Reconnect { get; set; } |
|
|
|
/// <summary> |
|
/// Max reconnect delay in seconds |
|
/// </summary> |
|
[JsonProperty("reconnect_delay_max")] |
|
public long? ReconnectDelayMax { get; set; } |
|
|
|
/// <summary> |
|
/// Socket timeout in microseconds |
|
/// </summary> |
|
[JsonProperty("timeout_us")] |
|
public long? TimeoutUs { get; set; } |
|
|
|
/// <summary> |
|
/// URI template, e.g. "https://example.com/file.mkv?token={{MY_SECRET}}" |
|
/// </summary> |
|
[JsonProperty("uri", NullValueHandling = NullValueHandling.Ignore)] |
|
public string Uri { get; set; } |
|
|
|
/// <summary> |
|
/// Custom user-agent string |
|
/// </summary> |
|
[JsonProperty("user_agent")] |
|
public string UserAgent { get; set; } |
|
} |
|
|
|
public partial class TracksClass |
|
{ |
|
[JsonProperty("audio")] |
|
public AudioClass Audio { get; set; } |
|
|
|
[JsonProperty("video")] |
|
public AudioClass Video { get; set; } |
|
} |
|
|
|
public partial class AudioClass |
|
{ |
|
[JsonProperty("source", NullValueHandling = NullValueHandling.Ignore)] |
|
public AudioSource Source { get; set; } |
|
|
|
[JsonProperty("stream_index", NullValueHandling = NullValueHandling.Ignore)] |
|
public long? StreamIndex { get; set; } |
|
} |
|
|
|
public partial class AudioSource |
|
{ |
|
[JsonProperty("in_point_ms")] |
|
public long? InPointMs { get; set; } |
|
|
|
[JsonProperty("out_point_ms")] |
|
public long? OutPointMs { get; set; } |
|
|
|
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)] |
|
public string Path { get; set; } |
|
|
|
[JsonProperty("source_type")] |
|
public SourceType SourceType { get; set; } |
|
|
|
[JsonProperty("params", NullValueHandling = NullValueHandling.Ignore)] |
|
public string Params { get; set; } |
|
|
|
/// <summary> |
|
/// Custom HTTP headers, e.g. ["Authorization: Bearer {{TOKEN}}"] |
|
/// </summary> |
|
[JsonProperty("headers")] |
|
public List<string> Headers { get; set; } |
|
|
|
/// <summary> |
|
/// Enable reconnect on failure (default: true) |
|
/// </summary> |
|
[JsonProperty("reconnect")] |
|
public bool? Reconnect { get; set; } |
|
|
|
/// <summary> |
|
/// Max reconnect delay in seconds |
|
/// </summary> |
|
[JsonProperty("reconnect_delay_max")] |
|
public long? ReconnectDelayMax { get; set; } |
|
|
|
/// <summary> |
|
/// Socket timeout in microseconds |
|
/// </summary> |
|
[JsonProperty("timeout_us")] |
|
public long? TimeoutUs { get; set; } |
|
|
|
/// <summary> |
|
/// URI template, e.g. "https://example.com/file.mkv?token={{MY_SECRET}}" |
|
/// </summary> |
|
[JsonProperty("uri", NullValueHandling = NullValueHandling.Ignore)] |
|
public string Uri { get; set; } |
|
|
|
/// <summary> |
|
/// Custom user-agent string |
|
/// </summary> |
|
[JsonProperty("user_agent")] |
|
public string UserAgent { get; set; } |
|
} |
|
|
|
public enum SourceType { Http, Lavfi, Local }; |
|
|
|
public partial class Playout |
|
{ |
|
public static Playout FromJson(string json) => JsonConvert.DeserializeObject<Playout>(json, ErsatzTV.Core.Next.Converter.Settings); |
|
} |
|
|
|
public static class Serialize |
|
{ |
|
public static string ToJson(this Playout self) => JsonConvert.SerializeObject(self, ErsatzTV.Core.Next.Converter.Settings); |
|
} |
|
|
|
internal static class Converter |
|
{ |
|
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings |
|
{ |
|
NullValueHandling = NullValueHandling.Ignore, |
|
MetadataPropertyHandling = MetadataPropertyHandling.Ignore, |
|
DateParseHandling = DateParseHandling.None, |
|
Converters = |
|
{ |
|
SourceTypeConverter.Singleton, |
|
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } |
|
}, |
|
}; |
|
} |
|
|
|
internal class SourceTypeConverter : JsonConverter |
|
{ |
|
public override bool CanConvert(Type t) => t == typeof(SourceType) || t == typeof(SourceType?); |
|
|
|
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) |
|
{ |
|
if (reader.TokenType == JsonToken.Null) return null; |
|
var value = serializer.Deserialize<string>(reader); |
|
switch (value) |
|
{ |
|
case "http": |
|
return SourceType.Http; |
|
case "lavfi": |
|
return SourceType.Lavfi; |
|
case "local": |
|
return SourceType.Local; |
|
} |
|
throw new Exception("Cannot unmarshal type SourceType"); |
|
} |
|
|
|
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) |
|
{ |
|
if (untypedValue == null) |
|
{ |
|
serializer.Serialize(writer, null); |
|
return; |
|
} |
|
var value = (SourceType)untypedValue; |
|
switch (value) |
|
{ |
|
case SourceType.Http: |
|
serializer.Serialize(writer, "http"); |
|
return; |
|
case SourceType.Lavfi: |
|
serializer.Serialize(writer, "lavfi"); |
|
return; |
|
case SourceType.Local: |
|
serializer.Serialize(writer, "local"); |
|
return; |
|
} |
|
throw new Exception("Cannot marshal type SourceType"); |
|
} |
|
|
|
public static readonly SourceTypeConverter Singleton = new SourceTypeConverter(); |
|
} |
|
}
|
|
|