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.

Create StreamTimelineManager

Configuration

NameRequiredDescription
leagueNametrueThe name of the leagues (case sensitive)
gameIdtrueThe unique identifier for the game.
firebaseConfigtrueConfiguration object is required to access the Cloud Firestore
spoilerfalseIndicates if the game events should be emitted ahead of the player watch position.
const config = {
leagueName: 'NHL',
gameId: '2022010075',
spoiler: false,
firebaseConfig: {
apiKey: '<key>',
authDomain: '<domain>',
projectId: '<project-id>',
storageBucket: '<bucket>',
messagingSenderId: '<messagingSenderId>',
appId: '<appId>',
measurementId: '<measurementId>',
},
};

streamTimelineManager = flStreamTimeline.createStreamTimelineManager(config, player, logger);
caution

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

Check Events Exists

To check whether timeline events are available for the given gameId, use:

const isExists = await streamTimelineManager.exists();

Setup

To setup the subscription for stream timeline events, use:

const timelineError = await streamTimelineManager.setup();

The setup API will return an Error when setup fails or undefined when successful.

note

StreamTimelineManager publishes events only when setup API is invoked and successful.

Update Player

To update the Player instance to StreamTimelineManager, when swapping player instances in the middle of playback.

streamTimelineManager.updatePlayer(player);

Listening to Timeline events

Once the StreamTimelineManager is created, real-time stream timeline events can be received by subscribing to streamtimelineevent event on the Player instance.

Game Info

The Game metadata is made available via StreamTimelineEvent.GAME_INFO event.

player.subscribe('streamtimelineevent', async function (streamTimelineEvent, action, metadata) {

switch (streamTimelineEvent) {
case flPlayerInterface.StreamTimelineEvent.GAME_INFO: {
console.log('Game Metadata', metadata);
}
}
}

JSONSchema - Game Info

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"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"
}
}
}
]
}
}
}
]
}
},
"required": [
"id"
],
"additionalProperties": false
}

Game Event

The real-time game events are notified via StreamTimelineEvent.GAME_EVENT event. The metdata object indicates the ChangeType which allows the application to respond accordingly.

player.subscribe('streamtimelineevent', async function (streamTimelineEvent, action, metadata) {

switch (streamTimelineEvent) {

case flPlayerInterface.StreamTimelineEvent.GAME_EVENT: {
switch (metadata.type) {
case flStreamTimeline.ChangeType.ADDED: {
// put your logic here
break;
}
case flStreamTimeline.ChangeType.MODIFIED: {
// put your logic here
break;
}
case flStreamTimeline.ChangeType.DELETED: {
// put your logic here
break;
}
}
}
}
}

JSONSchema - Game Event

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"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"
},
"role": {
"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"
}
}
}
]
}
}
}
},
"required": [
"id"
],
"additionalProperties": false
}

Stop Listening to Timeline Events

Shutdown the timeline manager when closing the player or when you are no longer interested in listening stream timeline events.

streamTimelineManager.shutdown()