Amazon IVS UGC platform web demo
A demo web application intended as an educational tool for demonstrating how you can use Amazon IVS, in conjunction with other AWS services, to create a full-featured User-Generated Content (UGC) platform with user authentication, live video playback, live chat, interactive virtual experiences, stream monitoring, and more.
This demo uses AWS Cloud Development Kit (AWS CDK v2).
This project is intended for educational purposes only and not for production usage.
Prerequisites
- AWS CLI (Installing the AWS CLI version 2)
- NodeJS (Installing Node.js)
- Docker (Installing Docker)
To use and deploy this project
IMPORTANT NOTE: this demo will create and use AWS resources on your AWS account, which will cost money.
Deploying the CDK stack will:
- create a Cognito User Pool to handle user sign-up and authentication
- create three Cognito triggers implemented with Lambda functions that are required for the user management flows
- create two DynamoDB tables to hold channels and stream metrics data
- create an Application Load Balancer and ECS Service that will act as the backend for the frontend application
- create a CloudFront distribution that sits in front of the backend service to handle incoming traffic from clients
- create an API Gateway, a Network Load Balancer and an ECS Service to handle EventBridge Amazon IVS events and store them in the Metrics DynamoDB table
- create an EventBridge rule to dispatch the Amazon IVS events to the aforementioned API Gateway
- create the Secrets Manager with the necessary secret(s) depending on the enabled features
Quick links 🔗
Architecture
Features
User Registration, Login and Password Reset using Amazon Cognito
New users can create an account from the /register
route. Returning users can login to their account from the /login
route. They can also reset their password at /reset
.
While no two accounts can share the same username and email, it is possible to create a new account with the same username and email after deleting the previous account.
On the first login, the required resources will be created on the backend and associated with the user account (each user gets their own IVS channel and IVS chatroom).
Channel page, with live video and chat
Each registered user has a channel page where viewers can watch the stream and chat together. The route for a channel page is based on the username, e.g.: /<username>
. Both authenticated and unauthenticated users can access a channel page.
GetChannelData
The playback URL and the streamer information are retrieved directly from the database.
“Follow” channels
Authenticated users can add or remove a channel from their following list by clicking the follow/unfollow button on a user’s channel of their choice. Unauthenticated users who click on the follow button are redirected to the login page to sign in or create a new account. Once logged in, the user is redirected back to the same channel page they were trying to follow earlier and the channel will be automatically followed for them on page load.
Stream chat
Each channel has a corresponding chat room which is accessible from the channel page.
Authenticated viewers are able to read and send messages. Unauthenticated users are only able to read messages. The owner of the channel can moderate their chatroom and delete messages or ban users from their channel.
Stream overlays
Streamers can trigger various stream overlays: host a quiz, feature a product, feature an Amazon product, show a notice and trigger a celebration. More information on how overlays are triggered by streamers is available here: Trigger overlays.
The stream actions are received by the viewers through the IVS Player using Timed Metadata.
Stream health monitoring
The Stream Health page is only accessible to authenticated users, from the /health
URL. It enables streamers to monitor live and past stream sessions. For each session, the page will show the stream events, the video bitrate and frame rate in the form of charts and a summary of the encoder configuration at the time of go-live. Learn more
Stream events
Stream events are being sent by EventBridge to a service that is responsible for storing them into the database. They are organized by stream session so they can easily be retrieved when a user monitors a specific stream session.
Stream metrics
The video bitrate, frame rate, concurrent views and keyframe interval metrics come from CloudWatch. For live sessions, the metrics are polled from CloudWatch at regular intervals and are not cached to ensure only the latest data is served. When monitoring an offline session, the metrics are fetched from CloudWatch and stored in the database so they can be retrieved faster.
Stream management
The stream management page is only accessible to authenticated users, from the /manager
URL. On this page, streamers can start a web broadcast, trigger stream overlays, as well as monitor and moderate their chat room. Users can also prepare and save stream overlay configurations for later use.
Web broadcast
Users are prompted to grant camera and microphone permissions when accessing the /manager
URL. The user must allow both the camera and microphone permissions to use this feature. Users can toggle their camera and microphone, and can also share their screen. Inside Settings, users can change the camera and microphone device used, and toggle the display of their camera when sharing their screen. Users can also enter a “full-screen” view while streaming.
Read more about the Amazon IVS Web broadcast SDK from the official SDK guide.
Read about web broadcast known issues and limitations.
Chat monitoring
The chat component on this page works exactly like the chat component from the Channel page. More information and an architecture diagram are available in the corresponding section)
Stream overlay configuration
Streamers can trigger overlays. Only one stream action can be active at a time. A stream action will remain active until the action expires, until it is stopped or until it is replaced by a different action.
The stream actions are sent to viewers using the PutMetadata Endpoint.
Settings
From the settings page (/settings
), registered users can select a profile color, change their avatar and profile banner, get and update their account information or delete their account. Deleting an account will delete its associated resources (IVS channel and IVS chat room). A “Go live from web” button in the stream settings section allows for quick access to the stream manager page, where users can start their live stream.
Get and Update User Information
All the user information is stored in the database. The data is retrieved or updated using the regular authenticated flow through the Cognito authorizer and then by a container calling the database.
Directory
The directory page (/
) is where all users can view the 50 most recent live streams, while authenticated users will also be able to see up to 14 of the channels they follow in a carousel. Within the following list, the live channels appear first and are sorted in order of most recent start time. The offline channels follow after the live channels and are sorted in order of most recently added.
Following
Authenticated users have a following page (/following
) where they can view the channels they are following, along with the live status of each channel.
Get and update following list
Each registered user has a following channels list that is stored in the database and contains the channel IDs of the channels the user follows. When a user follows or unfollows a channel, the database is updated to reflect the change by adding or removing the respective channel ID from the list. The data is retrieved or updated using the regular authenticated flow through the Cognito authorizer and then by a container calling the database.
Configuration
The cdk/cdk.json
file provides two configuration objects: one for the dev
stage and one for the prod
stage. The configuration object (resourceConfig
property) for each stage is set with sensible defaults but can be edited prior to deploying the stack:
-
allowedOrigins
is a list of origins (domain names) that the backend uses as the value for theAccess-Control-Allow-Origin
HTTP response header. This property is required in order for browsers to allow the requesting code (frontend application) running at an allowed origin domain to access our backend resources. You can use custom domains, or specify["*"]
to allow all origins. To follow best security practices in a production environment, it is recommended to set this value to the domain(s) where you intend to deploy the frontend application. -
clientBaseUrl
should be set to the base URL of the frontend application. This URL is used for sending verification emails with links that redirect the user back to the frontend application to complete the verification process. -
deploySeparateContainers
, setting this totrue
will deploy the backend in two separate services, each one with the minimal required permissions. While being more costly, this option will scale better and is recommended for production. -
enableUserAutoVerify
, setting this totrue
is not recommended for production. It will skip the email verification when a new user signs up in the app. -
ivsChannelType
can be set toBASIC
orSTANDARD
. -
logRetention
is the number of days that the logs for the Cognito triggers will be kept. Omit this property to keep the logs forever. -
maxAzs
is the maximum number of availability zones (AZs) for the VPC in the region that the stack is deployed. Setting this value to the maximum number of AZs in your region will reduce the risk of the backend going offline but also increase the running cost. If you pick a number that is higher than the amount of AZs in your region, then all the AZs in the region will be used. Therefore, to use all “all AZs” available to your account, specify a high number for this property (such as 99). While it is possible to use 1 AZ, we recommend using a minimum of 2 AZs to take advantage of the safety and reliability of geographic redundancy (i.e. when one AZ becomes unhealthy or unavailable, the unaffected AZ will be used instead). -
minScalingCapacity
sets the lower limit of the number of tasks for Service Auto Scaling to use when running each of the backend services, ensuring that the backend services will not be automatically adjusted below this amount. You may increase this value if you’re expecting high traffic in production. Alternatively, if you know that the backend services may be idle for a long period of time and you want to optimize for costs, you may set this value to 1. -
natGateways
, at least one NAT Gateway is required for the tasks to fetch the Docker image from the ECR Repository. This value can be increased up to themaxAzs
value in production. -
signUpAllowedDomains
is a list of email domains that are allowed to be used when creating a new account in the app. An attempt to create an account with an email containing a domain that is not in this allowlist will be rejected. Setting this property to an empty list will allow all email domains to be used for account creation.Example:
"signUpAllowedDomains": ["example.com"]
-
enableAmazonProductStreamAction
as the name suggests, the value of this feature flag will either hide or show the Amazon Product stream action on the stream manager page. Setting the value to false will hide the stream action while setting the value to true will show the stream action. Please review “Configuring cdk.json to enable the Amazon Product stream action” under the guides section before setting a value.Note: updating this value will require a new stack deployment.
Example:
"enableAmazonProductStreamAction": true
-
productApiLocale
in order to start retrieving marketplace information for the Amazon Product stream action we must set aproductApiLocale
value. You will need to identify the locale in which your Associates account is registered to. For a list of supported locale values, please refer to the following link, https://webservices.amazon.com/paapi5/documentation/common-request-parameters.html.Associate accounts are registered to particular marketplaces, so attempting to access a locale to which you are not registered for will throw an error. Further, setting a locale that is incorrectly spelt, left blank or not supported will attempt to retrieve products from the US marketplace. If products are still not showing you can view the logs for further details.
Example:
"productApiLocale": "United States"
-
productLinkRegionCode
the region code set here is simply a suffix that is added to the end of your unique tracking id that will appear on every product link for monetizing purposes. It is a 2 digit code that appears at the end of your provided partnerTag as an Amazon Associate. For example, if your partnerTag (or store ID) is store-20. 20 is your region code (North America).By not setting a value and leaving it blank, you wish to not participate in the tracking and monetization of product affiliate links.
Note: The region code value should be surrounded by double quotes (ie. “20” not 20).
Example:
"productLinkRegionCode": "20"
Guides
Configuring cdk.json to enable the Amazon Product stream action
-
Before enabling this feature, you MUST have an Amazon Associates account that has been reviewed and received final acceptance into the Amazon Associates Program. If you do not have an Amazon Associate account, you must sign up for Amazon Associates. For more information, see Sign Up as an Amazon Associate
-
Once accepted, you may set the value of
enableAmazonProductStreamAction
to true. -
If true, you can proceed to identify the
productApiLocale
value. This value will be the locale to which your Associates account is registered to. For a list of supported locale values, please refer to the following link, https://webservices.amazon.com/paapi5/documentation/common-request-parameters.html.Associate accounts are registered to particular marketplaces, so attempting to access a locale to which you are not registered for will throw an error. Further, setting a locale that is incorrectly spelt, left blank or not supported will attempt to retrieve products from the US marketplace. If products are still not showing you can view the logs for further details.
-
(OPTIONAL) The last cdk.json value to identify is the
productLinkRegionCode
. Having a region code value set will determine whether or not your affiliate links can be tracked and monetized (see “How to monetize product affiliate links” for additional setup). It is a 2 digit code that appears at the end of your provided partnerTag as an Amazon Associate. So for example, if your partnerTag (or store ID) is store-20. 20 is your region code (North America). By leaving this value blank you are opting out of affiliate tracking and monetization.Note: the region code value should be surrounded by double quotes (ie. “20” not 20).
-
Below is what your cdk.json config should look like if you are looking to enable the Amazon product stream action and overlay, with a region (for product link monetization and tracking) and locale set to United States.
"enableAmazonProductStreamAction": true, "productApiLocale": "United States", "productLinkRegionCode": "20"
-
Once the application has been deployed, you must set credentials (provided by the Associate account) inside of the AWS Secrets Manager in order to retrieve product information from the Product Advertising API. For more details on setting your credentials see “Setting your Product Advertising API credentials” under this section.
Note: Failure to set your credentials or typing incorrect values will throw an error in the application when attempting to search Amazon products.
Setting your Product Advertising API credentials
To set your Product Advertising API credentials you must:
-
Locate the Secrets Manager in the AWS console (AWS Secrets Manager > Secrets)
-
Find the secret name of
ProductAdvertisingAPISecret
followed by a unique string that should have been generated on deployment and click it -
Scroll down the page and click “Retrieve secret value”
-
Click “Edit” and set your secretKey, accessKey and partnerTag (Store ID)
-
Click Save
How to monetize product affiliate links
After deployment, through Amazon OneLink, you can best earn money via product affiliate links by redirecting international traffic to the appropriate Amazon store for their location, increasing the likelihood that they will make a purchase. To get started:
-
Sign up for Amazon Associates: To use Amazon OneLink, you need to be an Amazon Associate. If you’re not already signed up, go to the Amazon Associates website and create an account.
-
Enable OneLink: Once you’ve signed up for Amazon Associates, navigate to the ‘Manage Tracking IDs’ section located at the top right-hand corner of the Amazon Associates portal.
- Then, click on the
Add Tracking ID
button located at the top of this section.
- To track a channel, you must first obtain the channel’s
trackingId
(ex. xzhsymq-20). To locate it, you can simply go to the channel’s DynamoDB table (in the AWS console) and locate the channel of interest. Within the same row, a trackingId should be provided.
-
Copy and paste the
trackingId
into Amazon OneLink. Note: the id is composed of the channel’s id followed by the region code (productLinkRegionCode) that was set on stack deployment. -
Paste in the tracking ID you retrieved from the DynamoDB table to enable OneLink for your account, then click
Create
.
-
Test your links (by clicking the Buy now button) to make sure they are redirecting to the correct Amazon store for the visitor’s location.
-
Monitor your earnings: Keep track of your earnings through the Amazon Associates dashboard. You can see how many clicks and purchases you’ve received from each Amazon store.
Deployment
IMPORTANT NOTE: Before setting up the backend, make sure that you have Docker running.
-
To set up the backend, navigate to the
cdk
directory and run:make app
This command will install dependencies, bootstrap the CDK assets (if needed), and finally deploy the stack. By default, the
make app
command will deploy the stack using thedev
stage configuration. To specify a different deployment stage, you will need to set theSTAGE
environment variable to either “dev” or “prod” in themake app
command. For instance, to deploy theprod
stage configuration, run the following command:make app STAGE=prod
Optionally, you may also specify the AWS named profile to use when deploying the stack using the
AWS_PROFILE
environment variable:make app AWS_PROFILE=user1
Additionally, you can also build and publish the frontend application to an S3 bucket with a CloudFront distribution as part of the same deployment by setting the
PUBLISH
flag totrue
:make app PUBLISH=true
Deploying with the
PUBLISH
flag set totrue
will also append the CloudFront distribution URL to the list ofallowedOrigins
defined in yourcdk.json
config. It will also override the value ofclientBaseUrl
.NOTE: the deployment might take up to 20 minutes or more if you are also publishing the frontend application.
-
Go to the
web-ui
directory and run the following commands to start the React frontend host:npm install npm start
Running make app
is only required when you deploy the stack for the first time. Subsequent re-deployments will run faster with the following command (be sure to specify the STAGE
value if you are deploying to a stage other than dev
):
make deploy STAGE=<stage>
If you have initially deployed the stack with the PUBLISH
flag set to true
, make sure to set it again, every time you re-deploy. If you don’t, the stack will take down the existing deployment.
Additionally, if you want to make changes to any of the stage configuration options after the stack has been deployed, you will need to re-deploy the stack in order for the changes to take effect. For instance, say that you deployed the stack under the prod
stage and then decided to update the allowedOrigins
value in the configuration options. After updating the cdk.json
file, you will then need to run the following command to re-deploy the prod
stack with the new changes:
make deploy STAGE=prod
Summary
The following recaps all the most common commands that you can run to easily deploy the app to AWS.
NOTE: if you are running the command for the first time, you need to replace deploy
with app
in the make
command.
Deploy the backend with the “dev” config:
make deploy
Deploy the backend and the frontend app with the “dev” config:
make deploy PUBLISH=true
Deploy the backend with the “prod” config:
make deploy STAGE=prod
Deploy the backend and the frontend app with the “prod” config:
make deploy STAGE=prod PUBLISH=true
Backend Specification
An in-depth specification of the backend API can be found in the Postman collection (cdk/postman), along with instructions on how to call each individual endpoint.
Backend Teardown
To avoid unexpected charges to your account, be sure to destroy the CDK stack when you are finished:
-
In the
cdk
directory, run:make destroy
This command will delete all the AWS resources that were created for this demo, with the exception of the Amazon IVS channels and Amazon IVS chat rooms. These Amazon IVS resources will have to be manually stopped, in the case of channels that are still live, and deleted from the AWS console. Any channels that remain in offline status or chat rooms that have not been deleted will not incur charges to your account.
Additionally, the make destroy
command will also run a clean-up process that will delete the cloud assembly directory (cdk.out
).
More information about all the available make
rules can be found by navigating to the cdk
directory and running:
make help
Testing
Two types of testing were incorporated into this demo: unit testing for the backend API and end-to-end testing for the React web app.
Backend Unit Testing
Unit testing is run on the backend API using Jest.
-
To run the backend unit tests, navigate to the
cdk/api
directory and run:npm run test
Currently, the backend unit testing suite covers only the metrics API and the buildServer.ts
file, while the channels API is only partially covered.
End-to-end Testing
End-to-end tests are written using the Playwright web testing framework, which allows us to run our tests across Chromium, Firefox and WebKit browsers, on both desktop and mobile.
-
To run the E2E tests, navigate to the
web-ui
directory and run:npm run test:e2e
Currently, the E2E testing suite covers only the most common user management flows.
Automated Testing
Testing is automated using two GitHub Actions workflows: one for running the backend unit tests (backend-unit-test-on-pull-request
) and another for running the E2E tests (e2e-test-on-pull-request
). Each workflow is configured to run on every pull request made to the master
branch. Additionally, to save on GitHub Actions execution minutes, the backend unit testing workflow is run only if changes were made to the files inside the cdk/api
directory, and the E2E testing workflow is run only if changes were made to the files inside the web-ui
directory. In the instance that the E2E workflow fails at the testing step, an artifact will be generated containing the playwright test report. These artifacts have a retention period of 7 days, after which they are automatically deleted from the workflow run results.
Limitations
-
Currently only tested in the us-west-2 (Oregon) and us-east-1 (N. Virginia) regions. Additional regions may be supported depending on service availability.
-
Backend: In the Metrics DynamoDB table, the metrics data is overwritten in order to decrease the resolution of the data as per the CloudWatch schedule
-
Backend: While this demo relies on EventBridge to gather information about a user’s stream(s), the streaming configuration details are still retrieved via the Amazon IVS API. Therefore, during high traffic conditions, these requests may be throttled once the quota limit is reached. From the users’ perspective, there may be a delay before the streaming configuration details are available; however this delay will only occur once per stream, as they are immediately saved in the DynamoDB table once retrieved via the Amazon IVS API.
-
Backend: By default, Cognito will send user account-related emails using a Cognito-hosted domain, which are limited to 50 emails / day per account. If you wish to increase the email delivery volume, you will need to configure your Cognito user pool to use Amazon SES configured with your own domain. For more information, see Email settings for Amazon Cognito user pools.
-
Backend: The ECS tasks that are deployed as part of the backend infrastructure require public internet access to fetch the corresponding Docker image from the ECR repository. To enable the ECS tasks to access the public internet, and therefore the ECR repository, we have to create NAT Gateways – 1 for dev and 2 for prod, by default – and associate them with a VPC. There is a limit of 5 NAT Gateways per availability zone. If your account is already at this limit, attempting to deploy the infrastructure for the demo will fail. To solve this issue, you can either remove unused NAT Gateways from the current region or deploy the stack in a different region by modifying the
cdk/bin/cdk.ts
file as follows:const region = <your-region-here>
Alternatively, you may also choose to request a quota increase for “NAT gateways per Availability Zone” and “VPCs per Region.”
-
Backend: The user registration flow involves the creation and coordination of multiple AWS resources, including the Cognito user pool, the Amazon IVS channel and chat room, and the DynamoDB channels table. This registration flow also includes important validation checks to ensure that the submitted data meets a set of constraints before the user is allowed to sign up for a new account. Therefore, we highly advise against creating or managing any user account from the AWS Cognito console or directly from the DynamoDB channels table as any such changes will be out of sync with the other user-related AWS resources. If at any point you see an error message pertaining to a manual change that was made from the AWS Cognito console (e.g. a password reset), a new account should be created using the frontend application’s dedicated registration page.
-
Web Broadcast: Currently set to 720p resolution to ensure best performance across a wide range of devices.
-
Web Broadcast: For other Amazon IVS Web Broadcast SDK known issues, please refer to the official SDK Guide.
-
iOS: devices do not currently support the fullscreen API, which prevents a fullscreen player experience that includes custom player controls and header.
-
iOS: the volume level of the video player is always under the user’s physical control and not settable using JavaScript.
-
PA API: When creating your Product Advertising API 5.0 credentials (for the Amazon Product stream action), you are allowed an initial usage limit up to a maximum of one request per second (one TPS) and a cumulative daily maximum of 8640 requests per day (8640 TPD) for the first 30-day period. This will help you begin your integration with the API, test it out, and start building links and referring products. Your PA API usage limit will be adjusted based on your shipped item revenue. Your account will earn a usage limit of one TPD for every five cents or one TPS (up to a maximum of ten TPS) for every $4320 of shipped item revenue generated via the use of Product Advertising API 5.0 for shipments in the previous 30-day period. Note: that your account will lose access to Product Advertising API 5.0 if it has not generated referring sales for a consecutive 30-day period.
See Api Rates for more information.
Estimated costs
For this estimation, we considered the usage costs associated with 1, 10 and 100 users, where each “user” is assumed to monitor one 4-hour live stream with 1 viewer. In each scenario, we assumed that there were no more than 10,800 chat messages sent by the end of the 4-hour stream. Additionally, the estimated costs below reflect the usage costs of running the production configuration of the CDK stack.
Overall pricing
Service | 1 user | 10 users | 100 users |
---|---|---|---|
API Gateway | <$0.01 | <$0.01 | <$0.01 |
CloudFront | <$0.01 | $0.04 | $0.38 |
CloudWatch | $0.29 | $2.90 | $29.00 |
Cognito | <$0.01 | $0.06 | $0.55 |
DynamoDB | <$0.01 | <$0.01 | <$0.01 |
Elastic Container Registry | <$0.01 | <$0.01 | <$0.01 |
Elastic Container Service | $0.13 | $0.13 | $0.13 |
EventBridge | <$0.01 | <$0.01 | <$0.01 |
Interactive Video Service | $8.60 | $86.00 | $860.00 |
Lambda | <$0.01 | <$0.01 | <$0.01 |
Total cost | $9.09 | $89.18 | $890.11 |
Additional pricing
Service | Description |
---|---|
Secrets Manager | $0.40 per secret per month. A |
replica secret is considered a | |
distinct secret and will also | |
be billed at $0.40 per replica | |
per month. For secrets that | |
are stored for less than a | |
month, the price is prorated | |
(based on the number of hours.) | |
$0.05 per 10,000 API calls |
About Amazon IVS
Amazon Interactive Video Service (Amazon IVS) is a managed live streaming solution that is quick and easy to set up, and ideal for creating interactive video experiences. Learn more.
- Amazon IVS docs
- User Guide
- API Reference
- Setting Up for Streaming with Amazon Interactive Video Service
- Learn more about Amazon IVS on IVS.rocks
- View more demos like this
License
This library is licensed under the MIT-0 License. See the LICENSE file.