Amazon Interactive Video Service (Amazon IVS) provides a managed platform on which to build engaging live streams and interactive video experiences without having to worry about the underlying infrastructure.
One can imagine all of the many use cases for Amazon IVS, from gaming to live events. When we took it for a spin, we focused on creating a dynamic and engaging online shopping experience with the addition of live streaming. We took this a step further by adding more seller-features like QR codes and images. That code can be found in an upcoming blog post on the AWS site.
In the meantime, this post will show you how to add live streaming to any web application using Amazon IVS. Our example uses the low-latency offering that supports millions of users. AWS recently announced a real-time option (built on WebRTC!) for instant content delivery. It supports up to 12 hosts and 10,000 viewers, all with a remarkable latency of less than 300 milliseconds. We can’t wait to test this new option out!
The public code repository available at Github shows the capabilities we’ve enabled in this post plus the enhanced features in the AWS post. The examples there are written in Typescript using the Next.js framework, but the concepts are applicable to any kind of web application.
Prerequisites
You’ll need the following resources:
- Ingest Server, Stream Key and Playback URL values from an Amazon IVS Channel
- Chat Messaging Endpoint value from an Amazon IVS Chat Room
- Either a pair of Amazon IVS Chat Tokens or a backend service that generates these dynamically
Installing The Amazon IVS Broadcast SDK
The first step is to install the Amazon IVS Broadcast SDK. Once installed, make sure that you import the library dynamically, as outlined on the IVS FAQs page.
Next, initialize the Amazon IVS Broadcast client instance configuring the stream settings, including max resolution and frame rate. These settings must correspond with those chosen during the channel’s creation process.
The resulting client instance is stored as a reference in the React component, as shown below:
// initializing broadcast client instance
const IVSClient = IVSBroadcastClient.create({
// setting stream configuration using a preset
streamConfig: IVSBroadcastClient.STANDARD_LANDSCAPE,
})
// storing the client in a ref object
client.current = IVSClient
Setting up a Stream Preview
The next step is to add a preview of the video and audio sent to IVS, and render it in the browser. To do so, simply attach the reference of an HTMLCanvasElement
object to the client.
// reference of the canvas element
const canvasRef = useRef<HTMLCanvasElement>(null)
// attachment of the canvas element reference to the SDK client
client.current.attachPreview(canvasRef.current)
Adding Streams to the Client
Now you need to send the media streams to Amazon IVS. To do so we need to:
- List the available devices using the getMediaDevices function
- Use getUserMedia to get the streams
- Add the streams to the SDK client
We add the video stream to the client as a “layer” by specifying a unique name for it and a set of parameters that include height, width and an “index”. The index specifies the layer position relative to other layers. The complete list of parameters can be found at IVS Web Broadcast documentation.
// get the video stream using getUserMedia
const videoStream = await navigator.mediaDevices.getUserMedia({
video: {
// get video from a specific device
deviceId: { exact: params.device.deviceId }
// the rest of constraints
...
}
})
// add the stream to IVS by specifying the stream, a layer name and
// the rest of params
client.addVideoInputDevice(
videoStream,
params.name,
params
)
This logic lives in its own custom React hook for video devices. There is also a custom React hook for audio devices that is similar, but only the actual stream and a device name are required when adding audio devices to the SDK client, as follows:
// add the stream to IVS by specifying the stream and a device name
await client.addAudioInputDevice(audioStream, name)
With the above in place, now you can list the devices and leverage the newly created hooks to add the streams to IVS. Calling these is fairly simple, you set the parameters required by each one and then call their exposed methods.
For video streams, required parameters are the selected device, a name and index for the video “layer”, track status (enabled o disabled), its position (x and y) and size (width and height).
// get the dimensions of the canvas for stream preview
const canvas = client.current.getCanvasDimensions()
// get the active/selected device stored in a reference
const deviceToAdd = activeVideoDevice.current
// set the parameters
const params: Layer = {
device: deviceToAdd as MediaDeviceInfo,
name: CAM_LAYER_NAME,
index: 4,
enabled: true,
x: 0,
y: 0,
width: canvas.width,
height: canvas.height
}
// calling the hook
addLayer(params, client.current)
Calling the hook for audio is similar, differing only in the parameters which are: a name for the stream, the device and track status.
// set the params
const params: AudioDevice = {
name: MIC_LAYER_NAME,
device: activeAudioDevice.current as MediaDeviceInfo,
enabled: true,
}
// call the function
addVideoDevice(params, client.current)
Starting the Stream
With all these pieces in place, it’s time to start the stream! To do so, we just need to pass the ingestServer to the client and then call the startBroadcast
method passing the streamKey.
// set the ingest server for the channel
client.config.ingestEndpoint = ingestServer
// start broadcast
await client.startBroadcast(streamKey)
Stopping the stream is all matter of calling stopBroadcast
method from the SDK client as follows:
await client.stopBroadcast()
This logic also lives in its own custom React hook for managing the stream.
Viewing the Stream
So far, your stream is viewable at the playback URL that was assigned when your Amazon IVS channel was created. Such a URL can be added to a multimedia player such as VLC or mplayer and that’s it. Let the Live Selling begin!
To make it easier for your audience to view the stream without having to configure anything, you can set up a player within your application. This can be easily done using the Amazon IVS Player SDK.
To do so, start by adding the amazon-ivs-player library. This library allows you to create a Player object that you can attach an HTMLVideoElement to. The required list of steps to configure the player are the following:
- Set the initial state of the player in the React Component.
- Create a player by calling the create function from the library. Store it as a reference.
- Attach a video element to the player. Store this as a reference too.
- Add any required event listener to the player.
- Load the stream using the Playback URL from the Amazon Channel.
- Set player properties such as its volume or whether it should automatically start playing after retrieving the stream.
These steps are shown in the code example below. For demonstration purposes, a dummy event for when the stream ends has been added. The complete list of events are available at the library’s documentation page.
<Script
src="https://player.live-video.net/1.19.0/amazon-ivs-player.min.js"
strategy="afterInteractive"
onLoad={() => {
// get the library instance
const IVSPlayerPackage = window.IVSPlayer
// get an enum for different states of the player
const { PlayerState } = IVSPlayerPackage
// 1. Set the initial state of the player
setPlayerState(PlayerState.IDLE)
// 2. Create a player by calling the create function
// Store it as a reference
player.current = IVSPlayerPackage.create()
// 3. Attach the reference of a video element to the player
player.current.attachHTMLVideoElement(
videoRef.current as HTMLVideoElement
)
// 4. Add any required event listener to the player
// Ended stream event for demo purposes.
player.current.addEventListener(PlayerState.ENDED, () =>
setPlayerState(PlayerState.ENDED)
)
// 5. Load the stream using the playback URL
// Replace placeholder by your actual url
player.current.load('your-playback-Url-here')
// 6. Set player properties
player.current.setAutoplay(true)
player.current.setVolume(0.5)
}}
/>
Implementing Live Chat using Amazon IVS Chat
Another important element in an engaging Live Selling stream is chat. Through chat, sellers can directly interact with their audience, gaining valuable insights and feedback on their products.
Amazon IVS allows you to easily add chat capabilities to your application. To do so, start by creating a Chat Room and generating access tokens for your participants. Ideally, such tokens are created on a server side application with proper security and authentication mechanisms. The development of such an application is outside the scope of this post.
After creating the Chat Room and retrieving tokens in your application, it’s all just a matter of creating a websocket connection -authenticated using the token- to the Chat Room Endpoint. Once connected, you can actively listen for incoming messages and send new ones as needed.
// create the websocket connection
connection.current = new WebSocket(chatMessagingEndpoint, chatToken)
// set up event listener for new messages
// new messages are stored in the state
Connection.current.onmessage = (e) => {
const data = JSON.parse(e.data)
setMessages(prevState => [...prevState, { text: data.Content }])
}
Sending messages to the chat is the same as sending a message through the websocket connection.
// prepare the message as required by Amazon IVS
const payload = {
Action: 'SEND_MESSAGE',
Content: text
}
// set the right type for connection variable to make Typescript happy
const con = connection.current as WebSocket
// send the message
con.send(JSON.stringify(payload))
The above logic lives in a custom React hook for chat.
Our live streaming application built with Amazon IVS is complete!
Amazon IVS is an easy way to add scalable and powerful live streaming capabilities to any application, allowing you to create engaging and dynamic live selling experiences for your viewers. If you want to know how to take this experience to the next level, check out the next part of this post in Amazon’s blog.
Are you ready to add live streaming capabilities to your application? WebRTC.ventures is part of the Amazon Partner Network, a global community of developers who have met a vigorous set of criteria set by AWS, including knowledge, experience, and customer success requirements. Contact us today and take advantage of our expertise in all things AWS, including Amazon IVS!