Browse Source

add pad_until_exact and wait_until_exact scripted schedule calls (#2384)

pull/2385/head
Jason Dove 4 months ago committed by GitHub
parent
commit
31355ab887
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 39
      ErsatzTV.Core/Api/ScriptedPlayout/PadUntilExactRequestModel.cs
  2. 11
      ErsatzTV.Core/Api/ScriptedPlayout/PeekItemResponseModel.cs
  3. 12
      ErsatzTV.Core/Api/ScriptedPlayout/WaitUntilExactRequestModel.cs
  4. 17
      ErsatzTV.Core/Scheduling/Engine/ISchedulingEngine.cs
  5. 82
      ErsatzTV.Core/Scheduling/Engine/SchedulingEngine.cs
  6. 89
      ErsatzTV/Controllers/Api/ScriptedScheduleController.cs
  7. 268
      ErsatzTV/wwwroot/openapi/scripted-schedule-tagged.json
  8. 270
      ErsatzTV/wwwroot/openapi/scripted-schedule.json
  9. 2
      scripts/scripted-schedules/entrypoint.py

39
ErsatzTV.Core/Api/ScriptedPlayout/PadUntilExactRequestModel.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
using System.ComponentModel;
namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record PadUntilExactRequestModel
{
[Description("The 'key' for the content that should be added")]
public string Content { get; set; }
[Description("The time content should be added until")]
public 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; }
[Description("Controls whether content will be trimmed to exactly fit until the specified time")]
public bool Trim { get; set; }
[Description(
"When trim is false, this is the number of times to discard items from the collection to find something that fits until the specified time")]
public int DiscardAttempts { get; set; }
[Description(
"When false, allows content to run over the specified the specified time before completing this request")]
public bool StopBeforeEnd { get; set; } = true;
[Description(
"When true, afer scheduling everything that will fit, any remaining time from the specified interval will be unscheduled (offline)")]
public bool OfflineTail { get; set; }
[Description("Flags this content as filler, which influences EPG grouping")]
public string FillerKind { get; set; }
[Description("Overrides the title used in the EPG")]
public string CustomTitle { get; set; }
public bool DisableWatermarks { get; set; }
}

11
ErsatzTV.Core/Api/ScriptedPlayout/PeekItemResponseModel.cs

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
using System.ComponentModel;
namespace ErsatzTV.Core.Api.ScriptedPlayout;
public class PeekItemResponseModel
{
public string Content { get; set; }
[Description("Duration in milliseconds")]
public long Milliseconds { get; set; }
}

12
ErsatzTV.Core/Api/ScriptedPlayout/WaitUntilExactRequestModel.cs

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
using System.ComponentModel;
namespace ErsatzTV.Core.Api.ScriptedPlayout;
public record WaitUntilExactRequestModel
{
[Description("The time to wait (insert unscheduled time) until")]
public 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; }
}

17
ErsatzTV.Core/Scheduling/Engine/ISchedulingEngine.cs

@ -103,6 +103,20 @@ public interface ISchedulingEngine @@ -103,6 +103,20 @@ public interface ISchedulingEngine
string customTitle,
bool disableWatermarks);
bool PadUntilExact(
string content,
DateTimeOffset padUntil,
string fallback,
bool trim,
int discardAttempts,
bool stopBeforeEnd,
bool offlineTail,
Option<FillerKind> maybeFillerKind,
string customTitle,
bool disableWatermarks);
Option<MediaItem> PeekNext(string content);
// control instructions
void LockGuideGroup(bool advance);
void UnlockGuideGroup();
@ -118,10 +132,13 @@ public interface ISchedulingEngine @@ -118,10 +132,13 @@ public interface ISchedulingEngine
void SkipItems(string content, int count);
void SkipToItem(string content, int season, int episode);
ISchedulingEngine WaitUntil(TimeOnly waitUntil, bool tomorrow, bool rewindOnReset);
ISchedulingEngine WaitUntilExact(DateTimeOffset waitUntil, bool rewindOnReset);
PlayoutAnchor GetAnchor();
ISchedulingEngineState GetState();
TimeSpan DurationForMediaItem(MediaItem mediaItem);
}

82
ErsatzTV.Core/Scheduling/Engine/SchedulingEngine.cs

@ -586,6 +586,52 @@ public class SchedulingEngine( @@ -586,6 +586,52 @@ public class SchedulingEngine(
return true;
}
public bool PadUntilExact(
string content,
DateTimeOffset padUntil,
string fallback,
bool trim,
int discardAttempts,
bool stopBeforeEnd,
bool offlineTail,
Option<FillerKind> maybeFillerKind,
string customTitle,
bool disableWatermarks)
{
if (!_enumerators.TryGetValue(content, out EnumeratorDetails enumeratorDetails))
{
logger.LogWarning("Skipping invalid content {Key}", content);
return false;
}
EnumeratorDetails fallbackEnumeratorDetails = null;
if (!string.IsNullOrEmpty(fallback))
{
_enumerators.TryGetValue(fallback, out fallbackEnumeratorDetails);
}
DateTimeOffset targetTime = _state.CurrentTime;
if (targetTime < padUntil)
{
// this is wrong when offset changes?
targetTime = padUntil.ToLocalTime();
}
_state.CurrentTime = AddDurationInternal(
targetTime,
stopBeforeEnd,
discardAttempts,
trim,
offlineTail,
GetFillerKind(maybeFillerKind),
customTitle,
disableWatermarks,
enumeratorDetails,
Optional(fallbackEnumeratorDetails));
return true;
}
private DateTimeOffset AddDurationInternal(
DateTimeOffset targetTime,
bool stopBeforeEnd,
@ -844,6 +890,17 @@ public class SchedulingEngine( @@ -844,6 +890,17 @@ public class SchedulingEngine(
return result;
}
public Option<MediaItem> PeekNext(string content)
{
if (!_enumerators.TryGetValue(content, out EnumeratorDetails enumeratorDetails))
{
logger.LogWarning("Unable to peek next item for invalid content {Key}", content);
return Option<MediaItem>.None;
}
return enumeratorDetails.Enumerator.Current;
}
public void LockGuideGroup(bool advance)
{
_state.LockGuideGroup(advance);
@ -1006,6 +1063,29 @@ public class SchedulingEngine( @@ -1006,6 +1063,29 @@ public class SchedulingEngine(
return this;
}
public ISchedulingEngine WaitUntilExact(DateTimeOffset waitUntil, bool rewindOnReset)
{
var currentTime = _state.CurrentTime;
if (currentTime > waitUntil)
{
if (rewindOnReset && _state.Mode == PlayoutBuildMode.Reset)
{
// maybe wrong when offset changes?
currentTime = waitUntil.ToLocalTime();
}
}
else
{
// this is wrong when offset changes?
currentTime = waitUntil.ToLocalTime();
}
_state.CurrentTime = currentTime;
return this;
}
public PlayoutAnchor GetAnchor()
{
DateTime maxTime = _state.CurrentTime.UtcDateTime;
@ -1199,7 +1279,7 @@ public class SchedulingEngine( @@ -1199,7 +1279,7 @@ public class SchedulingEngine(
}
}
private static TimeSpan DurationForMediaItem(MediaItem mediaItem)
public TimeSpan DurationForMediaItem(MediaItem mediaItem)
{
if (mediaItem is Image image)
{

89
ErsatzTV/Controllers/Api/ScriptedScheduleController.cs

@ -123,10 +123,10 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP @@ -123,10 +123,10 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP
return Ok();
}
[HttpPost("add_search", Name = "AddSearchQuery")]
[HttpPost("add_search", Name = "AddSearch")]
[Tags("Scripted Content")]
[EndpointSummary("Add a search query")]
public async Task<IActionResult> AddSearchQuery(
public async Task<IActionResult> AddSearch(
[FromRoute]
Guid buildId,
[FromBody]
@ -319,7 +319,7 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP @@ -319,7 +319,7 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP
[HttpPost("pad_until", Name = "PadUntil")]
[Tags("Scripted Scheduling")]
[EndpointSummary("Add content until a specified time")]
[EndpointSummary("Add content until a specified time of day")]
public ActionResult<ContextResponseModel> PadUntil(
[FromRoute] Guid buildId,
[FromBody] PadUntilRequestModel request)
@ -351,6 +351,65 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP @@ -351,6 +351,65 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP
return GetContextInternal(engine);
}
[HttpPost("pad_until_exact", Name = "PadUntilExact")]
[Tags("Scripted Scheduling")]
[EndpointSummary("Add content until an exact time")]
public ActionResult<ContextResponseModel> PadUntilExact(
[FromRoute]
Guid buildId,
[FromBody]
PadUntilExactRequestModel request)
{
ISchedulingEngine engine = scriptedPlayoutBuilderService.GetEngine(buildId);
if (engine == null)
{
return NotFound($"Active build engine not found for build {buildId}.");
}
Option<FillerKind> maybeFillerKind = Option<FillerKind>.None;
if (Enum.TryParse(request.FillerKind, ignoreCase: true, out FillerKind fk))
{
maybeFillerKind = fk;
}
engine.PadUntilExact(
request.Content,
request.When,
request.Fallback,
request.Trim,
request.DiscardAttempts,
request.StopBeforeEnd,
request.OfflineTail,
maybeFillerKind,
request.CustomTitle,
request.DisableWatermarks);
return GetContextInternal(engine);
}
[HttpGet("peek_next/{content}", Name="PeekNext")]
[Tags("Scripted Scheduling")]
[EndpointSummary("Peek the next content item")]
public ActionResult<PeekItemResponseModel> PeekNext(Guid buildId, string content)
{
ISchedulingEngine engine = scriptedPlayoutBuilderService.GetEngine(buildId);
if (engine == null)
{
return NotFound($"Active build engine not found for build {buildId}.");
}
Option<MediaItem> maybeMediaItem = engine.PeekNext(content);
foreach (var mediaItem in maybeMediaItem)
{
return new PeekItemResponseModel
{
Content = content,
Milliseconds = (long)engine.DurationForMediaItem(mediaItem).TotalMilliseconds
};
}
return NotFound("Content key does not exist, or collection is empty");
}
[HttpPost("start_epg_group", Name = "StartEpgGroup")]
[Tags("Scripted Control")]
[EndpointSummary("Start an EPG group")]
@ -481,10 +540,30 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP @@ -481,10 +540,30 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP
return Ok();
}
[HttpPost("wait_until_exact", Name = "WaitUntilExact")]
[Tags("Scripted Control")]
[EndpointSummary("Wait until an exact time")]
public ActionResult<ContextResponseModel> WaitUntilExact(
[FromRoute]
Guid buildId,
[FromBody]
WaitUntilExactRequestModel request)
{
ISchedulingEngine engine = scriptedPlayoutBuilderService.GetEngine(buildId);
if (engine == null)
{
return NotFound($"Active build engine not found for build {buildId}.");
}
engine.WaitUntilExact(request.When, request.RewindOnReset);
return GetContextInternal(engine);
}
[HttpPost("wait_until", Name = "WaitUntil")]
[Tags("Scripted Control")]
[EndpointSummary("Wait until the specified time")]
public ActionResult<ContextResponseModel> WaitUntil(
[EndpointSummary("Wait until the specified time of day")]
public ActionResult<ContextResponseModel> WaitUntilTime(
[FromRoute]
Guid buildId,
[FromBody]

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

@ -253,7 +253,7 @@ @@ -253,7 +253,7 @@
"Scripted Content"
],
"summary": "Add a search query",
"operationId": "AddSearchQuery",
"operationId": "AddSearch",
"parameters": [
{
"name": "buildId",
@ -670,7 +670,7 @@ @@ -670,7 +670,7 @@
"tags": [
"Scripted Scheduling"
],
"summary": "Add content until a specified time",
"summary": "Add content until a specified time of day",
"operationId": "PadUntil",
"parameters": [
{
@ -732,6 +732,123 @@ @@ -732,6 +732,123 @@
}
}
},
"/api/scripted/playout/build/{buildId}/pad_until_exact": {
"post": {
"tags": [
"Scripted Scheduling"
],
"summary": "Add content until an exact time",
"operationId": "PadUntilExact",
"parameters": [
{
"name": "buildId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
}
}
}
}
}
},
"/api/scripted/playout/build/{buildId}/peek_next/{content}": {
"get": {
"tags": [
"Scripted Scheduling"
],
"summary": "Peek the next content item",
"operationId": "PeekNext",
"parameters": [
{
"name": "buildId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "content",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PeekItemResponseModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/PeekItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PeekItemResponseModel"
}
}
}
}
}
}
},
"/api/scripted/playout/build/{buildId}/start_epg_group": {
"post": {
"tags": [
@ -1107,12 +1224,79 @@ @@ -1107,12 +1224,79 @@
}
}
},
"/api/scripted/playout/build/{buildId}/wait_until_exact": {
"post": {
"tags": [
"Scripted Control"
],
"summary": "Wait until an exact time",
"operationId": "WaitUntilExact",
"parameters": [
{
"name": "buildId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
}
}
}
}
}
},
"/api/scripted/playout/build/{buildId}/wait_until": {
"post": {
"tags": [
"Scripted Control"
],
"summary": "Wait until the specified time",
"summary": "Wait until the specified time of day",
"operationId": "WaitUntil",
"parameters": [
{
@ -1551,6 +1735,56 @@ @@ -1551,6 +1735,56 @@
}
}
},
"PadUntilExactRequestModel": {
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
},
"when": {
"type": "string",
"description": "The time content should be added until",
"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
},
"trim": {
"type": "boolean",
"description": "Controls whether content will be trimmed to exactly fit until the specified time"
},
"discardAttempts": {
"type": "integer",
"description": "When trim is false, this is the number of times to discard items from the collection to find something that fits until the specified time",
"format": "int32"
},
"stopBeforeEnd": {
"type": "boolean",
"description": "When false, allows content to run over the specified the specified time before completing this request"
},
"offlineTail": {
"type": "boolean",
"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
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
},
"disableWatermarks": {
"type": "boolean"
}
}
},
"PadUntilRequestModel": {
"type": "object",
"properties": {
@ -1605,6 +1839,20 @@ @@ -1605,6 +1839,20 @@
}
}
},
"PeekItemResponseModel": {
"type": "object",
"properties": {
"content": {
"type": "string",
"nullable": true
},
"milliseconds": {
"type": "integer",
"description": "Duration in milliseconds",
"format": "int64"
}
}
},
"SkipItemsRequestModel": {
"type": "object",
"properties": {
@ -1649,6 +1897,20 @@ @@ -1649,6 +1897,20 @@
}
}
},
"WaitUntilExactRequestModel": {
"type": "object",
"properties": {
"when": {
"type": "string",
"description": "The time to wait (insert unscheduled time) until",
"format": "date-time"
},
"rewindOnReset": {
"type": "boolean",
"description": "When true, the current time of the playout build is allowed to move backward when the playout is reset."
}
}
},
"WaitUntilRequestModel": {
"type": "object",
"properties": {

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

@ -253,7 +253,7 @@ @@ -253,7 +253,7 @@
"ScriptedSchedule"
],
"summary": "Add a search query",
"operationId": "AddSearchQuery",
"operationId": "AddSearch",
"parameters": [
{
"name": "buildId",
@ -670,7 +670,7 @@ @@ -670,7 +670,7 @@
"tags": [
"ScriptedSchedule"
],
"summary": "Add content until a specified time",
"summary": "Add content until a specified time of day",
"operationId": "PadUntil",
"parameters": [
{
@ -732,6 +732,123 @@ @@ -732,6 +732,123 @@
}
}
},
"/api/scripted/playout/build/{buildId}/pad_until_exact": {
"post": {
"tags": [
"ScriptedSchedule"
],
"summary": "Add content until an exact time",
"operationId": "PadUntilExact",
"parameters": [
{
"name": "buildId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/PadUntilExactRequestModel"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
}
}
}
}
}
},
"/api/scripted/playout/build/{buildId}/peek_next/{content}": {
"get": {
"tags": [
"ScriptedSchedule"
],
"summary": "Peek the next content item",
"operationId": "PeekNext",
"parameters": [
{
"name": "buildId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "content",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PeekItemResponseModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/PeekItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PeekItemResponseModel"
}
}
}
}
}
}
},
"/api/scripted/playout/build/{buildId}/start_epg_group": {
"post": {
"tags": [
@ -1107,12 +1224,79 @@ @@ -1107,12 +1224,79 @@
}
}
},
"/api/scripted/playout/build/{buildId}/wait_until_exact": {
"post": {
"tags": [
"ScriptedSchedule"
],
"summary": "Wait until an exact time",
"operationId": "WaitUntilExact",
"parameters": [
{
"name": "buildId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/WaitUntilExactRequestModel"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ContextResponseModel"
}
}
}
}
}
}
},
"/api/scripted/playout/build/{buildId}/wait_until": {
"post": {
"tags": [
"ScriptedSchedule"
],
"summary": "Wait until the specified time",
"summary": "Wait until the specified time of day",
"operationId": "WaitUntil",
"parameters": [
{
@ -1551,6 +1735,56 @@ @@ -1551,6 +1735,56 @@
}
}
},
"PadUntilExactRequestModel": {
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The 'key' for the content that should be added",
"nullable": true
},
"when": {
"type": "string",
"description": "The time content should be added until",
"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
},
"trim": {
"type": "boolean",
"description": "Controls whether content will be trimmed to exactly fit until the specified time"
},
"discardAttempts": {
"type": "integer",
"description": "When trim is false, this is the number of times to discard items from the collection to find something that fits until the specified time",
"format": "int32"
},
"stopBeforeEnd": {
"type": "boolean",
"description": "When false, allows content to run over the specified the specified time before completing this request"
},
"offlineTail": {
"type": "boolean",
"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
},
"customTitle": {
"type": "string",
"description": "Overrides the title used in the EPG",
"nullable": true
},
"disableWatermarks": {
"type": "boolean"
}
}
},
"PadUntilRequestModel": {
"type": "object",
"properties": {
@ -1605,6 +1839,20 @@ @@ -1605,6 +1839,20 @@
}
}
},
"PeekItemResponseModel": {
"type": "object",
"properties": {
"content": {
"type": "string",
"nullable": true
},
"milliseconds": {
"type": "integer",
"description": "Duration in milliseconds",
"format": "int64"
}
}
},
"SkipItemsRequestModel": {
"type": "object",
"properties": {
@ -1649,6 +1897,20 @@ @@ -1649,6 +1897,20 @@
}
}
},
"WaitUntilExactRequestModel": {
"type": "object",
"properties": {
"when": {
"type": "string",
"description": "The time to wait (insert unscheduled time) until",
"format": "date-time"
},
"rewindOnReset": {
"type": "boolean",
"description": "When true, the current time of the playout build is allowed to move backward when the playout is reset."
}
}
},
"WaitUntilRequestModel": {
"type": "object",
"properties": {
@ -1700,4 +1962,4 @@ @@ -1700,4 +1962,4 @@
"name": "ScriptedSchedule"
}
]
}
}

2
scripts/scripted-schedules/entrypoint.py

@ -39,7 +39,7 @@ def main(): @@ -39,7 +39,7 @@ def main():
define_content(api_instance, context, known_args.build_id)
if known_args.mode == "reset":
reset_playout(api_instance, context, known_args.build_id)
context = reset_playout(api_instance, context, known_args.build_id)
build_playout(api_instance, context, known_args.build_id)
except etv_client.ApiException as e:

Loading…
Cancel
Save