User Guide
Channels
Channel creation
In general, the Virtual Channel workflow starts with the creation of a channel
using the PUT /channels/{channel}
endpoint. Two things are needed to
generate such a request:
you must choose a channel name and use it to form the URL you will
PUT
to (i.e. create arock_concert
event by PUTting to http://localhost:8000/channels/rock_concert)an appropriate SMIL playlist must be provided as an
application/xml
request body (see SMIL creation for instructions on SMIL creation).
The name you have chosen for your channel will reflect in the playout URL: i.e.
for the previous example's rock_concert
name, the playout URL will be
available at http://localhost/rock_concert.isml.
Note
As opposed to a classic Origin setup, an http://localhost/rock_concert.isml playout URL does not mean that the name of the corresponding server manifest file on disk is rock_concert.isml. Instead, on channel creation, a UUID is computed based on the full content of the SMIL playlist; that UUID is used as the server manifest's filename.
The creation of a live channel can be a long-running operation. For this reason, it's important to understand that its actual creation is performed by a job that Virtual Channel schedules for background execution after returning from the PUT operation.
In other words, a PUT operation does not create a new channel immediately and does not guarantee that the channel will be effectively created without errors. Instead, a variable amount of time (depending by various factors, such as playlist complexity and network speed) is required before the channel creation jobs terminates.
In order to understand if your channel is live, you have to check your channel creation status.
Note
Once a certain playlist has been used to create a channel for the first time, the job duration for any further channels that uses the exact same playlist will be almost instantaneous. In fact, all channels using the exact same SMIL playlist will completely reuse the related isml server manifest as well as media segments.
Checking channel creation job status
As a user, you can monitor at any time the status of your channel by using the
GET /channels/{channel}/status
endpoint. The possible statuses are:
Pending: your channel is scheduled to be created soon. At this time, no modifications to the channel are allowed.
In Progress: a job to create your channel is still running. Additional details are provided by the status endpoint. At this time, no modifications to the channel are allowed.
Success: the job was successful and your channel is live and accessible at the relative playout URL.
Failed: the channel was not created because of an error. In this case, refer to the API endpoints allowing you to retrieve the task's logs, which include details on the outcome of the
remix
andmp4split
commands.
When your channel has reached the Success status, it will be available for
playout at the corresponding origin_url
provided by the status endpoint.
If the status is Pending or In Progress, just wait until the system has finished the job execution.
If the status is Failed, it means something went wrong at playlist processing time and you should check the remix or mp4split logs using the dedicated endpoints.
Amending/modifying channels
If the channel's status is either "Success" or "Failure", performing another
PUT
operation (usually with a modified SMIL playlist) will overwrite the
existing channel.
Note
➡️ this is not the endpoint allowing channel "transitions"! This is mostly
dedicated to "overwrite and forget" channels that have been created with a
certain playlist but have not yet started playing. In fact, attempting a
PUT
on a channel that has started playout already will just fail.
Listing and deleting channels
You can get a list of the existing channels with the /channel
endpoint.
To remove a channel, perform a DELETE
operation. This will be allowed only
if the channel creation job is in either one of the Success or Failed
statuses.
Warning
the DELETE
operation does not perform any check and will successfully
delete also channels that are playing already.
Transitions
Once you have created at least one channel, you can proceed to add transitions.
Transitions allow you to seamlessly update a running virtual channel to switch to either a new VOD2Live playlist or an external live source. When transitioning to a VOD2Live playlist it is possible to start the playlist at the beginning, or to switch in to an already running playlist.
These options give you the flexibility to run your channel exactly as required.
For a visual example of how the output of Virtual Channel maps to the sources, whether VOD2Live playlists or live, see the following diagrams.
This shows a Virtual Channel which starts with a VOD2Live playlist A, switches to a live source X for a set duration, then switches to a new VOD2Live playlist B.
This shows a Virtual Channel which starts with a VOD2Live playlist A, switches to a live source X for a set duration, then switches back to the same VOD2Live playlist A. In this example the time block for the live source in playlist A should include some filler content to ensure that the switch back to VOD2Live works as expected.
Transition creation
It is possible to "transition" an existing channel from its current playlist to
another at a given date/time by means of the dedicated endpoint PUT
/channels/{channel}/transitions/{transition}
. The operation is similar to what
is required to create a channel and it requires two things:
knowing the name of the channel you want to "transition" and the time you want the transition to happen. This information is used to form the URL to
PUT
to (i.e. to transition therock_concert
event to another playlist at2022-07-18T20:00:00Z
, you shouldPUT
to http://localhost:8000/channels/rock_concert/2022-07-18T20:00:00Z)an appropriate SMIL playlist, provided as an
application/xml
request body, describing what the channel should transition to. (the same SMIL instructions SMIL creation apply).
Warning
always use transition times expressed in UTC, using one of the two allowed
time formats 2022-04-14T06:00:00Z
or 2022-04-14T06:00:00.000Z
As it happens for channels, creating a transition may be a long-running operation and as such is executed in the background. For this reason, you should always check the transition creation status after using this endpoint.
Note
Once a certain playlist has been used to create a transition for the first time, the job duration for any further transition that uses the exact same playlist will be almost instantaneous. In fact, all transitions using the exact same SMIL playlist will completely reuse the related isml server manifest as well as media segments.
The transition creation endpoint will error out immediately if certain conditions are failed. Those are:
Transitions will be refused if the provided transition time is earlier than the vod2live_start_time specified in the SMIL playlist. Allowing such transitions would essentially mean allowing switching to a presentation that hasn't yet started. This would generate a gap in the presentation and for this reason it is always considered an error.
Transitions will be refused if their transition time is in the past. Allowing such transitions would effectively break all players that have already started playing back the channel.
If you understand the consequences and know what you are doing, you can force the API to skip the above checks by appending a ?force query parameter to the API endpoint.
Checking transition creation job status
As a user, you can monitor at any time the status of your transition creation
job by using the GET /channels/{channel}/transitions/{transition}/status
endpoint. The possible statuses are:
Pending: your transition is scheduled to be created soon. At this time, no modifications to the channel or the transition are allowed.
In Progress: a job to create your transition is still running. Additional details are provided by the status endpoint. At this time, no modifications to the transition are allowed.
Success: the job was successful and your transition is active. At the scheduled time the channel will switch to the provided playlist.
Failed: the transition was not created because of an error. In this case, refer to the API endpoints allowing you to retrieve the task's logs, which include details on the outcome of the
remix
andmp4split
commands. No modifications have been done to the channel.
If the status is Pending or In Progress, just wait until the system has finished the job execution.
If the status is Failed, it means something went wrong at playlist processing time and you should check the remix or mp4split logs using the dedicated endpoints.
If the remix and mp4split steps were successful but took a long time to complete, the job can fail as well. In fact, once a working isml has been produced, Virtual Channel checks if the scheduled transition time has passed. If it has, the job is considered aborted. Allowing such transitions would effectively break all players that have already started playing back the channel.
Warning
If the transition was created using the ?force parameter (see previous section), the above check will be skipped.
Amending/modifying transitions
If the transition's status is either "Success" or "Failure", performing another PUT operation (usually with a modified SMIL playlist) will overwrite the existing transition.
Warning
this endpoint is dedicated to modify/overwrite transitions that have been scheduled but are not active yet (i.e. their transition time is in the future ). If the transition is active (i.e. transition time is in the past), the endpoint will fail and will not perform any modifications to the channel. If you want to modify the playlist that is currently playing in the channel, the right thing to do is just to create another transition at some point in the future.
Listing and deleting transitions
You can get a list of the existing transitions on a given channels with the
/channels/{channel}/transitions
endpoint. This will return a dictionary
where, for each transition ever submitted, details on the job status and the
related smil will be provided.
If you wish to only retrieve those transitions whose job was successful (and
thus actually affecting your channel), you can filter the results via query
parameter, i.e. /channels/{channel}/transitions?status=Success
. Similarly,
you may filter for unsuccessful transition jobs using the filter
/channels/{channel}/transitions?status=Failed
.
Time-based queries are supported for this endpoint. If you need to retrieve the
list of transitions of a given channel, in a specific time range, you can do so
by using the begin
and end
query parameters, e.g.
GET /channels/{channel}/transitions?begin=2022-10-21T07:03:41Z&end=2022-10-22T07:03:41Z
As usual, an UTC time in ISO-8601 format is required.
To remove a transition, perform a DELETE
operation. This will be allowed
only if the transition creation job is in either one of the Success or
Failed statuses.
Warning
the DELETE
operation does not perform any check and will successfully
delete also active transitions (i.e. with transition time in the past). In
this
case, any device/player that is actively reproducing content related to the
playlist being deleted will stop playback and hang. Hoewer, the underlying
channel will still be operational and will just "revert" to the content of the
base channel or of any transition prior to the one that was deleted.
Note
remember that automatic deletion of old, unused transitions is enabled in Virtual Channel (see Automatic transition deletion) and as such, after a certain time (default is 7 days), transitions may be automatically deleted.
SMIL creation
SMIL playlists are the primary way in Virtual Channel to:
specify the content of a channel/transition (generally accomplished in the
<body>
section)pass options to remix/mp4split at channel/transition creation time (generally accomplished in the
<head>
section)
At this purpose, two kinds of SMIL playlists exists:
VOD2Live SMIL playlist: this is the kind of playlist you may be already familiar with if you have already used Unified Remix-VOD2Live. It allows you to define content by stitching together existing VOD assets and timed metadata, as well as to pass options to Remix/mp4split at channel/transition creation time.
LIVE SMIL playlist: much simpler, it does not allow any stitching per se, but is used to add existing, external Origin Live sources to a Virtual Channel.
Each one will be addressed in detail in the following sections.
VOD2Live SMIL
For a VOD2Live playlist, an <head>
section with two mandatory options, vod2live
and vod2live_start_time
is
required.
Additional Origin output configuration options can also be set in the
<head>
. To check how they should be formatted you can use mp4split to
generate an example .isml like so: mp4split -o stdout:.isml
--hls.client_manifest_version=5
.
Here is an example: VOD2Live Smil:
<?xml version='1.0' encoding='UTF-8'?>
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
<head>
<meta name="vod2live" content="true" />
<meta name="vod2live_start_time" content="2022-04-14T06:00:00Z" />
<meta name="hls_client_manifest_version" content="5" />
<meta name="hls_minimum_fragment_length" content="48/25" />
<meta name="mpd_minimum_fragment_length" content="48/25" />
<meta name="mpd_segment_template" content="time" />
<meta name="timed_metadata" content="true" />
<meta name="splice_media" content="true" />
</head>
<body>
<seq>
<par clipEnd="wallclock(1970-01-01T00:00:44.160Z)">
<audio src="https://usp-vod2live.s3.amazonaws.com/Promo_Learning-aac-128k.mp4"/>
<video src="https://usp-vod2live.s3.amazonaws.com/Promo_Learning-avc1-400k.mp4"/>
<video src="https://usp-vod2live.s3.amazonaws.com/Promo_Learning-avc1-750k.mp4"/>
<video src="https://usp-vod2live.s3.amazonaws.com/Promo_Learning-avc1-1000k.mp4"/>
<video src="https://usp-vod2live.s3.amazonaws.com/Promo_Learning-avc1-1500k.mp4"/>
</par>
</seq>
</body>
</smil>
Warning
You can use the provided example for your tests, because it is based on media stored on a publicly accessible s3 bucket. As such though, it will only work if you have not set any S3 authentication environmental variables.
You can set a desired channel start time by respecting the ISO-8601 datetime
format and expressing time as UTC. Make sure to keep the value of vod2live to
true
.
You can find additional examples of valid SMIL playlists in Virtual Channel's repository , in the example folder.
SCTE 35 for ad insertion
Due to the flexibility of both SCTE 35 and DASH EventStreams there are many options for scheduling SCTE 35 events to enable ad insertion in Virtual Channel, but the most straightforward and recommended method is to schedule separate cue out and cue in events on the first element of the break and the return to main content respectively.
Scheduling these events without a duration on the DASH Event in the SMIL playlist will trigger Virtual Channel to calculate the actual duration and ensure everything is signalled appropriately in the output.
An example showing this with two sets of SCTE 35 events for two breaks with spliceEventId 1001 and 1002:
<?xml version='1.0' encoding='UTF-8'?>
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
<!--
Example playlist with SCTE 35 cues to signal ad breaks
-->
<head>
<meta name="vod2live" content="true"/>
<meta name="vod2live_start_time" content="2023-01-01T00:00:00Z"/>
<meta name="hls_client_manifest_version" content="5"/>
<meta name="dvr_window_length" content="600"/>
<meta name="timed_metadata" content="true"/>
<meta name="splice_media" content="true"/>
</head>
<body>
<seq>
<par>
<!-- Start of ad break CUE OUT - SCTE 35 event ID 1001 -->
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-400k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-750k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-1000k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-1500k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-2200k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-aac-128k.mp4"/>
<EventStream xmlns="urn:mpeg:dash:schema:mpd:2011" schemeIdUri="urn:scte:scte35:2014:xml+bin">
<Event id="1">
<Signal xmlns="http://www.scte.org/schemas/35/2016">
<SpliceInfoSection>
<SpliceInsert spliceEventId="1001" outOfNetworkIndicator="1" spliceImmediateFlag="1">
<Program/>
</SpliceInsert>
</SpliceInfoSection>
</Signal>
</Event>
</EventStream>
</par>
<par>
<video src="http://s3.internal.unified-streaming.com/vod2live/Toothpaste_Glitch_v2-avc1-400k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Toothpaste_Glitch_v2-avc1-750k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Toothpaste_Glitch_v2-avc1-1000k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Toothpaste_Glitch_v2-avc1-1500k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Toothpaste_Glitch_v2-avc1-2200k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Toothpaste_Glitch_v2-aac-128k.mp4"/>
</par>
<par clipEnd="wallclock(1970-01-01T00:01:00Z)" >
<!-- End of ad break CUE IN - SCTE 35 event ID 1001 -->
<video src="http://s3.internal.unified-streaming.com/vod2live/What_is_SCTE35_Jamie-avc1-400k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/What_is_SCTE35_Jamie-avc1-750k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/What_is_SCTE35_Jamie-avc1-1000k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/What_is_SCTE35_Jamie-avc1-1500k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/What_is_SCTE35_Jamie-avc1-2200k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/What_is_SCTE35_Jamie-aac-128k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/What_is_SCTE35_Jamie.ismt"/>
<EventStream xmlns="urn:mpeg:dash:schema:mpd:2011" schemeIdUri="urn:scte:scte35:2014:xml+bin">
<Event id="2">
<Signal xmlns="http://www.scte.org/schemas/35/2016">
<SpliceInfoSection>
<SpliceInsert spliceEventId="1001" outOfNetworkIndicator="0" spliceImmediateFlag="1">
<Program/>
</SpliceInsert>
</SpliceInfoSection>
</Signal>
</Event>
</EventStream>
</par>
<par>
<!-- Start of ad break CUE OUT - SCTE 35 event ID 1002 -->
<video src="http://s3.internal.unified-streaming.com/vod2live/Cycle_Unified_v2-avc1-400k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Cycle_Unified_v2-avc1-750k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Cycle_Unified_v2-avc1-1000k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Cycle_Unified_v2-avc1-1500k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Cycle_Unified_v2-avc1-2200k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Cycle_Unified_v2-aac-128k.mp4"/>
<EventStream xmlns="urn:mpeg:dash:schema:mpd:2011" schemeIdUri="urn:scte:scte35:2014:xml+bin">
<Event id="3">
<Signal xmlns="http://www.scte.org/schemas/35/2016">
<SpliceInfoSection>
<SpliceInsert spliceEventId="1002" outOfNetworkIndicator="1" spliceImmediateFlag="1">
<Program/>
</SpliceInsert>
</SpliceInfoSection>
</Signal>
</Event>
</EventStream>
</par>
<par>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-400k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-750k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-1000k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-1500k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-avc1-2200k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/Unified_Astronaut_A_v2-aac-128k.mp4"/>
</par>
<par clipEnd="wallclock(1970-01-01T00:01:00Z)">
<!-- End of ad break CUE IN - SCTE 35 event ID 1002 -->
<video src="http://s3.internal.unified-streaming.com/vod2live/ManifestEdit_Lightboard_V4_Linzi-avc1-400k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/ManifestEdit_Lightboard_V4_Linzi-avc1-750k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/ManifestEdit_Lightboard_V4_Linzi-avc1-1000k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/ManifestEdit_Lightboard_V4_Linzi-avc1-1500k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/ManifestEdit_Lightboard_V4_Linzi-avc1-2200k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/ManifestEdit_Lightboard_V4_Linzi-aac-128k.mp4"/>
<video src="http://s3.internal.unified-streaming.com/vod2live/ManifestEdit_Lightboard_V4_Linzi.ismt"/>
<EventStream xmlns="urn:mpeg:dash:schema:mpd:2011" schemeIdUri="urn:scte:scte35:2014:xml+bin">
<Event id="4">
<Signal xmlns="http://www.scte.org/schemas/35/2016">
<SpliceInfoSection>
<SpliceInsert spliceEventId="1002" outOfNetworkIndicator="0" spliceImmediateFlag="1">
<Program/>
</SpliceInsert>
</SpliceInfoSection>
</Signal>
</Event>
</EventStream>
</par>
</seq>
</body>
</smil>
Live SMIL
For a Live playlist, an empty <body>
and a <head>
section with two
mandatory options, live_source
and dvr_window_length
, are required.
In HLS ad insertion use cases it's also important to set two additional options
to ensure that media segmentation and segment duration is signalled correctly.
These options are hls_minimum_fragment_length
and splice_media
, they
should be set to the same values used in the source live stream.
Here is an example: Live Smil
<?xml version='1.0' encoding='UTF-8'?>
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
<head>
<meta name="live_source" content="https://demo.unified-streaming.com/k8s/vc-perm-live-source/trunk/colourbars/colourbars.isml" />
<meta name="dvr_window_length" content="30" />
<meta name="hls_minimum_fragment_length" content="48/25" />
<meta name="splice_media" content="true" />
</head>
<body/>
</smil>
Notice that live_source
must refer to an existing Live Origin instance and
that dvr_window_length
is expressed in seconds.
A live SMIL must only refer to one existing live source, i.e. it is not possible to "stitch" multiple live sources together in a single playlist. For this purpose, you will have to use multiple Live playlists and use transitions.
Handling live source latency
VOD2Live outputs from Origin use the server wallclock time to determine the "live edge", which can cause players to buffer or stall when transitioning to a live source which has some delay due to contribution and encoding adding latency.
To counteract this live stream latency there is an option to delay all of the VOD2Live outputs for a channel.
This is configured on a per-channel basis as different channels might use live sources with different latency.
Find your live stream latency
You can use the /archive or /statistics endpoints on your live stream to check approximately how much latency there is on the stream itself. We do not need to check any latency added downstream of the Origin by CDN or player, as that does not impact the Virtual Channel transitioning process.
For example, checking the latency of one of our test live streams:
#!/bin/bash
curl --silent https://demo.unified-streaming.com/k8s/vc-perm-live-source/trunk/colourbars/colourbars.isml/archive | grep -E "content|end"
Which should look something like:
content="2022-11-22T16:37:13.335659Z">
<c start="2022-11-22T14:00:00Z" end="2022-11-22T16:37:03.360000Z" />
<c start="2022-11-22T14:00:00Z" end="2022-11-22T16:37:03.360000Z" />
<c start="2022-11-22T14:00:00Z" end="2022-11-22T16:37:03.360000Z" />
<c start="2022-11-22T14:00:00Z" end="2022-11-22T16:37:03.360000Z" />
<c start="2022-11-22T14:00:00Z" end="2022-11-22T16:37:03.360000Z" />
This shows the request was made at 16:37:13, and the live edge of all the media streams is 16:37:03, so there is approximately 10 seconds encoding latency.
Set a VOD2Live delay
Using the API you can configure a delay to be applied to all VOD2Live outputs
for the channel. Do this by simplying PUTting the integer number of seconds to
delay to the /channels/{channel_name}/delay
endpoint.
For example:
#!/bin/bash
curl -X PUT -d 10 http://localhost:8000/channels/test_channel/delay
The API will respond with the set delay:
{"delay":10}
You can also use GET and DELETE verbs on the same endpoint to get or unset the delay for a channel respectively.
Content matching
HLS does not allow ABR ladders, tracks and encoding profiles to change at all mid-stream, and while DASH technically allows it in practice it doesn't work reliably.
This means it is important for all content being used for a Virtual Channel to match as closely as possible.
Normal encoder variations or intentional per-title encoding can cause your VOD content to vary in ways that make it hard to match.
However, because of the way Virtual Channel processes VOD playlists with Unified Remix it is possible to specify a desired output profile and pick the best fitting tracks from each source media.
Remix will use a set of heuristics to find the best possible fit for each track given the source media. For the best output it is best for the tracks to be fairly similar, for example, matching a single 30MBit 4K video track to other content using a full ABR ladder is unlikely to give the desired client experience.
By default, matching will be done using the first entry in any given SMIL playlist as the target profile, but best practice is to separately define a desired target profile and have every playlist processed to match it.
If you are using live sources, the best way to do this is to Capture a short clip from the live stream and use that as the target profile.
Otherwise, encode a short clip with the desired profile and use it as a reference.
Setting a target profile
Set the outputDescription
meta element in the head of the SMIL playlist to
a URL pointing to an ISOBMFF file of the desired target profile.
For example:
<?xml version='1.0' encoding='UTF-8'?>
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
<head>
<meta name="outputDescription"
content="https://usp-vod2live.s3.amazonaws.com/Promo_Learning-ad-dref.mp4" />
...
</head>
<body>
...
</body>
</smil>
Limitations
At the moment, the limitations mentioned for VOD2Live in the chapter Limitations, Scaling, Caching and DRM also apply to Virtual Channel's VOD2Live playlists.
If one or more of your VOD2Live playlist contain SCTE35 events and you are using transitions, you will have to manually take care of avoiding scheduling a transition at a time when a SCTE35 opportunity is programmed. In other words, if after a "CUE-OUT" event a transition happens, the corresponding "CUE-IN" event will be lost and this can lead to unexpected behaviour downstream.
DRM protection
The use of DRM similar as to how it is described in DRM protection and VOD2Live.
Manifest Edit pipelines
Virtual Channel integrates Manifest Edit functionalities. It is suggested that you read the chapter Manifest Edit if you are not familiar with it, where you can find a general description as well as detailed instructions on how to write your own pipeline configuration files, with examples.
Briefly, Manifest Edit allows you to create customized versions of DASH and HLS manifests, by applying editing pipelines that combine one or more plugins from its Plugins Library.
Users define editing pipelines by means of yaml pipeline configuration files. The same pipeline configuration files used for the Origin can be used, with no changes, with Virtual Channel.
Virtual Channel's API includes specific endpoints to associate a pipeline configuration file (and thus a Manifest Edit use case) to a channel's manifest URI.
The simplest possibility is to associate a pipeline to the "default" channel's
manifest URI (e.g. [...]/channel.isml/.mpd
for DASH or
[...]/channel.isml/.m3u8
for HLS). In this case, the channel's manifest will
always be modified by the Use Case specified by the pipeline.
A more flexible alternative is to associate a pipeline to a channel's "variant"
manifest URI. This works as a sort of "alias" that allows you to maintain
separate URIs for the "original" unedited manifest and the edited one. An
example of such "variant" may be to associate an mpd_use_case
to the URI
[...]/channel.isml/.mpd?python_pipeline_config=mpd_use_case
. This URI will
return a manifest modified by the mpd_use_case
Manifest Edit pipeline, while
the base URI [...]/channel.isml/.mpd
would still return the original
manifest.
This will be clarified further in the next sections.
Adding a pipeline to the base channel
You can associate a Manifest Edit use case to the base channel via the
PUT /channels/{channel}/pipelines/{format}
endpoint. Make sure that:
{channel}
is the name of the channel you want to associate a pipeline to.{format}
specifies one of the supported formats (i.e. mpd, m3u8_main or m3u8_media).the request body is a valid yaml configuration file
the
Content-Type
html header is set to one of the supported values (i.e. "text/yaml", "text/x-yaml" or "application/x-yaml")
Normally, {channel}
would refer to an existing channel. Using a non-existing
channel name is possible though. The operation would be successful but will have
no effect. If and when the referred channel will be created, the pipeline will
be associated with it.
This endpoints performs pipeline validation by checking that:
the yaml is syntactically valid
the format specified in the pipeline is coherent with the
{format}
string specified in the endpoint path (e.g. PUTting an m3u8 pipeline to an mpd endpoint would result in an error)plugins mentioned in the pipeline are valid
each plugin has a correct related configuration section
415 or 422 are returned in case one or more of the above checks are not passed. On success, the endpoint returns 200 OK and the playout URI of the channel.
Notice that the PUT operation does not perform any check on previously existing pipelines for the same channel and will silently overwrite any existing ones.
Adding a pipeline to a channel "variant"
If you want to keep the chance to access both the original and an edited version of your channel's manifest, then you should use a channel variant.
Channel variants are also the right choice in case you need even more flexibility and be able to have access to several different versions of edited manifests at the same time through as many variants.
Associating a Manifest Edit use case to a channel variant with
the PUT /channels/{channel}/pipelines/{format}/variants/{variant}
endpoint. Make sure that:
{channel}
is the name of the channel you want to associate a pipeline to.{format}
specifies one of the supported formats (i.e. mpd, m3u8_main or m3u8_media).the request body is a valid yaml configuration file
the
Content-Type
html header is set to one of the supported values (i.e. "text/yaml", "text/x-yaml" or "application/x-yaml"){variant}
is a variant name of your choice. It will directly affect the playout URI, which is obtained by adding the query parameterpython_pipeline_config={variant}
to the base channel playout URI.
The same set of checks will be performed by this endpoint than in the case of a pipeline associated to the base channel.
You can create as many variants as needed. Notice that the PUT operation does not perform any check on previously existing pipelines for the same variant and will silently overwrite any existing ones.
Keeping track of pipelines and variants
You can retrieve at any time the pipeline configuration files associated to a given base channel or variant, for any specific format, through the endpoints
GET /channels/{channel}/pipelines/{format}
(default pipeline)GET /channels/{channel}/pipelines/{format}/variants/{variant}
To retrieve a list of all the variants for a specific channel and format and their associated pipeline configuration files, use the endpoint
GET /channels/{channel}/pipelines/{format}/variants
To get a comprehensive view of all pipelines (default and variant) and related pipeline configuration files for a channel and for all formats, use the endpoint
GET /channels/{channel}/pipelines
Deleting pipelines
The base channel's pipelines for a specific format can be deleted with the endpoint
DELETE /channels/{channel}/pipelines/{format}
A channel variant for a specific format can be deleted with the endpoint
DELETE /channels/{channel}/pipelines/{format}/variants/{variant}
When you delete a channel variant pipeline, the related playout URI simply disappears and returns 404.
When you delete the base channel pipeline, the related playout URI keeps working and just returns the original, unedited manifest.
Troubleshooting
Channel Endpoint |
Status Code |
Meaning |
How to fix |
---|---|---|---|
PUT /channels/{channel} |
415 |
Wrong body mime type. |
Please provide an |
PUT /channels/{channel} |
422 |
Your SMIL has a syntax error. |
Check your XML syntax |
PUT /channels/{channel} |
400 |
Your SMIL is not valid. |
Check the options in the head section. Check your body sectio |
PUT /channels/{channel} |
400 |
a channel with that name is Live already |
Add a transition or use the force query parameter (running streams will break!!!). |
PUT /channels/{channel} |
503 |
There may be a running job already for the same channel |
Wait for the job to reach the |
DELETE /channels/{channel} |
404 |
You are trying to delete a non-existing channel. |
Check the channel name |
DELETE /channels/{channel} |
503 |
a channel creation/update job is running. Cannot delete right now. |
Wait for the job to reach the |
GET /channels/{channel}/status |
404 |
The specified channel could not be found |
Double-check the channel name |
GET /channels/{channel}/smil |
404 |
The specified channel could not be found |
Double-check the channel name |
GET /channels/{channel}/isml |
404 |
The specified channel could not be found |
Double-check the channel name |
GET /channels/{channel}/logs/remix |
404 |
The specified channel could not be found |
Double-check the channel name |
GET /channels/{channel}/logs/mp4split |
404 |
The specified channel could not be found |
Double-check the channel name |
GET /channels/{channel}/logs |
404 |
The specified channel could not be found |
Double-check the channel name |
GET /channels/{channel} |
404 |
The specified channel could not be found |
Double-check the channel name |
GET /channels/ |
404 |
No channels have ever been created or they all have been deleted |
Create a new channel |
Transition Endpoint |
Status Code |
Meaning |
How to fix |
---|---|---|---|
PUT /channels/{channel}/transitions/{transition} |
415 |
Wrong body mime type. |
Please provide an |
PUT /channels/{channel}/transitions/{transition} |
422 |
Your SMIL has a syntax error. |
Check your XML syntax |
PUT /channels/{channel}/transitions/{transition} |
400 |
Your SMIL is not valid. |
Check the options in the head section. Check your body sectio |
PUT /channels/{channel}/transitions/{transition} |
400 |
a transition at the same time is Live already |
Create a new transition instead or use the force query parameter (running streams will break!!!). |
PUT /channels/{channel}/transitions/{transition} |
400 |
Cannot process transition playlist, transition time <time> is in the past. |
Choose a new transition time or use the force query parameter (running streams will break!!!). |
PUT /channels/{channel}/transitions/{transition} |
400 |
[...] vod2live_start_time=<time> is after the scheduled transition time <time> |
Choose a new vod2live_start_time or transition time or use the force query parameter (running streams will break!!!). |
PUT /channels/{channel}/transitions/{transition} |
503 |
There may be a running job already for the same transition |
Wait for the job to reach the |
DELETE /channels/{channel}/transitions/{transition} |
404 |
You are trying to delete a non-existing transition. |
Check the transition name |
DELETE /channels/{channel}/transitions/{transition} |
503 |
a transition creation/update job is running. Cannot delete right now. |
Wait for the job to reach the |
GET /channels/{channel}/transitions/{transition}/status |
404 |
The specified transition could not be found |
Double-check the transition name |
GET /channels/{channel}/transitions/{transition}/smil |
404 |
The specified transition could not be found |
Double-check the transition name |
GET /channels/{channel}/transitions/{transition}/isml |
404 |
The specified transition could not be found |
Double-check the transition name |
GET /channels/{channel}/transitions/{transition}/logs/remix |
404 |
The specified transition could not be found |
Double-check the transition name |
GET /channels/{channel}/transitions/{transition}/logs/mp4split |
404 |
The specified transition could not be found |
Double-check the transition name |
GET /channels/{channel}/transitions/{transition}/logs |
404 |
The specified transition could not be found |
Double-check the transition name |
GET /channels/{channel}/transitions |
404 |
The specified transition could not be found |
Double-check the transition name |
Manifest Edit Endpoint |
Status Code |
Meaning |
How to fix |
---|---|---|---|
PUT /channels/{channel}/pipelines/{format} |
415 |
Wrong body mime type. |
Use Content-Type headers with values "text/yaml", "text/x-yaml" or "application/x-yaml" |
PUT /channels/{channel}/pipelines/{format}/variants/{variant} |
415 |
Wrong body mime type. |
Use Content-Type headers with values "text/yaml", "text/x-yaml" or "application/x-yaml" |
PUT /channels/{channel}/pipelines/{format} |
422 |
Invalid yaml pipeline configuration. |
Check the error's response body for further details of what needs fixing |
PUT /channels/{channel}/pipelines/{format}/variants/{variant} |
422 |
Invalid yaml pipeline configuration. |
Check the error's response body for further details of what needs fixing |
GET /channels/{channel}/pipelines/{format} |
404 |
Cannot find pipeline for channel/format |
Double-check the provided {channel} and {format}-yaml |
GET /channels/{channel}/pipelines/{format}/variants/{variant} |
404 |
Cannot find pipeline for channel/format/variant |
Double-check the provided {channel}, {format} and {variant}. |
GET /channels/{channel}/pipelines/{format}/variants |
404 |
Cannot find pipeline for channel/format |
Double-check the provided {channel} and {format} |
GET /channels/{channel}/pipelines |
404 |
Cannot find pipeline for channel |
Double-check the provided {channel}. |
DELETE /channels/{channel}/pipelines/{format} |
404 |
Cannot find pipeline for channel/format |
Double-check the provided {channel} and {format} |
DELETE /channels/{channel}/pipelines/{format}/variants/{variant} |
404 |
Cannot find pipeline for channel/format/variant |
Double-check the provided {channel}, {format} and {variant}. |