logo
Build a UGC Live Streaming App with Amazon IVS: Capturing Playback Metrics (Lesson 7.1)

Build a UGC Live Streaming App with Amazon IVS: Capturing Playback Metrics (Lesson 7.1)

Welcome to Lesson 7.1 in this series where we're looking at building a web based user-generated content live streaming application with Amazon IVS. This entire series is available in video format on the AWS Developers YouTube channel and all of the code related to the sample application used in this series can be viewed on GitHub. Refer to the links at the end of the post for more information.

TS
Todd Sharp
Amazon Employee
Published Jan 3, 2024

In this lesson, we'll learn how the StreamCat application collects and persists data related to live stream playback.

If you recall from earlier lessons in this course, a user's Channel has a one-to-many relationship with the Stream object. A Stream has a one-to-many relationship with the Metric object.
Channel, Stream, Metric Relationship
Channel, Stream, Metric Relationship
As shown in the relationship diagram, the Metric object contains:
  • Client data (such as the browser name and version)
  • Session data (the client IP address)
  • Playback quality data (such as the bitrate, framerate, etc)
StreamCat collects and persists this data every 30 seconds during low-latency stream playback. The data is used by the application to obtain current viewer counts on live streams and provide viewer insight within the user's dashboard. Your application may want to report client, session and playback data at a higher level to be used for detailed analysis of all channels.
💡 Note: This course makes no recommendations or assumptions on the legality of collecting client and session data. Your application should consider the laws regarding user privacy and data collection in the regions in which you are operating.
In a future lesson, we'll see how the StreamCat application aggregates this data and displays it, but for now we'll focus on how the data is collected.

If you recall from lesson 5.2, when low-latency live stream playback is initialized we set up a function to watch the isLive variable. When a stream is not live, we started a interval to attempt to playback the stream (this.pollForStream()). When the stream became live, we stopped the interval. To capture playback metrics, StreamCat uses this same watcher to start and stop an interval that calls a function to persist the metrics every 30 seconds.
1
2
3
4
5
6
7
8
9
10
11
this.$watch('isLive', async () => {
if (this.isLive) {
clearInterval(this.playbackInterval);
this.playbackInterval = null;
this.postAnalytics();
this.analyticsInterval = setInterval(() => this.postAnalytics(), 30000);
} else {
this.pollForStream();
clearInterval(this.analyticsInterval);
}
});
The postAnalytics() function makes a fetch() call to `POST` data to the /api/player/analytics endpoint.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
async postAnalytics() {
const quality = this.ivsPlayer.getQuality();
const session = this.ivsPlayer.getSessionData();
const clientData = client.getBrowserData();
await fetch('/api/player/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
channelId: this.channel.id,
ip: session['USER-IP'],
browserName: clientData.browser?.name,
browserVersion: clientData.browser?.version,
os: clientData.os?.name,
userAgent: clientData?.ua,
isMobile: client.isMobile(),
tz: client.getTimeZone(),
availableResolution: client.getAvailableResolution(),
currentResolution: client.getCurrentResolution(),
quality: quality.name,
codecs: quality.codecs,
bitrate: quality.bitrate,
framerate: quality.framerate,
latency: Number(this.ivsPlayer.getLiveLatency().toFixed(2)),
buffer: Number(this.ivsPlayer.getBufferDuration().toFixed(2)),
}),
});
}
This function retrieves the quality and session data from the ivsPlayer instance. The client data is retrieved via a third-party library called ClientJS.
On the server side, the data is persisted into the database.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Route.post('/player/analytics', async ({ request }) => {
const body = request.body();
const { channelId, ...metrics } = body;
const stream = await Stream
.query()
.where('channelId', channelId)
.andWhereNull('endedAt')
.orderBy('startedAt', 'desc')
.first();
if (stream?.id) {
const metric = await Metric.create(metrics);
metric.related('stream').associate(stream);
}
});

In this lesson, we learned how the StreamCat application collects and persists client, session, and playback quality data into the database. In future lessons, we'll see how this data can be used to retrieve current viewer counts and to generate stream analytics reports in the user's dashboard.


Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.