Browse Source

more dotnet 10 updates (#2676)

* update more libraries to dotnet 10

* fix dockerfiles

* fix numeric types
pull/2678/head
Jason Dove 1 month ago committed by GitHub
parent
commit
7bd8cefe2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentAll.cs
  2. 5
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentCollection.cs
  3. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentCreatePlaylist.cs
  4. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentMarathon.cs
  5. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentMultiCollection.cs
  6. 6
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentPlaylist.cs
  7. 15
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentSearch.cs
  8. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentShow.cs
  9. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentSmartCollection.cs
  10. 0
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlGraphicsOff.cs
  11. 2
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlGraphicsOn.cs
  12. 2
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlPreRollOn.cs
  13. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlSkipItems.cs
  14. 6
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlSkipToItem.cs
  15. 2
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlStartEpgGroup.cs
  16. 2
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWaitUntil.cs
  17. 2
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWaitUntilExact.cs
  18. 0
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWatermarkOff.cs
  19. 2
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWatermarkOn.cs
  20. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PeekItemDuration.cs
  21. 4
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlaylistItem.cs
  22. 8
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutContext.cs
  23. 8
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutCount.cs
  24. 10
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutDuration.cs
  25. 10
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutPadToNext.cs
  26. 10
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutPadUntil.cs
  27. 10
      ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutPadUntilExact.cs
  28. 14
      ErsatzTV.Core.Nullable/ErsatzTV.Core.Nullable.csproj
  29. 8
      ErsatzTV.Core/Api/ScriptedPlayout/ContentSearch.cs
  30. 5
      ErsatzTV.Core/ErsatzTV.Core.csproj
  31. 4
      ErsatzTV.Scanner/ErsatzTV.Scanner.csproj
  32. 8
      ErsatzTV.sln
  33. 17
      ErsatzTV/ErsatzTV.csproj
  34. 8
      ErsatzTV/Startup.cs
  35. 361
      ErsatzTV/wwwroot/openapi/scripted-schedule-tagged.json
  36. 361
      ErsatzTV/wwwroot/openapi/scripted-schedule.json
  37. 224
      ErsatzTV/wwwroot/openapi/v1.json
  38. 2
      docker/Dockerfile
  39. 2
      docker/arm32v7/Dockerfile
  40. 2
      docker/arm64/Dockerfile
  41. 2
      docker/ffmpeg-tests/Dockerfile

6
ErsatzTV.Core/Api/ScriptedPlayout/ContentAll.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentAll.cs

@ -5,13 +5,13 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,13 +5,13 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentAll
{
[Description("The 'key' for the content that should be added")]
public string Content { get; set; }
public required string Content { get; set; }
[Description("Flags this content as filler, which influences EPG grouping")]
public string FillerKind { get; set; }
public string? FillerKind { get; set; }
[Description("Overrides the title used in the EPG")]
public string CustomTitle { get; set; }
public string? CustomTitle { get; set; }
public bool DisableWatermarks { get; set; }
}

5
ErsatzTV.Core/Api/ScriptedPlayout/ContentCollection.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentCollection.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
namespace ErsatzTV.Core.Api.ScriptedPlayout;
@ -7,10 +8,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -7,10 +8,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentCollection
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public string Key { get; init; }
public required string Key { get; init; }
[Description("The name of the existing manual collection")]
public string Collection { get; init; }
public required string Collection { get; init; }
[Description("The playback order; only chronological and shuffle are currently supported")]
public string Order { get; init; } = "shuffle";

4
ErsatzTV.Core/Api/ScriptedPlayout/ContentCreatePlaylist.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentCreatePlaylist.cs

@ -5,8 +5,8 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,8 +5,8 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentCreatePlaylist
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public string Key { get; set; }
public required string Key { get; set; }
[Description("List of playlist items")]
public List<PlaylistItem> Items { get; set; }
public required List<PlaylistItem> Items { get; set; }
}

4
ErsatzTV.Core/Api/ScriptedPlayout/ContentMarathon.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentMarathon.cs

@ -5,11 +5,11 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,11 +5,11 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentMarathon
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public string Key { get; set; }
public required string Key { get; set; }
[Description(
"Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist and album.")]
public string GroupBy { get; set; }
public required string GroupBy { get; set; }
[Description("Playback order within each group; only chronological and shuffle are currently supported")]
public string ItemOrder { get; set; } = "shuffle";

4
ErsatzTV.Core/Api/ScriptedPlayout/ContentMultiCollection.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentMultiCollection.cs

@ -7,10 +7,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -7,10 +7,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentMultiCollection
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public string Key { get; set; }
public required string Key { get; set; }
[Description("The name of the existing multi-collection")]
public string MultiCollection { get; set; }
public required string MultiCollection { get; set; }
[Description("The playback order; only chronological and shuffle are currently supported")]
public string Order { get; set; } = "shuffle";

6
ErsatzTV.Core/Api/ScriptedPlayout/ContentPlaylist.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentPlaylist.cs

@ -5,11 +5,11 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,11 +5,11 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentPlaylist
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public string Key { get; set; }
public required string Key { get; set; }
[Description("The name of the existing playlist")]
public string Playlist { get; set; }
public required string Playlist { get; set; }
[Description("The name of the existing playlist group that contains the named playlist")]
public string PlaylistGroup { get; set; }
public required string PlaylistGroup { get; set; }
}

15
ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentSearch.cs

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
using System.ComponentModel;
namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentSearch
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public required string Key { get; set; }
[Description("The search query")]
public required string Query { get; set; }
[Description("The playback order; only chronological and shuffle are currently supported")]
public string Order { get; set; } = "shuffle";
}

4
ErsatzTV.Core/Api/ScriptedPlayout/ContentShow.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentShow.cs

@ -5,10 +5,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,10 +5,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentShow
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public string Key { get; set; }
public required string Key { get; set; }
[Description("List of show identifiers")]
public Dictionary<string, string> Guids { get; set; } = [];
public required Dictionary<string, string> Guids { get; set; } = [];
[Description("The playback order; only chronological and shuffle are currently supported")]
public string Order { get; set; } = "shuffle";

4
ErsatzTV.Core/Api/ScriptedPlayout/ContentSmartCollection.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ContentSmartCollection.cs

@ -7,10 +7,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -7,10 +7,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentSmartCollection
{
[Description("Unique name used to reference this content throughout the scripted schedule")]
public string Key { get; set; }
public required string Key { get; set; }
[Description("The name of the existing smart collection")]
public string SmartCollection { get; set; }
public required string SmartCollection { get; set; }
[Description("The playback order; only chronological and shuffle are currently supported")]
public string Order { get; set; } = "shuffle";

0
ErsatzTV.Core/Api/ScriptedPlayout/ControlGraphicsOff.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlGraphicsOff.cs

2
ErsatzTV.Core/Api/ScriptedPlayout/ControlGraphicsOn.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlGraphicsOn.cs

@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ControlGraphicsOn
{
[Description("A list of graphics elements to turn on.")]
public List<string> Graphics { get; set; }
public required List<string> Graphics { get; set; }
public Dictionary<string, string> Variables { get; set; } = [];
}

2
ErsatzTV.Core/Api/ScriptedPlayout/ControlPreRollOn.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlPreRollOn.cs

@ -5,5 +5,5 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,5 +5,5 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ControlPreRollOn
{
[Description("The 'key' for the scripted playlist")]
public string Playlist { get; set; }
public required string Playlist { get; set; }
}

4
ErsatzTV.Core/Api/ScriptedPlayout/ControlSkipItems.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlSkipItems.cs

@ -5,8 +5,8 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,8 +5,8 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ControlSkipItems
{
[Description("The 'key' for the content")]
public string Content { get; set; }
public required string Content { get; set; }
[Description("The number of items to skip")]
public int Count { get; set; }
public required int Count { get; set; }
}

6
ErsatzTV.Core/Api/ScriptedPlayout/ControlSkipToItem.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlSkipToItem.cs

@ -5,11 +5,11 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,11 +5,11 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ControlSkipToItem
{
[Description("The 'key' for the content")]
public string Content { get; set; }
public required string Content { get; set; }
[Description("The season number")]
public int Season { get; set; }
public required int Season { get; set; }
[Description("The episode number")]
public int Episode { get; set; }
public required int Episode { get; set; }
}

2
ErsatzTV.Core/Api/ScriptedPlayout/ControlStartEpgGroup.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlStartEpgGroup.cs

@ -8,5 +8,5 @@ public record ControlStartEpgGroup @@ -8,5 +8,5 @@ public record ControlStartEpgGroup
public bool Advance { get; set; } = true;
[Description("Custom title to apply to all items in the EPG group.")]
public string CustomTitle { get; set; }
public string? CustomTitle { get; set; }
}

2
ErsatzTV.Core/Api/ScriptedPlayout/ControlWaitUntil.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWaitUntil.cs

@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ControlWaitUntil
{
[Description("The time of day to wait (insert unscheduled time) until")]
public string When { get; set; }
public required string When { get; set; }
[Description("When true, will wait until the specified time tomorrow if it has already passed today.")]
public bool Tomorrow { get; set; }

2
ErsatzTV.Core/Api/ScriptedPlayout/ControlWaitUntilExact.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWaitUntilExact.cs

@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ControlWaitUntilExact
{
[Description("The time to wait (insert unscheduled time) until")]
public DateTimeOffset When { get; set; }
public required DateTimeOffset When { get; set; }
[Description("When true, the current time of the playout build is allowed to move backward when the playout is reset.")]
public bool RewindOnReset { get; set; }

0
ErsatzTV.Core/Api/ScriptedPlayout/ControlWatermarkOff.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWatermarkOff.cs

2
ErsatzTV.Core/Api/ScriptedPlayout/ControlWatermarkOn.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/ControlWatermarkOn.cs

@ -5,5 +5,5 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,5 +5,5 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ControlWatermarkOn
{
[Description("A list of existing watermark names to turn on")]
public List<string> Watermark { get; set; }
public required List<string> Watermark { get; set; }
}

4
ErsatzTV.Core/Api/ScriptedPlayout/PeekItemDuration.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PeekItemDuration.cs

@ -4,8 +4,8 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -4,8 +4,8 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public class PeekItemDuration
{
public string Content { get; set; }
public required string Content { get; set; }
[Description("Duration in milliseconds")]
public long Milliseconds { get; set; }
public required long Milliseconds { get; set; }
}

4
ErsatzTV.Core/Api/ScriptedPlayout/PlaylistItem.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlaylistItem.cs

@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,7 +5,7 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PlaylistItem
{
[Description("The 'key' for the content")]
public string Content { get; set; }
public required string Content { get; set; }
public int Count { get; set; }
public required int Count { get; set; }
}

8
ErsatzTV.Core/Api/ScriptedPlayout/PlayoutContext.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutContext.cs

@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PlayoutContext
{
[Description("The current time of the playout build")]
public DateTimeOffset CurrentTime { get; set; }
public required DateTimeOffset CurrentTime { get; set; }
[Description("The start time of the playout build")]
public DateTimeOffset StartTime { get; set; }
public required DateTimeOffset StartTime { get; set; }
[Description("The finish time of the playout build")]
public DateTimeOffset FinishTime { get; set; }
public required DateTimeOffset FinishTime { get; set; }
[Description("Indicates whether the current playout build is complete")]
public bool IsDone { get; set; }
public required bool IsDone { get; set; }
}

8
ErsatzTV.Core/Api/ScriptedPlayout/PlayoutCount.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutCount.cs

@ -5,15 +5,15 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,15 +5,15 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PlayoutCount
{
[Description("The 'key' for the content that should be added")]
public string Content { get; set; }
public required string Content { get; set; }
public int Count { get; set; }
public required int Count { get; set; }
[Description("Flags this content as filler, which influences EPG grouping")]
public string FillerKind { get; set; }
public string? FillerKind { get; set; }
[Description("Overrides the title used in the EPG")]
public string CustomTitle { get; set; }
public string? CustomTitle { get; set; }
public bool DisableWatermarks { get; set; }
}

10
ErsatzTV.Core/Api/ScriptedPlayout/PlayoutDuration.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutDuration.cs

@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PlayoutDuration
{
[Description("The 'key' for the content that should be added")]
public string Content { get; set; }
public required string Content { get; set; }
[Description("The amount of time to add using the referenced content")]
public string Duration { get; set; }
public required string Duration { get; set; }
[Description(
"The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.")]
public string Fallback { get; set; }
public string? Fallback { get; set; }
[Description("Controls whether content will be trimmed to exactly fit the specified duration")]
public bool Trim { get; set; }
@ -29,10 +29,10 @@ public record PlayoutDuration @@ -29,10 +29,10 @@ public record PlayoutDuration
public bool OfflineTail { get; set; }
[Description("Flags this content as filler, which influences EPG grouping")]
public string FillerKind { get; set; }
public string? FillerKind { get; set; }
[Description("Overrides the title used in the EPG")]
public string CustomTitle { get; set; }
public string? CustomTitle { get; set; }
public bool DisableWatermarks { get; set; }
}

10
ErsatzTV.Core/Api/ScriptedPlayout/PlayoutPadToNext.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutPadToNext.cs

@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PlayoutPadToNext
{
[Description("The 'key' for the content that should be added")]
public string Content { get; set; }
public required string Content { get; set; }
[Description("The minutes interval")]
public int Minutes { get; set; }
public required int Minutes { get; set; }
[Description(
"The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.")]
public string Fallback { get; set; }
public string? Fallback { get; set; }
[Description("Controls whether content will be trimmed to exactly fit the specified interval")]
public bool Trim { get; set; }
@ -29,10 +29,10 @@ public record PlayoutPadToNext @@ -29,10 +29,10 @@ public record PlayoutPadToNext
public bool OfflineTail { get; set; } = true;
[Description("Flags this content as filler, which influences EPG grouping")]
public string FillerKind { get; set; }
public string? FillerKind { get; set; }
[Description("Overrides the title used in the EPG")]
public string CustomTitle { get; set; }
public string? CustomTitle { get; set; }
public bool DisableWatermarks { get; set; }
}

10
ErsatzTV.Core/Api/ScriptedPlayout/PlayoutPadUntil.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutPadUntil.cs

@ -5,10 +5,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,10 +5,10 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PlayoutPadUntil
{
[Description("The 'key' for the content that should be added")]
public string Content { get; set; }
public required string Content { get; set; }
[Description("The time of day that content should be added until")]
public string When { get; set; }
public required string When { get; set; }
[Description(
"Only used when the current playout time is already after the specified pad until time. When true, content will be scheduled until the specified time of day (the next day). When false, no content will be scheduled by this request.")]
@ -16,7 +16,7 @@ public record PlayoutPadUntil @@ -16,7 +16,7 @@ public record PlayoutPadUntil
[Description(
"The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.")]
public string Fallback { get; set; }
public string? Fallback { get; set; }
[Description("Controls whether content will be trimmed to exactly fit until the specified time")]
public bool Trim { get; set; }
@ -34,10 +34,10 @@ public record PlayoutPadUntil @@ -34,10 +34,10 @@ public record PlayoutPadUntil
public bool OfflineTail { get; set; }
[Description("Flags this content as filler, which influences EPG grouping")]
public string FillerKind { get; set; }
public string? FillerKind { get; set; }
[Description("Overrides the title used in the EPG")]
public string CustomTitle { get; set; }
public string? CustomTitle { get; set; }
public bool DisableWatermarks { get; set; }
}

10
ErsatzTV.Core/Api/ScriptedPlayout/PlayoutPadUntilExact.cs → ErsatzTV.Core.Nullable/Api/ScriptedPlayout/PlayoutPadUntilExact.cs

@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout; @@ -5,14 +5,14 @@ namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PlayoutPadUntilExact
{
[Description("The 'key' for the content that should be added")]
public string Content { get; set; }
public required string Content { get; set; }
[Description("The time content should be added until")]
public DateTimeOffset When { get; set; }
public required DateTimeOffset When { get; set; }
[Description(
"The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.")]
public string Fallback { get; set; }
public string? Fallback { get; set; }
[Description("Controls whether content will be trimmed to exactly fit until the specified time")]
public bool Trim { get; set; }
@ -30,10 +30,10 @@ public record PlayoutPadUntilExact @@ -30,10 +30,10 @@ public record PlayoutPadUntilExact
public bool OfflineTail { get; set; }
[Description("Flags this content as filler, which influences EPG grouping")]
public string FillerKind { get; set; }
public string? FillerKind { get; set; }
[Description("Overrides the title used in the EPG")]
public string CustomTitle { get; set; }
public string? CustomTitle { get; set; }
public bool DisableWatermarks { get; set; }
}

14
ErsatzTV.Core.Nullable/ErsatzTV.Core.Nullable.csproj

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>ErsatzTV.Core</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Folder Include="Api\" />
</ItemGroup>
</Project>

8
ErsatzTV.Core/Api/ScriptedPlayout/ContentSearch.cs

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record ContentSearch
{
public string Key { get; set; }
public string Query { get; set; }
public string Order { get; set; } = "shuffle";
}

5
ErsatzTV.Core/ErsatzTV.Core.csproj

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>disable</Nullable>
</PropertyGroup>
<ItemGroup>
@ -47,4 +48,8 @@ @@ -47,4 +48,8 @@
<ProjectReference Include="..\ErsatzTV.FFmpeg\ErsatzTV.FFmpeg.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Api\" />
</ItemGroup>
</Project>

4
ErsatzTV.Scanner/ErsatzTV.Scanner.csproj

@ -28,8 +28,8 @@ @@ -28,8 +28,8 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
<PackageReference Include="Serilog" Version="4.3.0" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />

8
ErsatzTV.sln

@ -26,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErsatzTV.Infrastructure.MyS @@ -26,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErsatzTV.Infrastructure.MyS
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErsatzTV.Infrastructure.Sqlite", "ErsatzTV.Infrastructure.Sqlite\ErsatzTV.Infrastructure.Sqlite.csproj", "{C105FD01-9D6F-4574-A987-BD39E7B349E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErsatzTV.Core.Nullable", "ErsatzTV.Core.Nullable\ErsatzTV.Core.Nullable.csproj", "{557D88A6-C982-4FFD-8FD2-6446CB07D093}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -105,6 +107,12 @@ Global @@ -105,6 +107,12 @@ Global
{C105FD01-9D6F-4574-A987-BD39E7B349E8}.Release|Any CPU.Build.0 = Release|Any CPU
{C105FD01-9D6F-4574-A987-BD39E7B349E8}.Debug No Sync|Any CPU.ActiveCfg = Debug|Any CPU
{C105FD01-9D6F-4574-A987-BD39E7B349E8}.Debug No Sync|Any CPU.Build.0 = Debug|Any CPU
{557D88A6-C982-4FFD-8FD2-6446CB07D093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{557D88A6-C982-4FFD-8FD2-6446CB07D093}.Debug|Any CPU.Build.0 = Debug|Any CPU
{557D88A6-C982-4FFD-8FD2-6446CB07D093}.Release|Any CPU.ActiveCfg = Release|Any CPU
{557D88A6-C982-4FFD-8FD2-6446CB07D093}.Release|Any CPU.Build.0 = Release|Any CPU
{557D88A6-C982-4FFD-8FD2-6446CB07D093}.Debug No Sync|Any CPU.ActiveCfg = Debug|Any CPU
{557D88A6-C982-4FFD-8FD2-6446CB07D093}.Debug No Sync|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CE7F1ACD-F286-4761-A7BC-A541A1E25C86} = {325E6DA0-52B3-4431-98A2-72C36F403704}

17
ErsatzTV/ErsatzTV.csproj

@ -39,16 +39,16 @@ @@ -39,16 +39,16 @@
<PackageReference Include="LanguageExt.Core" Version="4.4.9" />
<PackageReference Include="Markdig" Version="0.44.0" />
<PackageReference Include="MediatR.Courier.DependencyInjection" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.11">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="9.0.11">
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="10.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@ -61,8 +61,8 @@ @@ -61,8 +61,8 @@
<PackageReference Include="Refit.HttpClientFactory" Version="8.0.0" />
<PackageReference Include="Scalar.AspNetCore" Version="2.11.0" />
<PackageReference Include="Serilog" Version="4.3.0" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" />
<PackageReference Include="VueCliMiddleware" Version="6.0.0" />
</ItemGroup>
@ -72,6 +72,7 @@ @@ -72,6 +72,7 @@
<ProjectReference Include="..\ErsatzTV.Infrastructure.MySql\ErsatzTV.Infrastructure.MySql.csproj" />
<ProjectReference Include="..\ErsatzTV.Infrastructure.Sqlite\ErsatzTV.Infrastructure.Sqlite.csproj" />
<ProjectReference Include="..\ErsatzTV.Infrastructure\ErsatzTV.Infrastructure.csproj" />
<ProjectReference Include="..\ErsatzTV.Core.Nullable\ErsatzTV.Core.Nullable.csproj" />
<ProjectReference Include="..\ErsatzTV.Scanner\ErsatzTV.Scanner.csproj" />
</ItemGroup>

8
ErsatzTV/Startup.cs

@ -4,6 +4,7 @@ using System.IO.Abstractions; @@ -4,6 +4,7 @@ using System.IO.Abstractions;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Channels;
using BlazorSortable;
using Bugsnag.AspNet.Core;
@ -92,7 +93,7 @@ using Microsoft.Extensions.Primitives; @@ -92,7 +93,7 @@ using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IO;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi;
using MudBlazor.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
@ -162,10 +163,11 @@ public class Startup @@ -162,10 +163,11 @@ public class Startup
{
options.ShouldInclude += a => a.GroupName == "scripted-schedule";
var tag = new OpenApiTag { Name = "ScriptedSchedule" };
var tagReference = new OpenApiTagReference("ScriptedSchedule");
options.AddOperationTransformer((operation, _, _) =>
{
operation.Tags.Clear();
operation.Tags.Add(tag);
operation.Tags.Add(tagReference);
return Task.CompletedTask;
});
options.AddDocumentTransformer((document, _, _) =>
@ -176,6 +178,8 @@ public class Startup @@ -176,6 +178,8 @@ public class Startup
});
});
services.ConfigureHttpJsonOptions(o => o.SerializerOptions.NumberHandling = JsonNumberHandling.Strict);
OidcHelper.Init(Configuration);
JwtHelper.Init(Configuration);
SearchHelper.Init(Configuration);

361
ErsatzTV/wwwroot/openapi/scripted-schedule-tagged.json

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
{
"openapi": "3.0.1",
"openapi": "3.1.1",
"info": {
"title": "ErsatzTV | scripted-schedule-tagged",
"version": "1.0.0"
@ -1487,22 +1487,28 @@ @@ -1487,22 +1487,28 @@
"components": {
"schemas": {
"ContentAll": {
"required": [
"content"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -1510,60 +1516,64 @@ @@ -1510,60 +1516,64 @@
}
},
"ContentCollection": {
"required": [
"key",
"collection"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"collection": {
"type": "string",
"description": "The name of the existing manual collection",
"nullable": true
"description": "The name of the existing manual collection"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentCreatePlaylist": {
"required": [
"key",
"items"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PlaylistItem"
},
"description": "List of playlist items",
"nullable": true
"description": "List of playlist items"
}
}
},
"ContentMarathon": {
"required": [
"key",
"groupBy"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"groupBy": {
"type": "string",
"description": "Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist and album.",
"nullable": true
"description": "Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist and album."
},
"itemOrder": {
"type": "string",
"description": "Playback order within each group; only chronological and shuffle are currently supported",
"nullable": true
"description": "Playback order within each group; only chronological and shuffle are currently supported"
},
"guids": {
"type": "object",
@ -1573,16 +1583,14 @@ @@ -1573,16 +1583,14 @@
"type": "string"
}
},
"description": "List of external content identifiers",
"nullable": true
"description": "List of external content identifiers"
},
"searches": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of search queries",
"nullable": true
"description": "List of search queries"
},
"playAllItems": {
"type": "boolean",
@ -1595,102 +1603,111 @@ @@ -1595,102 +1603,111 @@
}
},
"ContentMultiCollection": {
"required": [
"key",
"multiCollection"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"multiCollection": {
"type": "string",
"description": "The name of the existing multi-collection",
"nullable": true
"description": "The name of the existing multi-collection"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentPlaylist": {
"required": [
"key",
"playlist",
"playlistGroup"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"playlist": {
"type": "string",
"description": "The name of the existing playlist",
"nullable": true
"description": "The name of the existing playlist"
},
"playlistGroup": {
"type": "string",
"description": "The name of the existing playlist group that contains the named playlist",
"nullable": true
"description": "The name of the existing playlist group that contains the named playlist"
}
}
},
"ContentSearch": {
"required": [
"key",
"query"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"query": {
"type": "string",
"nullable": true
"description": "The search query"
},
"order": {
"type": "string",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentShow": {
"required": [
"key",
"guids"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"guids": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "List of show identifiers",
"nullable": true
"description": "List of show identifiers"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentSmartCollection": {
"required": [
"key",
"smartCollection"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"smartCollection": {
"type": "string",
"description": "The name of the existing smart collection",
"nullable": true
"description": "The name of the existing smart collection"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
@ -1702,12 +1719,14 @@ @@ -1702,12 +1719,14 @@
"items": {
"type": "string"
},
"description": "A list of graphics elements to turn off. All graphics elements will be turned off if this list is null or empty",
"nullable": true
"description": "A list of graphics elements to turn off. All graphics elements will be turned off if this list is null or empty"
}
}
},
"ControlGraphicsOn": {
"required": [
"graphics"
],
"type": "object",
"properties": {
"graphics": {
@ -1715,35 +1734,38 @@ @@ -1715,35 +1734,38 @@
"items": {
"type": "string"
},
"description": "A list of graphics elements to turn on.",
"nullable": true
"description": "A list of graphics elements to turn on."
},
"variables": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"nullable": true
}
}
}
},
"ControlPreRollOn": {
"required": [
"playlist"
],
"type": "object",
"properties": {
"playlist": {
"type": "string",
"description": "The 'key' for the scripted playlist",
"nullable": true
"description": "The 'key' for the scripted playlist"
}
}
},
"ControlSkipItems": {
"required": [
"content",
"count"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content",
"nullable": true
"description": "The 'key' for the content"
},
"count": {
"type": "integer",
@ -1753,12 +1775,16 @@ @@ -1753,12 +1775,16 @@
}
},
"ControlSkipToItem": {
"required": [
"content",
"season",
"episode"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content",
"nullable": true
"description": "The 'key' for the content"
},
"season": {
"type": "integer",
@ -1780,19 +1806,23 @@ @@ -1780,19 +1806,23 @@
"description": "When true, will make a new EPG group. When false, will continue the existing EPG group."
},
"customTitle": {
"type": "string",
"description": "Custom title to apply to all items in the EPG group.",
"nullable": true
"type": [
"null",
"string"
],
"description": "Custom title to apply to all items in the EPG group."
}
}
},
"ControlWaitUntil": {
"required": [
"when"
],
"type": "object",
"properties": {
"when": {
"type": "string",
"description": "The time of day to wait (insert unscheduled time) until",
"nullable": true
"description": "The time of day to wait (insert unscheduled time) until"
},
"tomorrow": {
"type": "boolean",
@ -1805,6 +1835,9 @@ @@ -1805,6 +1835,9 @@
}
},
"ControlWaitUntilExact": {
"required": [
"when"
],
"type": "object",
"properties": {
"when": {
@ -1826,12 +1859,14 @@ @@ -1826,12 +1859,14 @@
"items": {
"type": "string"
},
"description": "A list of existing watermark names to turn off. All (scripted) watermarks will be turned off if this list is null or empty.",
"nullable": true
"description": "A list of existing watermark names to turn off. All (scripted) watermarks will be turned off if this list is null or empty."
}
}
},
"ControlWatermarkOn": {
"required": [
"watermark"
],
"type": "object",
"properties": {
"watermark": {
@ -1839,17 +1874,19 @@ @@ -1839,17 +1874,19 @@
"items": {
"type": "string"
},
"description": "A list of existing watermark names to turn on",
"nullable": true
"description": "A list of existing watermark names to turn on"
}
}
},
"PeekItemDuration": {
"required": [
"content",
"milliseconds"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"nullable": true
"type": "string"
},
"milliseconds": {
"type": "integer",
@ -1859,12 +1896,15 @@ @@ -1859,12 +1896,15 @@
}
},
"PlaylistItem": {
"required": [
"content",
"count"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content",
"nullable": true
"description": "The 'key' for the content"
},
"count": {
"type": "integer",
@ -1873,6 +1913,12 @@ @@ -1873,6 +1913,12 @@
}
},
"PlayoutContext": {
"required": [
"currentTime",
"startTime",
"finishTime",
"isDone"
],
"type": "object",
"properties": {
"currentTime": {
@ -1897,26 +1943,33 @@ @@ -1897,26 +1943,33 @@
}
},
"PlayoutCount": {
"required": [
"content",
"count"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"count": {
"type": "integer",
"format": "int32"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -1924,22 +1977,26 @@ @@ -1924,22 +1977,26 @@
}
},
"PlayoutDuration": {
"required": [
"content",
"duration"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"duration": {
"type": "string",
"description": "The amount of time to add using the referenced content",
"nullable": true
"description": "The amount of time to add using the referenced content"
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -1959,14 +2016,18 @@ @@ -1959,14 +2016,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified duration will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -1974,12 +2035,15 @@ @@ -1974,12 +2035,15 @@
}
},
"PlayoutPadToNext": {
"required": [
"content",
"minutes"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"minutes": {
"type": "integer",
@ -1987,9 +2051,11 @@ @@ -1987,9 +2051,11 @@
"format": "int32"
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -2009,14 +2075,18 @@ @@ -2009,14 +2075,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified interval will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -2024,26 +2094,30 @@ @@ -2024,26 +2094,30 @@
}
},
"PlayoutPadUntil": {
"required": [
"content",
"when"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"when": {
"type": "string",
"description": "The time of day that content should be added until",
"nullable": true
"description": "The time of day that content should be added until"
},
"tomorrow": {
"type": "boolean",
"description": "Only used when the current playout time is already after the specified pad until time. When true, content will be scheduled until the specified time of day (the next day). When false, no content will be scheduled by this request."
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -2063,14 +2137,18 @@ @@ -2063,14 +2137,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified interval will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -2078,12 +2156,15 @@ @@ -2078,12 +2156,15 @@
}
},
"PlayoutPadUntilExact": {
"required": [
"content",
"when"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"when": {
"type": "string",
@ -2091,9 +2172,11 @@ @@ -2091,9 +2172,11 @@
"format": "date-time"
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -2113,14 +2196,18 @@ @@ -2113,14 +2196,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified interval will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"

361
ErsatzTV/wwwroot/openapi/scripted-schedule.json

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
{
"openapi": "3.0.1",
"openapi": "3.1.1",
"info": {
"title": "ErsatzTV | scripted-schedule",
"version": "1.0.0"
@ -1487,22 +1487,28 @@ @@ -1487,22 +1487,28 @@
"components": {
"schemas": {
"ContentAll": {
"required": [
"content"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -1510,60 +1516,64 @@ @@ -1510,60 +1516,64 @@
}
},
"ContentCollection": {
"required": [
"key",
"collection"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"collection": {
"type": "string",
"description": "The name of the existing manual collection",
"nullable": true
"description": "The name of the existing manual collection"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentCreatePlaylist": {
"required": [
"key",
"items"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PlaylistItem"
},
"description": "List of playlist items",
"nullable": true
"description": "List of playlist items"
}
}
},
"ContentMarathon": {
"required": [
"key",
"groupBy"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"groupBy": {
"type": "string",
"description": "Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist and album.",
"nullable": true
"description": "Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist and album."
},
"itemOrder": {
"type": "string",
"description": "Playback order within each group; only chronological and shuffle are currently supported",
"nullable": true
"description": "Playback order within each group; only chronological and shuffle are currently supported"
},
"guids": {
"type": "object",
@ -1573,16 +1583,14 @@ @@ -1573,16 +1583,14 @@
"type": "string"
}
},
"description": "List of external content identifiers",
"nullable": true
"description": "List of external content identifiers"
},
"searches": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of search queries",
"nullable": true
"description": "List of search queries"
},
"playAllItems": {
"type": "boolean",
@ -1595,102 +1603,111 @@ @@ -1595,102 +1603,111 @@
}
},
"ContentMultiCollection": {
"required": [
"key",
"multiCollection"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"multiCollection": {
"type": "string",
"description": "The name of the existing multi-collection",
"nullable": true
"description": "The name of the existing multi-collection"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentPlaylist": {
"required": [
"key",
"playlist",
"playlistGroup"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"playlist": {
"type": "string",
"description": "The name of the existing playlist",
"nullable": true
"description": "The name of the existing playlist"
},
"playlistGroup": {
"type": "string",
"description": "The name of the existing playlist group that contains the named playlist",
"nullable": true
"description": "The name of the existing playlist group that contains the named playlist"
}
}
},
"ContentSearch": {
"required": [
"key",
"query"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"query": {
"type": "string",
"nullable": true
"description": "The search query"
},
"order": {
"type": "string",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentShow": {
"required": [
"key",
"guids"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"guids": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "List of show identifiers",
"nullable": true
"description": "List of show identifiers"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
"ContentSmartCollection": {
"required": [
"key",
"smartCollection"
],
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Unique name used to reference this content throughout the scripted schedule",
"nullable": true
"description": "Unique name used to reference this content throughout the scripted schedule"
},
"smartCollection": {
"type": "string",
"description": "The name of the existing smart collection",
"nullable": true
"description": "The name of the existing smart collection"
},
"order": {
"type": "string",
"description": "The playback order; only chronological and shuffle are currently supported",
"nullable": true
"description": "The playback order; only chronological and shuffle are currently supported"
}
}
},
@ -1702,12 +1719,14 @@ @@ -1702,12 +1719,14 @@
"items": {
"type": "string"
},
"description": "A list of graphics elements to turn off. All graphics elements will be turned off if this list is null or empty",
"nullable": true
"description": "A list of graphics elements to turn off. All graphics elements will be turned off if this list is null or empty"
}
}
},
"ControlGraphicsOn": {
"required": [
"graphics"
],
"type": "object",
"properties": {
"graphics": {
@ -1715,35 +1734,38 @@ @@ -1715,35 +1734,38 @@
"items": {
"type": "string"
},
"description": "A list of graphics elements to turn on.",
"nullable": true
"description": "A list of graphics elements to turn on."
},
"variables": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"nullable": true
}
}
}
},
"ControlPreRollOn": {
"required": [
"playlist"
],
"type": "object",
"properties": {
"playlist": {
"type": "string",
"description": "The 'key' for the scripted playlist",
"nullable": true
"description": "The 'key' for the scripted playlist"
}
}
},
"ControlSkipItems": {
"required": [
"content",
"count"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content",
"nullable": true
"description": "The 'key' for the content"
},
"count": {
"type": "integer",
@ -1753,12 +1775,16 @@ @@ -1753,12 +1775,16 @@
}
},
"ControlSkipToItem": {
"required": [
"content",
"season",
"episode"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content",
"nullable": true
"description": "The 'key' for the content"
},
"season": {
"type": "integer",
@ -1780,19 +1806,23 @@ @@ -1780,19 +1806,23 @@
"description": "When true, will make a new EPG group. When false, will continue the existing EPG group."
},
"customTitle": {
"type": "string",
"description": "Custom title to apply to all items in the EPG group.",
"nullable": true
"type": [
"null",
"string"
],
"description": "Custom title to apply to all items in the EPG group."
}
}
},
"ControlWaitUntil": {
"required": [
"when"
],
"type": "object",
"properties": {
"when": {
"type": "string",
"description": "The time of day to wait (insert unscheduled time) until",
"nullable": true
"description": "The time of day to wait (insert unscheduled time) until"
},
"tomorrow": {
"type": "boolean",
@ -1805,6 +1835,9 @@ @@ -1805,6 +1835,9 @@
}
},
"ControlWaitUntilExact": {
"required": [
"when"
],
"type": "object",
"properties": {
"when": {
@ -1826,12 +1859,14 @@ @@ -1826,12 +1859,14 @@
"items": {
"type": "string"
},
"description": "A list of existing watermark names to turn off. All (scripted) watermarks will be turned off if this list is null or empty.",
"nullable": true
"description": "A list of existing watermark names to turn off. All (scripted) watermarks will be turned off if this list is null or empty."
}
}
},
"ControlWatermarkOn": {
"required": [
"watermark"
],
"type": "object",
"properties": {
"watermark": {
@ -1839,17 +1874,19 @@ @@ -1839,17 +1874,19 @@
"items": {
"type": "string"
},
"description": "A list of existing watermark names to turn on",
"nullable": true
"description": "A list of existing watermark names to turn on"
}
}
},
"PeekItemDuration": {
"required": [
"content",
"milliseconds"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"nullable": true
"type": "string"
},
"milliseconds": {
"type": "integer",
@ -1859,12 +1896,15 @@ @@ -1859,12 +1896,15 @@
}
},
"PlaylistItem": {
"required": [
"content",
"count"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content",
"nullable": true
"description": "The 'key' for the content"
},
"count": {
"type": "integer",
@ -1873,6 +1913,12 @@ @@ -1873,6 +1913,12 @@
}
},
"PlayoutContext": {
"required": [
"currentTime",
"startTime",
"finishTime",
"isDone"
],
"type": "object",
"properties": {
"currentTime": {
@ -1897,26 +1943,33 @@ @@ -1897,26 +1943,33 @@
}
},
"PlayoutCount": {
"required": [
"content",
"count"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"count": {
"type": "integer",
"format": "int32"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -1924,22 +1977,26 @@ @@ -1924,22 +1977,26 @@
}
},
"PlayoutDuration": {
"required": [
"content",
"duration"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"duration": {
"type": "string",
"description": "The amount of time to add using the referenced content",
"nullable": true
"description": "The amount of time to add using the referenced content"
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -1959,14 +2016,18 @@ @@ -1959,14 +2016,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified duration will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -1974,12 +2035,15 @@ @@ -1974,12 +2035,15 @@
}
},
"PlayoutPadToNext": {
"required": [
"content",
"minutes"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"minutes": {
"type": "integer",
@ -1987,9 +2051,11 @@ @@ -1987,9 +2051,11 @@
"format": "int32"
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -2009,14 +2075,18 @@ @@ -2009,14 +2075,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified interval will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -2024,26 +2094,30 @@ @@ -2024,26 +2094,30 @@
}
},
"PlayoutPadUntil": {
"required": [
"content",
"when"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"when": {
"type": "string",
"description": "The time of day that content should be added until",
"nullable": true
"description": "The time of day that content should be added until"
},
"tomorrow": {
"type": "boolean",
"description": "Only used when the current playout time is already after the specified pad until time. When true, content will be scheduled until the specified time of day (the next day). When false, no content will be scheduled by this request."
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -2063,14 +2137,18 @@ @@ -2063,14 +2137,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified interval will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"
@ -2078,12 +2156,15 @@ @@ -2078,12 +2156,15 @@
}
},
"PlayoutPadUntilExact": {
"required": [
"content",
"when"
],
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
"description": "The 'key' for the content that should be added"
},
"when": {
"type": "string",
@ -2091,9 +2172,11 @@ @@ -2091,9 +2172,11 @@
"format": "date-time"
},
"fallback": {
"type": "string",
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit.",
"nullable": true
"type": [
"null",
"string"
],
"description": "The 'key' for the content that should be used to fill any remaining unscheduled time. One item will be selected to be looped and trimmed to exactly fit."
},
"trim": {
"type": "boolean",
@ -2113,14 +2196,18 @@ @@ -2113,14 +2196,18 @@
"description": "When true, afer scheduling everything that will fit, any remaining time from the specified interval will be unscheduled (offline)"
},
"fillerKind": {
"type": "string",
"description": "Flags this content as filler, which influences EPG grouping",
"nullable": true
"type": [
"null",
"string"
],
"description": "Flags this content as filler, which influences EPG grouping"
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
"type": [
"null",
"string"
],
"description": "Overrides the title used in the EPG"
},
"disableWatermarks": {
"type": "boolean"

224
ErsatzTV/wwwroot/openapi/v1.json

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
{
"openapi": "3.0.1",
"openapi": "3.1.1",
"info": {
"title": "ErsatzTV | v1",
"version": "1.0.0"
@ -605,24 +605,34 @@ @@ -605,24 +605,34 @@
"format": "int32"
},
"number": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"fFmpegProfile": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"language": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"streamingMode": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
}
}
},
@ -638,8 +648,10 @@ @@ -638,8 +648,10 @@
"format": "int32"
},
"appVersion": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
}
}
},
@ -674,8 +686,10 @@ @@ -674,8 +686,10 @@
"type": "object",
"properties": {
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"threadCount": {
"type": "integer",
@ -685,20 +699,26 @@ @@ -685,20 +699,26 @@
"$ref": "#/components/schemas/HardwareAccelerationKind"
},
"vaapiDisplay": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"vaapiDriver": {
"$ref": "#/components/schemas/VaapiDriver"
},
"vaapiDevice": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"qsvExtraHardwareFrames": {
"type": "integer",
"format": "int32",
"nullable": true
"type": [
"null",
"integer"
],
"format": "int32"
},
"resolutionId": {
"type": "integer",
@ -711,12 +731,16 @@ @@ -711,12 +731,16 @@
"$ref": "#/components/schemas/FFmpegProfileVideoFormat"
},
"videoProfile": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"videoPreset": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"allowBFrames": {
"type": "boolean"
@ -773,12 +797,16 @@ @@ -773,12 +797,16 @@
"type": "object",
"properties": {
"query": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
}
}
},
@ -818,8 +846,10 @@ @@ -818,8 +846,10 @@
"format": "int32"
},
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"threadCount": {
"type": "integer",
@ -829,24 +859,32 @@ @@ -829,24 +859,32 @@
"$ref": "#/components/schemas/HardwareAccelerationKind"
},
"vaapiDisplay": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"vaapiDriver": {
"$ref": "#/components/schemas/VaapiDriver"
},
"vaapiDevice": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"qsvExtraHardwareFrames": {
"type": "integer",
"format": "int32",
"nullable": true
"type": [
"null",
"integer"
],
"format": "int32"
},
"resolution": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"scalingBehavior": {
"$ref": "#/components/schemas/ScalingBehavior"
@ -855,12 +893,16 @@ @@ -855,12 +893,16 @@
"$ref": "#/components/schemas/FFmpegProfileVideoFormat"
},
"videoProfile": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"videoPreset": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"allowBFrames": {
"type": "boolean"
@ -905,8 +947,10 @@ @@ -905,8 +947,10 @@
"type": "boolean"
},
"deinterlaceVideo": {
"type": "boolean",
"nullable": true
"type": [
"null",
"boolean"
]
}
}
},
@ -967,12 +1011,16 @@ @@ -967,12 +1011,16 @@
"type": "object",
"properties": {
"channelNumber": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"state": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"transcodedUntil": {
"type": "string",
@ -1005,8 +1053,10 @@ @@ -1005,8 +1053,10 @@
"format": "int32"
},
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"width": {
"type": "integer",
@ -1035,8 +1085,10 @@ @@ -1035,8 +1085,10 @@
"type": "object",
"properties": {
"showTitle": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"deepScan": {
"type": "boolean",
@ -1057,12 +1109,16 @@ @@ -1057,12 +1109,16 @@
"format": "int32"
},
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"query": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
}
}
},
@ -1102,8 +1158,10 @@ @@ -1102,8 +1158,10 @@
"format": "int32"
},
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"threadCount": {
"type": "integer",
@ -1113,20 +1171,26 @@ @@ -1113,20 +1171,26 @@
"$ref": "#/components/schemas/HardwareAccelerationKind"
},
"vaapiDisplay": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"vaapiDriver": {
"$ref": "#/components/schemas/VaapiDriver"
},
"vaapiDevice": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"qsvExtraHardwareFrames": {
"type": "integer",
"format": "int32",
"nullable": true
"type": [
"null",
"integer"
],
"format": "int32"
},
"resolutionId": {
"type": "integer",
@ -1139,12 +1203,16 @@ @@ -1139,12 +1203,16 @@
"$ref": "#/components/schemas/FFmpegProfileVideoFormat"
},
"videoProfile": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"videoPreset": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"allowBFrames": {
"type": "boolean"
@ -1206,12 +1274,16 @@ @@ -1206,12 +1274,16 @@
"format": "int32"
},
"name": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"query": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
}
}
},

2
docker/Dockerfile

@ -28,6 +28,7 @@ COPY artwork/* ./artwork/ @@ -28,6 +28,7 @@ COPY artwork/* ./artwork/
COPY ErsatzTV/*.csproj ./ErsatzTV/
COPY ErsatzTV.Application/*.csproj ./ErsatzTV.Application/
COPY ErsatzTV.Core/*.csproj ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/*.csproj ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/*.csproj ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/*.csproj ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/*.csproj ./ErsatzTV.Infrastructure.Sqlite/
@ -39,6 +40,7 @@ RUN dotnet restore -r linux-x64 ErsatzTV/ @@ -39,6 +40,7 @@ RUN dotnet restore -r linux-x64 ErsatzTV/
COPY ErsatzTV/. ./ErsatzTV/
COPY ErsatzTV.Application/. ./ErsatzTV.Application/
COPY ErsatzTV.Core/. ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/. ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/. ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/. ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/. ./ErsatzTV.Infrastructure.Sqlite/

2
docker/arm32v7/Dockerfile

@ -14,6 +14,7 @@ COPY artwork/* ./artwork/ @@ -14,6 +14,7 @@ COPY artwork/* ./artwork/
COPY ErsatzTV/*.csproj ./ErsatzTV/
COPY ErsatzTV.Application/*.csproj ./ErsatzTV.Application/
COPY ErsatzTV.Core/*.csproj ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/*.csproj ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/*.csproj ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/*.csproj ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/*.csproj ./ErsatzTV.Infrastructure.Sqlite/
@ -25,6 +26,7 @@ RUN dotnet restore -r linux-arm ErsatzTV/ @@ -25,6 +26,7 @@ RUN dotnet restore -r linux-arm ErsatzTV/
COPY ErsatzTV/. ./ErsatzTV/
COPY ErsatzTV.Application/. ./ErsatzTV.Application/
COPY ErsatzTV.Core/. ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/. ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/. ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/. ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/. ./ErsatzTV.Infrastructure.Sqlite/

2
docker/arm64/Dockerfile

@ -14,6 +14,7 @@ COPY artwork/* ./artwork/ @@ -14,6 +14,7 @@ COPY artwork/* ./artwork/
COPY ErsatzTV/*.csproj ./ErsatzTV/
COPY ErsatzTV.Application/*.csproj ./ErsatzTV.Application/
COPY ErsatzTV.Core/*.csproj ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/*.csproj ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/*.csproj ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/*.csproj ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/*.csproj ./ErsatzTV.Infrastructure.Sqlite/
@ -25,6 +26,7 @@ RUN dotnet restore -r linux-arm64 ErsatzTV/ @@ -25,6 +26,7 @@ RUN dotnet restore -r linux-arm64 ErsatzTV/
COPY ErsatzTV/. ./ErsatzTV/
COPY ErsatzTV.Application/. ./ErsatzTV.Application/
COPY ErsatzTV.Core/. ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/. ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/. ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/. ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/. ./ErsatzTV.Infrastructure.Sqlite/

2
docker/ffmpeg-tests/Dockerfile

@ -13,6 +13,7 @@ COPY artwork/* ./artwork/ @@ -13,6 +13,7 @@ COPY artwork/* ./artwork/
COPY ErsatzTV/*.csproj ./ErsatzTV/
COPY ErsatzTV.Application/*.csproj ./ErsatzTV.Application/
COPY ErsatzTV.Core/*.csproj ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/*.csproj ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/*.csproj ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/*.csproj ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/*.csproj ./ErsatzTV.Infrastructure.Sqlite/
@ -25,6 +26,7 @@ RUN dotnet restore -r linux-x64 ErsatzTV/ @@ -25,6 +26,7 @@ RUN dotnet restore -r linux-x64 ErsatzTV/
COPY ErsatzTV/. ./ErsatzTV/
COPY ErsatzTV.Application/. ./ErsatzTV.Application/
COPY ErsatzTV.Core/. ./ErsatzTV.Core/
COPY ErsatzTV.Core.Nullable/. ./ErsatzTV.Core.Nullable/
COPY ErsatzTV.FFmpeg/. ./ErsatzTV.FFmpeg/
COPY ErsatzTV.Infrastructure/. ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/. ./ErsatzTV.Infrastructure.Sqlite/

Loading…
Cancel
Save