Heartbeat
Heartbeat is an add-on functionality to the Quickplay Player that facilitates stream concurrency maintenance, maintaining last played position (for VOD) and enforcing geo-restrictions. For Live Streams, Heartbeat can notify the application of all applicable events during the stream.
Setup Heartbeat
Applicability
The corresponding Authorization response for that playback holds the relevant information that indicate whether Heartbeat service is applicable for that playback.
Name | Description |
---|---|
heartbeatFlag | Indicates whether heartbeat should be attached for the current playback. |
heartbeatFrequencyMs | The recommended heartbeat sync interval in milli-seconds |
heartbeatToken | The unique heartbeat token for the current playback |
liveEventType | The type of LIVE event i.e. regular or overflow. Applicable exclusively for live events. |
HeartbeatConfiguration
HeartbeatConfiguration
encapsulates all the necessary information required to enforce Heartbeat. It also holds configurable properties that can be used to tweak
the default behaviors.
Name | Default value | Description |
---|---|---|
heartbeatEndPointUrl | - | Heartbeat service end-point url. |
streamConcurrencyEndPointUrl | - | Stream Concurrency service end-point url. |
heartbeatSyncIntervalMs | 60000L | The time interval in seconds used to periodically update stream state of the currently playing content. Default: 60000 . |
heartbeatMaxAllowedFailures | 2 | The maximum number of failed heartbeat check attempts (network or infrastructure issues) that are allowed to happen in line before the Live content's playback is terminated. Default: 2 . |
recordBookmark | false | Specifies whether to use the heartbeat service to record bookmarks/resume points for VOD contents. Default: false . |
showPostEventSlateTimeMs | 900000L | The amount of time - in milliseconds - that the post slate should be displayed for before sending OVERFLOW_EVENT_END. This is applicable only for overflow events. Default: 900000L . |
stopPlayerOnStreamTimelineEvent | true | Indicates whether the player should automatically be stopped on applicable Stream Timeline Events. |
multiStreamMode | false | Specifies whether the client application has initialized multiple playback sessions. |
trackViewersCount | false | The flag indicates whether to track the viewers count or not, for the content to play. Default value is false. |
val heartbeatConfiguration = HeartbeatConfiguration(
streamConcurrencyEndPointUrl,
heartbeatEndPointUrl,
heartbeatSyncIntervalMs,
heartbeatMaxAllowedFailures,
recordBookmark,
showPostEventSlateTimeMs,
stopPlayerOnStreamTimelineEvent,
multiStreamMode
)
HeartbeatManager
HeartbeatManager
should be attached to a Player by passing the ComposablePlayer
instance as a parameter.
Name | Required | Description |
---|---|---|
contentId | true | The content id for which the heartbeat is to be triggered. |
deviceId | true | The unique identifier of the device. |
heartbeatToken | true | The unique heartbeat token for the current playback. |
heartbeatConfiguration | true | The HeartbeatConfiguration instance that specifies the Heartbeat service configuration. |
platformAuthorizer | true | The PlatformAuthorizer instance to authorize Heartbeat Microservice access. |
player | true | The ComposablePlayer instance that provides PlaybackState information and used to abort the playback in case of errors. |
liveStartTime | false | The start time of the Live event/program in ISO8601 format. |
liveEndTime | false | The end time of the Live event/program in ISO8601 format. |
liveEventType | false | The type of LIVE stream. This value is part of the payload provided by content authorization service response. |
overflowMode | false | The OverflowMode of the overflow LIVE stream. This value is part of the payload provided by content authorization service response. |
headers | false | The optional custom HTTP headers. |
logger | false | The optional Logger instance. |
catalogType | false | The value of the Catalog type of content. |
primaryContentId | false | The unique identifier of the primary content to which the selected content (i.e. secondary angle content) to play is associated with. This is applicable only for multi-camera enabled content. |
live360StartTime | false | The start time of the live 360 camera supported content. |
live360EndTime | false | The end time of the live 360 camera supported content. |
val composedPlayer = composablePlayerWith(player)
val heartbeatManager = HeartbeatFactory.createHeartbeatManager(
contentId,
deviceId,
heartbeatToken,
heartbeatConfiguration,
platformAuthorizer,
composedPlayer,
liveStartTime, // applicable only for live streams. part of content authorization response.
liveEndTime, // applicable only for live streams. part of content authorization response.
liveEventType, // applicable only for live streams. part of content authorization response.
overflowMode, // applicable only for live overflow streams. part of content authorization response.
headers, // optional
logger, //optional,
catalogType, // applicable only for multi camera mode
primaryContentId, // applicable only for multi camera mode
live360StartTime, // applicable only for 360 degree camera mode
live360EndTime // applicable only for 360 degree camera mode
)
Track Watch Count
Watch count of the content can be tracked for business purpose. To extend support for Watch Count, additional param should be passed to HeartbeatConfig
instance.
Along with all necessary information required to enforce Heartbeat, HeartbeatConfig
now encapsulates another optional param trackViewersCount
to track the watch count of the content.
Name | Type | Description |
---|---|---|
trackViewersCount | Boolean | The flag indicates whether to track the viewers count or not, for the content to play. Default value is false. |
val heartbeatConfiguration = HeartbeatConfiguration(
...,
trackViewersCount = true
)
Update Heartbeat token
Quickplay exposes an API to update the heartbeat token so that future heartbeat call will request with the new heartbeat token.
val heartbeatManager = HeartbeatFactory.createHeartbeatManager(
...,
...
)
heartbeatManager.updateHeartbeatToken(<new-token>)
Events during Live Streams
All the applicable events for different type of live streams are part of StreamTimelineEvent
and can be notified to the application using Heartbeat.
The type of live event is indicated to the application using ContentAuthorizationToken.liveEventType
, which is obtained during playback authorization.
Name | Description |
---|---|
LIVE_EVENT_START | The start of a one-time Live event. |
LIVE_EVENT_END | The end of a one-time live event. |
LIVE_PROGRAM_START | The start of a recurring live program. |
LIVE_PROGRAM_END | The end of a recurring live program. |
OVERFLOW_EVENT_END | The end of an overflow event. Applicable only for Overflow events. |
BLACKOUT | The playback has blacked out. |
OVERFLOW_EVENT_END | The end of an overflow event. Applicable only for Overflow events. |
BLACKOUT | The playback has blacked out. |
LIVE_360_AVAILABLE | The Availability of 360 degree mode |
LIVE_360_UNAVAILABLE | The Unavailability of 360 degree mode |
Heartbeat relies on liveStartTime
, liveEndtime
, liveEventType
, live360StartTime
and live360EndTime
passed by the application to send applicable events at the right time.
Listening for StreamTimelineEvents
Heartbeat notifies the application about appropriate StreamTimelineEvents
using the Listener
attached to the ComposablePlayer
that was passed during setup.
override fun onEventReceived(
streamTimelineEvent: StreamTimelineEvent,
suggestedAction: Action,
streamTimelineEventMetadata: StreamTimelineEventMetadata?
) {
// handle events as required
}
Blackouts
While authorizing an asset for Playback, the server might enforce Blackout rules based on tenant specific configuration. When a playback is attempted from a Blacked-out region, the server would respond with the following:
Name | Description |
---|---|
blackoutAction | Indicates appropriate action for Blackout scenario. Possible Values: ALLOW, DENY, ALLOW_WITH_UPGRADE. |
blackoutUrl | The alternate blackout slate stream to play while the user is in blackout. |
When receiving a blackoutAction
other than ALLOW, the application must play the blackoutUrl
instead of the regular contentUrl
. BlackoutUrl
can be obtained from BlackoutMetadata
.
Blackouts are detected and enforced via Heartbeat
to ensure when the user is roaming to a blacked-out region, they are no longer able to stream the content.
When detecting a blackout, the playback will be aborted and StreamTimelineEvent.BLACKOUT
with corresponding Action
and BlackoutMetadata
(if any) will be
propagated to the application via Player.Listener
. Application can process the information and manage the blackout based on the UX requirements (typically,
swap the on-going player with a player playing blacked-out slate).
Overflow Events
Live events that do not have set start or end times are called Overflow
events. These events typically show a pre-slate before the event starts, and
dynamically switch to main content when the event eventually starts. Similarly, a post-slate is typically shown after the content has ended.
OverflowMode
Heartbeat uses the OverflowMode
to detect when the playback has started i.e. before, during or after the event. This should be provided by the application while
setting up Heartbeat.
fun getOverflowMode(): OverflowMode? {
var overflowMode: OverflowMode? = OverflowMode.EVENT
val currentTime = convertToEpochTime(System.currentTimeMillis())
contentAuthorizationToken.liveStartTime?.let { overflowStartTime ->
contentAuthorizationToken.liveEndTime?.let { overflowEndTime ->
overflowMode = when {
currentTime < iso8601UTCDateToEpochTime(overflowStartTime) -> {
OverflowMode.PRE_EVENT
}
currentTime > iso8601UTCDateToEpochTime(overflowEndTime) -> {
OverflowMode.POST_EVENT
}
else -> {
OverflowMode.EVENT
}
}
}
}
return overflowMode
}
fun iso8601UTCDateToEpochTime(iso8601Date: String): Long {
val timeZone = TimeZone.getTimeZone("UTC")
val dateFormat = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss'Z'",
Locale.getDefault()
)
dateFormat.timeZone = timeZone
val date = dateFormat.parse(iso8601Date)
return date.time
}
Handling StreamTimelineEvents
Heartbeat notifies the application of all applicable changes in the live stream to ensure that the playback is updated accordingly.
override fun onEventReceived(
streamTimelineEvent: StreamTimelineEvent,
suggestedAction: Action,
streamTimelineMetadata: StreamTimelineMetadata?
) {
when (streamTimelineEvent) {
StreamTimelineEvent.LIVE_EVENT_START -> {
// indicates the main content has started.
// stop pre-slate playback and start the main content playback.
startLiveEvent()
}
StreamTimelineEvent.LIVE_EVENT_END -> {
// indicates the main content has ended.
// stop main content playback and start the post-slate playback.
endLiveEvent()
}
StreamTimelineEvent.OVERFLOW_EVENT_END -> {
// indicates the post-slate has ended after
// honoring HeartbeatConfiguration.showPostEventSlateTimeMs.
// stop post-slate playback and exit.
player.stop()
}
StreamTimelineEvent.LIVE_360_AVAILABLE -> {
// indicates the availability of 360 degree camera mode
}
StreamTimelineEvent.LIVE_360_UNAVAILABLE -> {
// indicates the unavailability of 360 degree camera mode
}
}
}