Re-use SCTE 35 Events from a Live Stream

Unified Remix benefits from not only being able to create new SCTE 35 events (as described above) but also re-use any SCTE 35 events in your source media.

Remix VOD2Live can be incorporated into any existing Unified Remix - nPVR workflow where normally the remixed asset would be presented as a VOD clip, instead now can be presented VOD2Live.

An nPVR archive would store multiple clips over a given time-range that have been captured from a live channel. If the live channel is already conditioned with SCTE 35 based ad replacement opportunities, these would be present within the source clips when captured using Unified Capture against the DASH presentation.

Below is an example of how existing SCTE 35 events can be re-used.

Capture the source stream

With a live stream running, we have identified a portion of the live event we would like to capture between 11:59:50 and 12:00:30. This existing live stream contains a SCTE 35 ad-replacement opportunity at 12:00:00.

So we capture the clip using Unified Capture.

#!/bin/bash

unified_capture \
--remix \
-o captured-clip.mp4 \
"https://demo.unified-streaming.com/k8s/live/scte35.isml/.mpd?vbegin=2021-04-07T11:59:50Z&vend=2021-04-07T12:00:30Z"

The SCTE 35 event capture can then be verified using mp4split:

#!/bin/bash

mp4split -v0 -o stdout:.xml captured-clip.mp4

Which returns:

 1<?xml version="1.0" encoding="utf-8"?>
 2<!-- Created with Unified Streaming Platform  (version=1.11.0-24004) -->
 3<smil
 4  xmlns="http://www.w3.org/2001/SMIL20/Language">
 5  <body>
 6    <seq>
 7      <par>
 8        <EventStream
 9          xmlns="urn:mpeg:dash:schema:mpd:2011"
10          schemeIdUri="urn:scte:scte35:2013:xml"
11          timescale="1">
12          <!-- 2021-04-07T12:00:00Z -->
13          <Event
14            presentationTime="1617796800"
15            duration="19"
16            id="917">
17            <Signal
18              xmlns="http://www.scte.org/schemas/35/2016">
19              <SpliceInfoSection>
20                <SpliceInsert
21                  spliceEventId="917"
22                  outOfNetworkIndicator="1"
23                  spliceImmediateFlag="1"
24                  uniqueProgramId="49152"
25                  availNum="0"
26                  availsExpected="0">
27                  <Program>
28                  </Program>
29                  <BreakDuration
30                    autoReturn="1"
31                    duration="1710000" />
32                </SpliceInsert>
33              </SpliceInfoSection>
34            </Signal>
35          </Event>
36        </EventStream>
37      </par>
38    </seq>
39  </body>
40</smil>

Remix the captured clip

We can now use captured-clip.mp4 as input to Unified Remix using the below SMIL file to create remixed-clip.mp4. The stdout messaging from Unified Remix will signal the presence of a SCTE 35 with a statement Event Messages received.

1<?xml version="1.0" encoding="UTF-8"?>
2<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
3  <body>
4    <seq>
5      <video src="capture-clip.mp4" />
6    </seq>
7  </body>
8</smil>
#!/bin/bash

unified_remix -o remixed-clip.mp4 remixed-clip.smil

Which will print:

 1unified_remix version=1.11.0 (24004)    Copyright 2015-2021 CodeShop B.V.
 2
 3I0.000 input: file:///data/remixed-clip.smil
 4I0.000 output: file:///data/remixed-clip.mp4
 5I0.027 Target track selection set:
 6I0.027 [1/2]: id=1 timescale=48000 lang=und
 7I0.027 soun/mp4a dref=1 bitrate=69000/69000 tag=255 samplerate=48000 channels=1 sample_size=16 packet_size=2
 8I0.027 [2/2]: id=2 timescale=90000 lang=und
 9I0.027 vide/avc1 dref=1 bitrate=700000/493000 size=1280x720 sar=1:1 dar=16:9 codecs=avc1.64001F
10I0.028 event id=917 (scheme_id=urn:scte:scte35:2013:bin): presentationTime=00:00:10.000000(10/1) -> 00:00:08.405333(756480/90000)
11I0.028 event id=917 (scheme_id=urn:scte:scte35:2013:bin): duration=00:00:19.000000(19/1) -> 00:00:19.200000(96/5)
12I0.028 [1/2]: movie=00:00:00.000000
13I0.028 [2/2]: movie=00:00:00.005333
14I0.029 [1/2]: movie=00:00:40.000000
15I0.029 [2/2]: movie=00:00:40.005333
16I0.029 emsg[917] presentation_time=756480 duration=1728000/90000
17I0.029 1 Event Messages received of which 1 are unique.
18I0.029 stat: url=file:///data/remixed-clip.smil, reads=1, size=197 bytes
19I0.029 stat: url=file:///data/captured-clip.mp4, reads=3, size=91 KB
20I0.029 writing 5 buckets for a total of 21 KB
21I0.067 total running time is 0.067135 seconds
22Status: 200 FMP4_OK

Generate the server manifest

Next we create a VOD2Live server manifest with the required --timed_metadata and --splice_media options to support the signaling of SCTE 35 events in the client manifests.

The stdout from mp4split will signal the presence of a meta track contained in the source.

Where running:

#!/bin/bash

mp4split -o vod2live-remixed-clip.isml \
--vod2live \
--dvr_window_length=30 \
--archiving=false \
--hls.client_manifest_version=4 \
--hls.minimum_fragment_length=48/25 \
--timed_metadata --splice_media \
remixed-clip.mp4

Will print:

 1mp4split version=1.11.0 (24004)    Copyright 2007-2021 CodeShop B.V.
 2
 3I0.015 Manifest file:///data/vod2live-remixed-clip.isml
 4I0.030 Track 1:
 5I0.030 src=remixed-clip.mp4
 6I0.030 audio bitrate=69000 name=audio
 7I0.030 id=1 timescale=48000 lang=und
 8I0.030 soun/mp4a dref=1 bitrate=69000/69000 tag=255 samplerate=48000 channels=1 sample_size=16 packet_size=2
 9I0.030 soun/mp4a dref=2 (captured-clip.mp4) bitrate=69000/69000 tag=255 samplerate=48000 channels=1 sample_size=16 packet_size=2
10I0.030 Track 2:
11I0.030 src=remixed-clip.mp4
12I0.030 video bitrate=700000/493000 name=video
13I0.030 id=2 timescale=90000 lang=und
14I0.030 vide/avc1 dref=1 bitrate=700000/493000 size=1280x720 sar=1:1 dar=16:9 codecs=avc1.64001F
15I0.030 vide/avc1 dref=2 (captured-clip.mp4) bitrate=700000/493000 size=1280x720 sar=1:1 dar=16:9 codecs=avc1.64001F
16I0.030 Track 3:
17I0.030 src=remixed-clip.mp4
18I0.030 meta bitrate=1000 name=meta
19I0.030 id=3 timescale=375 lang=und
20I0.030 scheme_id=urn:scte:scte35:2013:bin
21I0.030 meta/urim dref=1 bitrate=1000/0
22I0.032 writing 1 buckets for a total of 2390 bytes
23I0.060 stat: url=file:///data/remixed-clip.mp4, reads=1, size=21 KB
24I0.060 stat: url=file:///data/captured-clip.mp4, reads=1, size=20 KB
25Status: 200 FMP4_OK

Request the VOD2Live client manifest

The 30 second captured clip containing the existing SCTE 35 ad-replacement opportunities can now be played out VOD2Live in a continuous loop.

The example manifest below shows the previous SCTE 35 event being re-used as part of the VOD2Live stream. Where the necessary timing information for both the source clip and required presentationTime of the event have been realigned to the timeline of the live stream.

Using mp4split to generate Origin output and print it to stdout from the command-line:

#!/bin/bash

mp4split -v0 -o stdout: vod2live-remixed-clip.isml/.mpd

Which will print the MPD:

  1<?xml version="1.0" encoding="utf-8"?>
  2<!-- Created with Unified Streaming Platform  (version=1.11.0-24004) -->
  3<MPD
  4  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5  xmlns="urn:mpeg:dash:schema:mpd:2011"
  6  xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
  7  type="dynamic"
  8  availabilityStartTime="1970-01-01T00:00:00Z"
  9  publishTime="2021-04-07T13:02:43.874153Z"
 10  minimumUpdatePeriod="PT2S"
 11  timeShiftBufferDepth="PT30S"
 12  maxSegmentDuration="PT3S"
 13  minBufferTime="PT10S"
 14  profiles="urn:mpeg:dash:profile:isoff-live:2011,urn:hbbtv:dash:profile:isoff-live:2012">
 15  <Period
 16    id="1"
 17    start="PT0S">
 18    <BaseURL>dash/</BaseURL>
 19    <EventStream
 20      schemeIdUri="urn:scte:scte35:2014:xml+bin"
 21      timescale="720000">
 22      <!-- 2021-04-07T13:02:06.384000Z -->
 23      <Event
 24        presentationTime="1164816378996480"
 25        duration="13824000"
 26        id="353014667">
 27        <Signal
 28          xmlns="http://www.scte.org/schemas/35/2016">
 29          <Binary>/DAgAAAAAAAAAP/wDwUAAAOVf//+ABoXsMAAAAAAACt+1iQ=</Binary>
 30        </Signal>
 31      </Event>
 32    </EventStream>
 33    <AdaptationSet
 34      id="1"
 35      group="1"
 36      contentType="audio"
 37      segmentAlignment="true"
 38      audioSamplingRate="48000"
 39      mimeType="audio/mp4"
 40      codecs="mp4a.40.2"
 41      startWithSAP="1">
 42      <AudioChannelConfiguration
 43        schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011"
 44        value="1" />
 45      <InbandEventStream
 46        schemeIdUri="urn:scte:scte35:2014:xml+bin">
 47      </InbandEventStream>
 48      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
 49      <SegmentTemplate
 50        timescale="48000"
 51        initialization="vod2live-remixed-clip-$RepresentationID$.dash"
 52        media="vod2live-remixed-clip-$RepresentationID$-$Time$.dash">
 53        <!-- 2021-04-07T13:02:13.978666Z / 1617800533 - 2021-04-07T13:02:44Z -->
 54        <SegmentTimeline>
 55          <S t="77654425630976" d="96256" r="2" />
 56          <S d="95232" />
 57          <S d="96256" />
 58          <S d="76800" />
 59          <S d="115712" />
 60          <S d="95232" />
 61          <S d="96256" r="2" />
 62          <S d="95232" />
 63          <S t="77654426783232" d="96256" r="2" />
 64        </SegmentTimeline>
 65      </SegmentTemplate>
 66      <Representation
 67        id="audio=69000"
 68        bandwidth="69000">
 69      </Representation>
 70    </AdaptationSet>
 71    <AdaptationSet
 72      id="2"
 73      group="2"
 74      contentType="video"
 75      par="16:9"
 76      segmentAlignment="true"
 77      width="1280"
 78      height="720"
 79      sar="1:1"
 80      frameRate="25"
 81      mimeType="video/mp4"
 82      codecs="avc3.64001F"
 83      startWithSAP="1">
 84      <InbandEventStream
 85        schemeIdUri="urn:scte:scte35:2014:xml+bin">
 86      </InbandEventStream>
 87      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
 88      <SegmentTemplate
 89        timescale="600"
 90        initialization="vod2live-remixed-clip-$RepresentationID$.dash"
 91        media="vod2live-remixed-clip-$RepresentationID$-$Time$.dash">
 92        <!-- 2021-04-07T13:02:14.063333Z / 1617800534 - 2021-04-07T13:02:44.468333Z -->
 93        <SegmentTimeline>
 94          <S t="970680320438" d="1152" r="11" />
 95          <S d="528" />
 96          <S t="970680334793" d="1584" />
 97          <S d="1152" r="1" />
 98        </SegmentTimeline>
 99      </SegmentTemplate>
100      <Representation
101        id="video=700000"
102        bandwidth="700000"
103        scanType="progressive">
104      </Representation>
105    </AdaptationSet>
106  </Period>
107  <UTCTiming
108    schemeIdUri="urn:mpeg:dash:utc:http-iso:2014"
109    value="https://time.akamai.com/?iso" />
110</MPD>

Note

When capturing and re-using SCTE 35 events as part of an nPVR, AVOD or VOD2Live based workflow the same requirements apply.

Such as ensuring your source SCTE 35 event aligns with IDR video frames and/or segment boundaries. If not, remix will automatically update the desired presentationTime and duration to align the valid boundaries.

If the SCTE 35 event spans 2 archive clips, both clips need to be referenced as sources within the remix smil (necessary clipBegin or clipEnd timing can also be applied).