in serverless/lambda/index.js [667:824]
N: stream ? String(stream.viewerCount) : String(0)
}
},
UpdateExpression: 'SET #IsLive = :isLive, #ChannelStatus = :channelStatus, #Viewers = :viewers',
ReturnValues: "ALL_NEW"
};
console.info("_updateDDBChannelIsLive > params:", JSON.stringify(params, null, 2));
const result = await ddb.updateItem(params).promise();
return result;
} catch (err) {
console.info("_updateDDBChannelIsLive > err:", err, err.stack);
throw new Error(err);
}
};
const _isLive = async (counter) => {
console.info("_isLive > counter:", counter);
const liveStreams = await ivs.listStreams({}).promise();
console.info("_isLive > liveStreams:", liveStreams);
if (!liveStreams) {
console.log("_isLive: No live streams. Nothing to check");
return;
}
const result = await ddb.scan({ TableName: CHANNELS_TABLE_NAME }).promise();
if (!result.Items) {
console.log("_isLive: No channels. Nothing to check");
return;
}
let len = result.Items.length;
while (--len >= 0) {
const channelArn = result.Items[len].ChannelArn.S;
console.log("_isLive > channel:", channelArn);
const liveStream = liveStreams.streams.find(obj => obj.channelArn === channelArn);
console.log("_isLive > liveStream:", JSON.stringify(liveStream, null, 2));
await _updateDDBChannelIsLive((liveStream ? true : false), result.Items[len].Id.S, liveStream);
}
};
exports.isLiveCron = async (event) => {
console.log("isLiveCron event:", JSON.stringify(event, null, 2));
// Run three times before the next scheduled event every 1 minute
const waitTime = 3 * 1000; // 3 seconds
let i = 0;
_isLive(i + 1); // run immediately
for (i; i < 2; i++) {
await new Promise(r => setTimeout(r, waitTime)); // wait 3 seconds
console.log("isLiveCron event: waited 3 seconds");
_isLive(i + 1);
}
console.log("isLiveCron event: end");
return;
};
/* EventBridge */
exports.customEventFromEventBridge = async (event) => {
console.log("customEventFromEventBridge:", JSON.stringify(event, null, 2));
const params = {
TableName: CHANNELS_TABLE_NAME,
Key: {
'Id': {
S: event.detail.channel_name
},
}
};
const channel = await ddb.getItem(params).promise();
console.log("customEventFromEventBridge > getChannel :", JSON.stringify(channel));
if (event.detail.event_name == "Stream Start") {
try {
await _updateDDBChannelIsLive(true, event.detail.channel_name);
return;
} catch (err) {
console.info("_customEventFromEventBridge > Stream Start > err:", err, err.stack);
throw new Error(err);
}
}
if (event.detail.event_name == "Stream End") {
try {
await _updateDDBChannelIsLive(false, event.detail.channel_name);
return;
} catch (err) {
console.info("_customEventFromEventBridge > Stream End> err:", err, err.stack);
throw new Error(err);
}
}
if (event.detail.recording_status == "Recording End") {
try {
console.log("customEventFromEventBridge > Recording End > getChannel :", JSON.stringify(channel));
let payload = {
id: event.detail.stream_id,
channelName: event.detail.channel_name,
title: channel.Item.Title.S,
subtitle: channel.Item.Subtitle.S,
length: msToTime(event.detail.recording_duration_ms),
createOn: event.time,
playbackUrl: `${STORAGE_URL}/${event.detail.recording_s3_key_prefix}/media/hls/master.m3u8`,
viewers: channel.Item.Viewers.N,
thumbnail: `${STORAGE_URL}/${event.detail.recording_s3_key_prefix}/media/thumbnails/thumb0.jpg`,
thumbnails: [
`${STORAGE_URL}/${event.detail.recording_s3_key_prefix}/media/thumbnails/thumb0.jpg`,
`${STORAGE_URL}/${event.detail.recording_s3_key_prefix}/media/thumbnails/thumb1.jpg`,
`${STORAGE_URL}/${event.detail.recording_s3_key_prefix}/media/thumbnails/thumb2.jpg`,
]
};
await _createDdbVideo(payload);
return;
} catch (err) {
console.info("_customEventFromEventBridge > Recording End > err:", err, err.stack);
throw new Error(err);
}
}
return;
};
/* PUT /Video/:id */
exports.putVideo = async (event) => {
console.log("putVideo:", JSON.stringify(event, null, 2));
if (!event.pathParameters.id) {
return response({ message: 'Missing id' }, 400);
}
try {
const payload = JSON.parse(event.body);
const params = {
TableName: VIDEOS_TABLE_NAME,
Key: {
'Id': {