HLS Timed Metadata

HLS Timed Metadata feature helps you synchronise certain events with the HLS stream. This can be useful for showing interactive quizzes / product overlays etc.

Requirements

  • 100ms Android SDK version 2.5.6 or higher
  • Active HLS stream

Sending HLS Timed Metadata

To add HLS timed metadata cue to the currently running HLS stream use setHlsSessionMetadata API like this:

val metadata = HMSHLSTimedMetadata( payload = payloadText, duration = durationText ) hmsSDK.setHlsSessionMetadata(arrayListOf(hmsHLSTimedMetadata), object : HMSActionResultListener { override fun onError(error: HMSException) { Log.d(TAG, "hls metadata sending failed"); } override fun onSuccess() { Log.d(TAG, "hls metadata sent successfully"); } })

Receiving HLS Timed Metadata

Getting metadata from exoplayer

val hlsManifest = exoPlayer.currentManifest as HlsManifest? val windowIndex = exoPlayer.currentMediaItemIndex val timeline = exoPlayer.currentTimeline val window = timeline.getWindow(windowIndex, Timeline.Window()) val currentAbsolutePosition = (window.windowStartTimeMs + exoPlayer.currentPosition) val META_DATA_MATCHER = "#EXT-X-DATERANGE:ID=\"(?<id>.*)\",START-DATE=\"(?<startDate>.*)\",DURATION=(?<duration>.*),X-100MSLIVE-PAYLOAD=\"(?<payload>.*)\"" var duration = 0; var tagStartTime = 0L; String payload = ""; hlsManifest?.mediaPlaylist?.tags?.forEach { if (it.contains("EXT-X-DATERANGE")) { val pattern = Pattern.compile(META_DATA_MATCHER) val matcher = pattern.matcher(it) if (matcher.matches()) { try { // X-100MSLIVE-PAYLOAD : this contains payload passed in metadata from setHlsSessionMetadata() payload = matcher.group(4).orEmpty() // DURATION : this contains duration that was passed in metadata from setHlsSessionMetadata() duration = matcher.group(3).orEmpty().toLongOrNull()?.times(1000) ?: 0 // START-DATE : this contains start time for metadata val startDate = matcher.group(2).orEmpty() val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") formatter.timeZone = UTC tagStartTime = formatter.parse(startDate).time // Syncing of metadata with current player position. if (tagStartTime <= currentAbsolutePosition && currentAbsolutePosition - tagStartTime <= duration) { Log.i(TAG,payload); } return@lastOrNull tagStartTime <= currentAbsolutePosition } catch (e: Exception) { e.printStackTrace(); } } } false }

Please Note : above step has to be repeated periodically to sync meta-data with playback.


Have a suggestion? Recommend changes ->

Was this helpful?

1234