Timeline Events
The fl-stream-timeline library facilitates streaming real-time events for an on-going live stream to enable rich, interactive Live experiences.
Create StreamTimelineManager
Use the following configuration and manager settings to set up timeline events for your live stream.
StreamTimelineConfiguration
| Values | Type | Description |
|---|---|---|
| leagueName | String | The league name for the content to play. For example: NHL, NBA, IPL |
| gameId | String | The identifier for the particular game |
| spoiler | Bool | true to receive events as soon as available, false to receive events as per playhead progress. Default value is false |
StreamTimelineManager
| Values | Type | Description |
|---|---|---|
| configuration | StreamTimelineConfiguration | The configuration information required by the manager |
| player | Player | The player that's 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.
Listen to Player Events
The player should confirm to EventSendableDelegate to receive events. Once you've subscribed the StreamTimelineManager, you can receive real-time stream timeline events on the Player instance.
StreamTimelineEvent
| Value | Description |
|---|---|
| gameInfo | The Game metadata event received in the gameInfo type |
| gameEvent | The StreamTimeline events are received in the gameEvent type |
Action
| Value | Description |
|---|---|
| none | No action is required on the playback. For example: playback start or playback end |
StreamTimelineMetadata
| Values | Type | Description |
|---|---|---|
| eventMetadata | [String: Any] | The metadata of the stream timeline event |
| type | ChangeType | The stream timeline event type of action that happened on the event |
ChangeType
| Value | Description |
|---|---|
| added | A new event added to the stream timeline |
| modified | The existing event metadata is modified |
| deleted | The existing event metadata is deleted |
| unknown | The event is triggered without type info. StreamTimelineEvent.gameInfo is received 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
The following JSON schemas define the structure of game information and game events.
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
Call this method when closing the player or when you're no longer interested in listening to stream timeline events.
streamTimelineManager.shutdown()