logo
Build a UGC Live Streaming App with Amazon IVS: Displaying Viewer Counts on a Channel (Lesson 8.3)

Build a UGC Live Streaming App with Amazon IVS: Displaying Viewer Counts on a Channel (Lesson 8.3)

Welcome to Lesson 8.3 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 retrieves viewer counts for a live stream.

In lesson 5.2, we saw how StreamCat adds live stream playback for low-latency streams to the user's channel. In that lesson, we set a variable called isLive to true when playback begins. For viewer counts, if a stream is live, we'll poll the server every 30 seconds to retrieve the latest viewer count.
1
2
3
4
5
6
7
8
this.$watch('isLive', async () => {
if (this.isLive) {
this.updateViewerCount();
this.viewerCountInterval = setInterval(() => this.updateViewerCount(), 30000);
} else {
clearInterval(this.viewerCountInterval);
}
})
The updateViewerCount() function makes a call to an endpoint to retrieve the latest viewer count.
1
2
3
4
5
async updateViewerCount() {
const request = await fetch(`/api/stream/viewers/${this.channel.id}`);
const response = await request.json();
this.viewers = response.viewers || 1;
}
This endpoint queries the metrics table for the current stream to retrieve a distinct count of viewer IP addresses as of the most recent minute.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Route.get('/stream/viewers/:channelId', async ({ params, response }) => {
const channel = await Channel.find(params.channelId);
await channel?.load('streams');
const stream = channel?.currentStream();
let viewers = 0;
if (stream?.id) {
const viewerQry = await Database.rawQuery(`
select count(distinct ip) as unique_viewers
from metrics
where to_char(created_at, 'HH:MI') = (
select max(to_char(created_at, 'HH:MI'))
from metrics
where stream_id = ?
)
and stream_id = ?
group by to_char(created_at, 'HH:MI')`
,
[stream.id, stream.id]
);
viewers = viewerQry.rows[0]?.unique_viewers || 0;
}
response.send({ viewers });
});

The @aws-sdk/client-ivs module of the AWS SDK for JavaScript (v3) can also provide viewer count information for a channel, but is limited by service quota limitations. If you'd prefer to utilize this approach, you could use the GetStream (docs) method of the IvsClient.
1
2
3
4
5
6
public async getStream(channelArn: string): Promise <GetStreamCommandOutput> {
const request: GetStreamCommand = new GetStreamCommand({
channelArn,
});
return await this.ivsClient.send(request);
};
The GetStreamCommandOutput object contains a stream object which has a viewerCount (docs) property. The docs for this property describe it as:
A count of concurrent views of the stream. Typically, a new view appears in viewerCount within 15 seconds of when video playback starts and a view is removed from viewerCount within 1 minute of when video playback ends. A value of -1 indicates that the request timed out; in this case, retry.

In this lesson, we saw how StreamCat retrieves viewer counts for a user's live stream. In the next lesson, we'll see how StreamCat supports 'following' another user's channel.


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