mirror of https://github.com/ErsatzTV/ErsatzTV.git
5 changed files with 267 additions and 9 deletions
@ -0,0 +1,259 @@
@@ -0,0 +1,259 @@
|
||||
// <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 |
||||
{ |
||||
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(); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue