Skip to main content

Timeline Events

fl-stream-timeline library facilitates streaming real-time events for an on-going live stream to enable rich, interactive Live experiences.

Creating StreamTimelineManager

StreamTimelineConfiguration
ValuesTypeDescription
leagueNameStringThe league name for the content is going to play. Ex: NHL, NBA, IPL,..etc
gameIdStringThe Identifier for the particular game.
spoilerBooltrue to receive events as soon as available, false to receive events as per playhead progress. Default value is false.
StreamTimelineManager
ValuesTypeDescription
configurationStreamTimelineConfigurationThe configuration information required to the manager
playerPlayerThe player which playing the content. It should confirm to EventSendableDelegate to receive events.

let streamTimelineConfig = FLStreamTimelineFactory.streamTimelineConfiguration(leagueName: "NHL", gameId: "2354717", spoiler: false)
let streamTimelineManager = FLStreamTimelineFactory.streamTimelineManager(configuration: streamTimelineConfig, player: player)
// Check if the game is available to subscribe
streamTimelineManager.canSubscribeEvents { isSuccess in
if isSuccess {
// Subscribe to timeline events
streamTimelineManager.subscribeEvents { result in
switch result {
case .success:
print("StreamTimeline subscribed!")
case .failure:
print("StreamTimeline subscribe failed!")
}
}
}
}
caution

Firebase charges for document reads and writes, so we recommend creating the TimelineManager lazily.

Listening to Player Events

The player should be confirmed to EventSendableDelegate to receive events. Once the StreamTimelineManager is subscribed, real-time stream timeline events can be received on the Player instance.

StreamTimelineEvent
ValueDescription
gameInfoThe Game metadata event receivde in the gameInfo type
gameEventThe StreamTimeline events are received in the gameEvent type
Action
ValueDescription
noneNo action is required on the playback. For ex: playback start or playback end.
StreamTimelineMetadata
ValuesTypeDescription
eventMetadata[String: Any]The metadata of the stream timeline event.
typeChangeTypeThe stream timeline event have been sent with the type of action happened on the event
ChangeType
ValueDescription
addedA new event added to the stream timeline
modifiedThe existing event metadata is modified
deletedThe existing event metadata is deleted
unknownThe event is triggered without type info. StreamTimelineEvent.gameInfo will receive on this type.
func didReceive(event: StreamTimelineEvent, suggestedAction: Action, metadata: StreamTimelineMetadata?) { 
switch event {
case .gameInfo:
guard let data = metadata as? TimelineEventMetadata else { return }
print("Game Info Metadata: \(data.eventMetadata)")
break
case .gameEvent:
guard let data = metadata as? TimelineEventMetadata else { return }
print("Game Event Metadata: \(data.eventMetadata)")
switch data.type {
case .added:
// put your logic here
case .modified:
// put your logic here
case .deleted:
// put your logic here
default:
break
}
break
default:
break
}
}

JSONSchema

Game Info
{
"id": {
"type": "string"
},
"matchNumber": {
"type": "string"
},
"season": {
"type": "string"
},
"series": {
"type": "string"
},
"scheduledStart": {
"type": "string",
"format": "date-time"
},
"timestamp": {
"type": "string",
"format": "date-time"
},
"venue_id": {
"type": "string"
},
"venue_name": {
"type": "string"
},
"game_year": {
"type": "string"
},
"teams": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"id": {
"type": "string"
},
"images": {
"type": "array",
"items": [
{
"type": "string"
}
]
},
"region": {
"type": "string"
},
"name": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"home",
"visitor"
]
},
"players": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"currentTeam": {
"type": "string"
},
"name": {
"type": "string"
},
"images": {
"type": "array",
"items": [
{
"type": "string"
}
]
},
"id": {
"type": "string"
},
"number": {
"type": "string"
},
"position": {
"type": "string"
}
}
}
]
}
}
}
]
}
}
Game Event
{
"description": {
"type": "string"
},
"id": {
"type": "string",
"format": "date-time"
},
"teamInvolved": {
"type": "string",
"enum": [
"home",
"visitor"
]
},
"timestamp": {
"type": "string",
"format": "date-time"
},
"period": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"period_start",
"period_end",
"overtime_start",
"overtime_end",
"shootout_start",
"shootout_end",
"break_start",
"break_end",
"goal",
"penalty",
"penalty_shot"
]
},
"startTime": {
"type": "string",
"format": "date-time"
},
"players": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"winner",
"loser",
"shooter",
"goalie",
"scorer",
"assist",
"unknown",
"blocker",
"hitter",
"hittee"
]
}
}
}
]
},
"scorecard": {
"type": "object",
"properties": {
"total": {
"type": "object",
"properties": {
"visitor": {
"type": "string"
},
"home": {
"type": "string"
}
}
},
"goals_by_period": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"visitor": {
"type": "string"
},
"home": {
"type": "string"
},
"period": {
"type": "string"
}
}
}
]
}
}
}
}
Stop Listening to StreamTimeline Events

This should be called when closing the player or when you no longer interested in listening stream timeline events.


streamTimelineManager.shutdown()