Skip to content
71 changes: 70 additions & 1 deletion src/mux-analytics.brs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@ function muxAnalytics() as Object
m._videoSourceDuration = Invalid
m._videoCurrentCdn = Invalid
m._viewPrerollPlayedCount = Invalid
m._totalAdWatchTime = Invalid
m._adWatchTime = Invalid
m._cumulativePlayingTime = Invalid
m._lastAdResumeTime = Invalid

m._lastSourceWidth = Invalid
m._lastSourceHeight = Invalid
Expand Down Expand Up @@ -926,12 +930,20 @@ function muxAnalytics() as Object
end sub

prototype._rafEventhandler = sub(eventType, ctx, adMetadata)
date = m._getDateTime()
now = 0# + date.AsSeconds() * 1000.0# + date.GetMilliseconds()

if m._adWatchTime = Invalid
m._adWatchTime = 0
end if

m._Flag_isPaused = (eventType = "Pause")
if eventType = "PodStart"
m._advertProperties = m._getAdvertProperties(adMetadata)
m._addEventToQueue(m._createEvent("adbreakstart"))
' In the case that this is SSAI, we need to signal an adplay and adplaying event
if m._Flag_useSSAI = true
m._lastAdResumeTime = now
m._addEventToQueue(m._createEvent("adplay"))
m._addEventToQueue(m._createEvent("adplaying"))
end if
Expand All @@ -947,6 +959,10 @@ function muxAnalytics() as Object
else if eventType = "Impression"
m._addEventToQueue(m._createEvent("adimpression"))
else if eventType = "Pause"
if m._lastAdResumeTime <> Invalid
m._adWatchTime += max(0, now - m._lastAdResumeTime)
m._lastAdResumeTime = Invalid
end if
m._addEventToQueue(m._createEvent("adpause"))
else if eventType = "Start"
if m._viewTimeToFirstFrame = Invalid
Expand All @@ -965,13 +981,21 @@ function muxAnalytics() as Object
m._viewPrerollPlayedCount++
end if
m._advertProperties = m._getAdvertProperties(ctx)
m._adWatchTime = 0
m._lastAdResumeTime = now
m._addEventToQueue(m._createEvent("adplay"))
m._addEventToQueue(m._createEvent("adplaying"))
else if eventType = "Resume"
m._lastAdResumeTime = now
m._advertProperties = m._getAdvertProperties(ctx)
m._addEventToQueue(m._createEvent("adplay"))
m._addEventToQueue(m._createEvent("adplaying"))
else if eventType = "Complete"
if m._lastAdResumeTime <> Invalid
m._adWatchTime += max(0, now - m._lastAdResumeTime)
m._lastAdResumeTime = Invalid
end if
m._totalAdWatchTime += m._adWatchTime
m._addEventToQueue(m._createEvent("adended"))
else if eventType = "NoAdsError"
if m._Flag_FailedAdsErrorSet <> true
Expand All @@ -997,12 +1021,24 @@ function muxAnalytics() as Object
else if eventType = "ThirdQuartile"
m._addEventToQueue(m._createEvent("adthirdquartile"))
else if eventType = "Skip"
if m._lastAdResumeTime <> Invalid
m._adWatchTime += max(0, now - m._lastAdResumeTime)
m._lastAdResumeTime = Invalid
end if
m._totalAdWatchTime += m._adWatchTime
m._addEventToQueue(m._createEvent("adskipped"))
m._addEventToQueue(m._createEvent("adended"))
end if
end sub

prototype._renderStitchedStreamRafEventHandler = sub(eventType, ctx, adMetadata)
date = m._getDateTime()
now = 0# + date.AsSeconds() * 1000.0# + date.GetMilliseconds()

if m._adWatchTime = Invalid
m._adWatchTime = 0
end if

if eventType = "AdStateChange"
state = ctx.state
m._advertProperties = m._getAdvertProperties(adMetadata)
Expand All @@ -1018,21 +1054,31 @@ function muxAnalytics() as Object
m._Flag_isPaused = false
m._addEventToQueue(m._createEvent("adplay"))
else if state = "playing"
' in the playing state, if we either resuming, we need adplay first
' in the playing state, if we are resuming, we need adplay first
if m._Flag_isPaused
m._Flag_isPaused = false
m._addEventToQueue(m._createEvent("adplay"))
else
' starting fresh: reset watch time
m._adWatchTime = 0
end if
' and always emit adplaying
m._lastAdResumeTime = now
m._addEventToQueue(m._createEvent("adplaying"))
else if state = "paused"
if m._lastAdResumeTime <> Invalid
m._adWatchTime += max(0, now - m._lastAdResumeTime)
m._lastAdResumeTime = Invalid
end if
m._Flag_isPaused = true
m._addEventToQueue(m._createEvent("adpause"))
end if
else if eventType = "PodStart"
' Need to handle PodStart for non-pre-rolls
if not m._Flag_rssInAdBreak
m._Flag_rssInAdBreak = true
m._adWatchTime = 0
m._lastAdResumeTime = now
if not m._Flag_isPaused
m._Flag_isPaused = true
m._addEventToQueue(m._createEvent("pause"))
Expand All @@ -1042,13 +1088,20 @@ function muxAnalytics() as Object
else if eventType = "Complete"
' Complete signals an ad has finished playback
m._Flag_rssAdEnded = true
if m._lastAdResumeTime <> Invalid
m._adWatchTime += max(0, now - m._lastAdResumeTime)
m._lastAdResumeTime = Invalid
end if
m._totalAdWatchTime += m._adWatchTime
m._addEventToQueue(m._createEvent("adended"))
else if eventType = "Impression"
' When an additional ad is played within an ad pod, we do not get
' the AdStateChange events or anything other than the Impression
' event to know that a new ad was played
if m._Flag_rssAdEnded
m._Flag_rssAdEnded = false
m._adWatchTime = 0
m._lastAdResumeTime = now
m._addEventToQueue(m._createEvent("adplay"))
m._addEventToQueue(m._createEvent("adplaying"))
end if
Expand Down Expand Up @@ -1139,6 +1192,7 @@ function muxAnalytics() as Object
if m._contentPlaybackTime = Invalid then return

m._viewWatchTime = m._viewTimeToFirstFrame + m._viewRebufferDuration + m._contentPlaybackTime
m._cumulativePlayingTime = m._viewWatchTime + m._totalAdWatchTime
end sub

prototype._setBufferingMetrics = sub()
Expand Down Expand Up @@ -1275,6 +1329,9 @@ function muxAnalytics() as Object
end if
m._viewId = m._generateGUID()
m._viewWatchTime = 0
m._adWatchTime = 0
m._totalAdWatchTime = 0
m._cumulativePlayingTime = 0
m._contentPlaybackTime = 0
m._viewRebufferCount = 0
m._viewRebufferDuration = 0
Expand Down Expand Up @@ -1329,6 +1386,10 @@ function muxAnalytics() as Object
m._playerTimeToFirstFrame = Invalid
m._contentPlaybackTime = Invalid
m._viewWatchTime = Invalid
m._adWatchTime = Invalid
m._lastAdResumeTime = Invalid
m._totalAdWatchTime = Invalid
m._cumulativePlayingTime = Invalid
m._viewRebufferCount = Invalid
m._viewRebufferDuration = Invalid
m._viewRebufferFrequency! = Invalid
Expand Down Expand Up @@ -1689,6 +1750,12 @@ function muxAnalytics() as Object
if m._viewRequestCount <> Invalid
props.view_request_count = m._viewRequestCount
end if
if m._cumulativePlayingTime <> Invalid AND m._cumulativePlayingTime > 0
props.view_playing_time_ms_cumulative = m._cumulativePlayingTime
end if
if m._totalAdWatchTime <> Invalid AND m._totalAdWatchTime > 0
props.ad_playing_time_ms_cumulative = m._totalAdWatchTime
end if
if m._configProperties <> Invalid AND m._configProperties.player_init_time <> Invalid
playerInitTime = Invalid
if Type(m._configProperties.player_init_time) = "roString"
Expand Down Expand Up @@ -2063,6 +2130,7 @@ function muxAnalytics() as Object
"current": "cu",
"connection": "cx",
"context": "cz",
"cumulative": "cv",
"downscaling": "dg",
"domain": "dm",
"cdn": "dn",
Expand Down Expand Up @@ -2124,6 +2192,7 @@ function muxAnalytics() as Object
"manufacturer": "mn",
"model": "mo",
"mux": "mx",
"ms": "ms",
"newest": "ne",
"name": "nm",
"number": "no",
Expand Down