Skip to content

An interactive broadcasting experience using Amazon Chime and AWS Elemental

License

Notifications You must be signed in to change notification settings

aws-samples/amazon-chime-live-events

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Amazon Chime SDK Meeting with Live Connector

This demo will deploy several components to be used to create an Amazon Chime SDK Meeting and use the Amazon Chime SDK media live connector to stream to a Real-Time Messaging Protocol (RTMP) endpoint. In this demo, we will use Amazon Interactive Video Service as the RTMP endpoint.

Overview

AmazonChimeSDKMeetingWithLiveConnector

This demo will use serverless components to host a React based site the user is able to interact with through an AWS API Gateway to an AWS Lambda function. This AWS Lambda function will control the meeting through calls to the AWS SDK.

Creating and Joining an Amazon Chime SDK Meeting

Once deployed, you can click the Join button to join the meeting.

JoinMeeting

This will invoke the included AWS Lambda function to create and join the meeting.

async function meetingRequest() {
  const currentMeetings = await checkForMeetings();
  if (currentMeetings) {
    for (let meeting of currentMeetings) {
      if (meeting.joinInfo.Attendee.length < 2) {
        console.log(`Adding an attendee to an existing meeting: ${meeting.meetingId}`);
        const attendeeInfo = await createAttendee(meeting.meetingId);
        console.log(`attendeeInfo: ${JSON.stringify(attendeeInfo)}`);
        meeting.joinInfo.Attendee.push(attendeeInfo.Attendee);
        await putMeetingInfo(meeting.joinInfo);

        const responseInfo = {
          Meeting: meeting.joinInfo.Meeting,
          Attendee: attendeeInfo.Attendee,
        };

        response.statusCode = 200;
        response.body = JSON.stringify(responseInfo);
        console.info('joinInfo: ' + JSON.stringify(response));
        return response;
      }
    }
  }

This function will first check to see if there are any existing meetings. If there is, it will look for a meeting with fewer than two people. If there is one, an attendee will be created in the meeting and the information passed back to the user.

  const meetingInfo = await createMeeting();
  if (meetingInfo && meetingInfo.Meeting && meetingInfo.Meeting.MeetingId) {
    const attendeeInfo = await createAttendee(meetingInfo.Meeting.MeetingId);
    if (attendeeInfo && attendeeInfo.Attendee) {
      const joinInfo: JoinInfo = {
        Meeting: meetingInfo.Meeting,
        Attendee: [attendeeInfo.Attendee],
      };
      await putMeetingInfo(joinInfo);

      const responseInfo = {
        Meeting: meetingInfo.Meeting,
        Attendee: attendeeInfo.Attendee,
      };

      response.statusCode = 200;
      response.body = JSON.stringify(responseInfo);
      console.info('joinInfo: ' + JSON.stringify(response));
      return response;
    }
  }
  response.statusCode = 503;
  return response;
}

If there is not a meeting available, a new meeting and attendee will be created. This information is captured and returned to the user that will be used to join the meeting.

Creating an IVS Channel and Amazon Chime SDK media live connector pipeline

Once the meeting has started, the Amazon Chime media live connector stream can be created.

StartStream

async function createStream(meetingId: string) {
  const createChannelResponse: CreateChannelCommandOutput =
    await ivsClient.send(new CreateChannelCommand({ latencyMode: 'NORMAL' }));
  console.log(
    `createChannelResponse: ${JSON.stringify(createChannelResponse)}`,
  );
  if (
    createChannelResponse &&
    createChannelResponse.channel &&
    createChannelResponse.streamKey
  ) {
    createMediaLiveConnectorPipelineCommandInput!.Sources![0]!.ChimeSdkMeetingLiveConnectorConfiguration!.Arn = `arn:aws:chime::${awsAccountId}:meeting:${meetingId}`;
    createMediaLiveConnectorPipelineCommandInput!.Sinks![0]!.RTMPConfiguration!.Url = `rtmps://${createChannelResponse.channel.ingestEndpoint}:443/app/${createChannelResponse.streamKey.value}`;

    console.log(
      `CreateMediaLiveConnectorPipelineCommandInput: ${JSON.stringify(
        createMediaLiveConnectorPipelineCommandInput,
      )}`,
    );

The first step is to create an IVS Channel. We will use the information from the response when creating the media live connector pipeline in the next step.

const createPipelineResponse: CreateMediaLiveConnectorPipelineCommandOutput =
  await chimeSdkMediaPipelineclient.send(
    new CreateMediaLiveConnectorPipelineCommand(
      createMediaLiveConnectorPipelineCommandInput,
    ),
  );
console.log(
  `CreatePipelineResponse: ${JSON.stringify(createPipelineResponse)}`,
);

Using the information from the IVS Channel creation, we will use `CreateMediaLiveConnectorPipelineCommand to create the Amazon Chime SDK media live connector. The source for this media live connector will be the previously created meeting. The sink for this media live connector will be the RTMPS endpoint of the IVS channel.

    if (
      createPipelineResponse &&
      createPipelineResponse.MediaLiveConnectorPipeline
    ) {
      const getStreamResponse: GetStreamCommandOutput | null =
        await checkForStream(createChannelResponse);
      console.log(`getStreamResponse: ${JSON.stringify(getStreamResponse)}`);
      if (getStreamResponse && getStreamResponse.stream) {
        response.body = JSON.stringify({
          mediaPipelineId:
            createPipelineResponse.MediaLiveConnectorPipeline.MediaPipelineId,
          playbackUrl: getStreamResponse.stream.playbackUrl,
        });

        response.statusCode = 200;
        console.info('streamInfo: ' + JSON.stringify(response));
        return response;
      }
    }
  }
  response.statusCode = 503;
  return response;
}

Once the media live connector has been configured to use the IVS channel, we can use GetStreamCommand to get the playbackUrl that will be used to view the IVS stream. This information is passed back to the user so that they can view the broadcast.

ViewStream

Service-Linked Role

A service linked role is required for this deployment.

If this does not already exist in your account, you can run:

aws iam create-service-linked-role --aws-service-name mediapipelines.chime.amazonaws.com

Components Deployed

  • AWS Lambda Function
  • Amazon DynamoDB Table
  • Amazon Cloudfront Distribution
  • Amazon Simple Storage Service (S3) Bucket
  • Amazon API Gateway

Deployment

To deploy this demo:

yarn launch

The output of this deployment will include an Amazon Cloudfront Distribution that can be used. This demo also includes the ability to run locally:

cd site
yarn && yarn run start

Clean Up

To remove the components created:

yarn cdk destroy

Note on Repo Update

Previously, this repo contained a much different deployment based on an older technique. That repo is still available in the master branch. Going forward, updates will be applied to the main branch using the new features.

About

An interactive broadcasting experience using Amazon Chime and AWS Elemental

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published