Skip to main content

Heartbeat

Heartbeat is an add-on functionality to the Quickplay Player that facilitates stream concurrency maintenance, maintaining the last played position (for VOD), and enforcing geo-restrictions. For Live Streams, Heartbeat can notify your application of all applicable events during the stream.

Setup Heartbeat

Applicability

The corresponding Authorization response for that playback holds the relevant information that indicates whether the Heartbeat service applies to that playback.

NameDescription
heartbeatFlagIndicates whether you should attach heartbeat for the current playback.
heartbeatFrequencyMsThe recommended heartbeat sync interval in milliseconds
heartbeatTokenThe unique heartbeat token for the current playback
liveEventTypeThe type of LIVE event (for example, regular or overflow). Applies exclusively to live events.

HeartbeatConfiguration

HeartbeatConfiguration encapsulates all the necessary information required to enforce Heartbeat. It also holds configurable properties that you can use to tweak the default behaviors.

NameDefault valueDescription
heartbeatEndPointUrl-Heartbeat service end-point url.
streamConcurrencyEndPointUrl-Stream Concurrency service end-point url.
heartbeatSyncIntervalMs60000LThe time interval in seconds used to periodically update stream state of the currently playing content. Default: 60000.
heartbeatMaxAllowedFailures2The 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.
recordBookmarkfalseSpecifies whether to use the heartbeat service to record bookmarks/resume points for VOD contents. Default: false.
showPostEventSlateTimeMs900000LThe 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.
stopPlayerOnStreamTimelineEventtrueIndicates whether the player should automatically be stopped on applicable Stream Timeline Events.
multiStreamModefalseSpecifies whether the client application has initialized multiple playback sessions.
trackViewersCountfalseThe 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

You should attach HeartbeatManager to a Player by passing the ComposablePlayer instance as a parameter.

NameRequiredDescription
contentIdtrueThe content id for which the heartbeat is to be triggered.
deviceIdtrueThe unique identifier of the device.
heartbeatTokentrueThe unique heartbeat token for the current playback.
heartbeatConfigurationtrueThe HeartbeatConfiguration instance that specifies the Heartbeat service configuration.
platformAuthorizertrueThe PlatformAuthorizer instance to authorize Heartbeat Microservice access.
playertrueThe ComposablePlayer instance that provides PlaybackState information and used to abort the playback in case of errors.
liveStartTimefalseThe start time of the Live event/program in ISO8601 format.
liveEndTimefalseThe end time of the Live event/program in ISO8601 format.
programStartTimefalseThe currently playing LIVE program start in ISO8601 format.
programEndTimefalseThe currently playing LIVE program end in ISO8601 format.
liveEventTypefalseThe type of LIVE stream. This value is part of the payload provided by content authorization service response.
overflowModefalseThe OverflowMode of the overflow LIVE stream. This value is part of the payload provided by content authorization service response.
headersfalseThe optional custom HTTP headers.
loggerfalseThe optional Logger instance.
catalogTypefalseThe value of the Catalog type of content.
primaryContentIdfalseThe 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.
live360StartTimefalseThe start time of the live 360 camera supported content.
live360EndTimefalseThe 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.
programStartTime, // applicable only for live streams. part of content authorization response.
programEndTime, // 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

You can track the watch count of content for business purposes. To extend support for Watch Count, you should pass an additional param to the 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.

NameTypeDescription
trackViewersCountBooleanThe 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 calls request with the new heartbeat token.

val heartbeatManager = HeartbeatFactory.createHeartbeatManager(
...,
...
)
heartbeatManager.updateHeartbeatToken(<new-token>)

Events during Live Streams

All the applicable events for different types of live streams are part of StreamTimelineEvent and can be notified to your application using Heartbeat. The type of live event is indicated to your application using ContentAuthorizationToken.liveEventType, which you obtain during playback authorization.

NameDescription
LIVE_EVENT_STARTThe start of a one-time Live event.
LIVE_EVENT_ENDThe end of a one-time live event.
LIVE_PROGRAM_STARTThe start of a recurring live program.
LIVE_PROGRAM_ENDThe end of a recurring live program.
OVERFLOW_EVENT_ENDThe end of an overflow event. Applicable only for Overflow events.
BLACKOUTThe playback has blacked out.
OVERFLOW_EVENT_ENDThe end of an overflow event. Applicable only for Overflow events.
BLACKOUTThe playback has blacked out.
LIVE_360_AVAILABLEThe Availability of 360 degree mode
LIVE_360_UNAVAILABLEThe Unavailability of 360 degree mode

Heartbeat relies on liveStartTime, liveEndtime, liveEventType, live360StartTime, and live360EndTime that you pass to send applicable events at the right time.

Listen for StreamTimelineEvents

Heartbeat notifies your application about appropriate StreamTimelineEvents using the Listener attached to the ComposablePlayer that you 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 you attempt playback from a blacked-out region, the server responds with the following:

NameDescription
blackoutActionIndicates appropriate action for Blackout scenario. Possible Values: ALLOW, DENY, ALLOW_WITH_UPGRADE.
blackoutUrlThe alternate blackout slate stream to play while the user is in blackout.
note

When you receive a blackoutAction other than ALLOW, you must play the blackoutUrl instead of the regular contentUrl. You can obtain BlackoutUrl from BlackoutMetadata.

Blackouts are detected and enforced via Heartbeat to ensure that when you're roaming to a blacked-out region, you're no longer able to stream the content. When detecting a blackout, the playback is aborted and StreamTimelineEvent.BLACKOUT with corresponding Action and BlackoutMetadata (if any) is propagated to your application via Player.Listener. You can process the information and manage the blackout based on the UX requirements (typically, swap the ongoing player with a player playing blacked-out slate).

Overflow Events

Live events that don't 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 ends.

OverflowMode

Heartbeat uses the OverflowMode to detect when the playback has started (that is, before, during, or after the event). You should provide this 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
}

Handle StreamTimelineEvents

Heartbeat notifies your application of all applicable changes in the live stream to ensure that you update the playback 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
}
}
}