
Build a UGC Live Streaming App with Amazon IVS: Responding to Stream State Events (Lesson 3.5)
Welcome to Lesson 3.5 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.
- Stream Start
- Stream End
- Recording Start
- Recording End
1
2
3
4
[
'IVS Stream State Change',
'IVS Recording State Change'
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"version": "0",
"id": "[redacted]",
"detail-type": "IVS Stream State Change",
"source": "aws.ivs",
"account": "[redacted]",
"time": "2023-05-16T15:54:09Z",
"region": "us-east-1",
"resources": [
"arn:aws:ivs:us-east-1:[redacted]:channel/[redacted]"
],
"detail": {
"event_name": "Stream Start",
"channel_name": "[redacted]",
"stream_id": "[redacted]"
}
}
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
{
"version": "0",
"id": "[redacted]",
"detail-type": "IVS Recording State Change",
"source": "aws.ivs",
"account": "[redacted]",
"time": "2023-06-14T14:33:16Z",
"region": "us-east-1",
"resources": [
"arn:aws:ivs:us-east-1:[redacted]:channel/[redacted]"
],
"detail": {
"recording_status": "Recording End",
"recording_status_reason": "",
"recording_s3_bucket_name": "streamcat-vod-storage",
"recording_s3_key_prefix": "ivs/v1/[redacted]",
"recording_duration_ms": 1000,
"channel_name": "[redacted]",
"stream_id": "[redacted]",
"recording_session_id": "[redacted]",
"recording_session_stream_ids": [
"[redacted]"
]
}
}
- Updates the
Channel
to setisLive
totrue
- Inserts a new
Stream
object in the database.
💡 Note: Refer to lesson 1 to learn more about StreamCat's schema and the relationship betweenChannel
andStream
.
Stream Start
or Stream End
, we can use the event.detail.event_name
property to determine the proper value to set Channel.isLive
.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const isLive = event.detail.event_name === 'Stream Start';
const channelResult = await client.query(`
select id, title, category_id
from channels
where arn = $1`,
[
event.resources[0]
]
);
const channelId = channelResult.rows[0].id;
await client.query(`
update channels
set is_live = $1
where id = $2`,
[
isLive,
channelId
]
);
Stream
record depending on whether or not one exists for the given stream_id
. This method captures the title
, and category_id
of the Channel
when the broadcast began1
2
3
4
5
6
7
8
9
10
11
12
13
await client.query(`
insert into streams (stream_id, channel_id, started_at, title, category_id )
values ($1, $2, $3, $4, $5)
on conflict(stream_id) do update set
${isLive ? 'started_at' : 'ended_at'} = $3`,
[
event.detail.stream_id,
channelId,
event.time,
channelResult.rows[0].title,
channelResult.rows[0]?.category_id || null,
]
);
Stream
to persist the recording_started_at
, the recording_path
, and the Channel
's title
at the time the recording began to the VOD recording for the given stream.💡 Note: Technically, theStream
should already exist (since it's created on theStream Start
event), but sometimes these events fire nearly simultaneously, so it's best to handle the possibility that aStream
might not exist yet when theRecording Start
event is handled.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
client.query(`
insert into streams (stream_id, channel_id, recording_started_at, title, recording_path)
values ($1, $2, $3, $4, $5)
on conflict(stream_id) do update set
recording_started_at = $3,
recording_path = $5`,
[
event.detail.stream_id,
channelId,
event.time,
channelResult.rows[0].title,
event.detail?.recording_s3_key_prefix,
]
);
Recording End
event fires, StreamCat finalizes the Stream
record to capture the recording_end_date
, recording_duration_ms
, and recording_path
.1
2
3
4
5
6
7
8
9
10
11
12
13
client.query(`
update streams set
recording_ended_at = $1,
recording_duration_ms = $2,
recording_path = $3
where stream_id = $4`,
[
event.time,
event.detail?.recording_duration_ms,
event.detail?.recording_s3_key_prefix,
event.detail.stream_id,
]
);
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.