N: stream ? String()

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': {