Learn Azure Communication Services Day 14 – Showing Video and Screen Share Content
This blog post is part of a series called “Learn ACS“, all about Microsoft Azure Communication Services. The series covers a high-level overview of capabilities and considerations, then dives into the development detail of using ACS in your application. Find the rest of the posts in the series at learnACS.dev.
Yesterday we looked at Call.remoteParticipants as a way to build and manage a participant list, and today we’re going to continue with using that array to get access to the video streams of each participant.
Video and Content Share streams are provided for each participant in a call or meeting. There isn’t a single “mixed” stream of participant video. This is either a good thing or a bad thing, depending on what you are trying to do. It gives the greatest flexibility for the widest range of applications because as a developer you have the choice of what video feeds to display when. However, if you’re looking for single video feed to represent the active speaker, that’s something you will need to implement yourself. (totally doable using the isSpeaking property of the remoteParticipant but outside the scope of this blog post).
From a developer perspective, both video and content-sharing streams are the same. They are both streams in the remoteParticipant.videoStreams array, they have the same properties, methods and events and you work with them in the same way. (Painting the stream onto the page is exactly the same as for the local video stream we covered in Day 10.)
Each RemoteVideoStream has a isAvailable property and a isAvailableChanged event you can use to know when there’s something to display. In fact, the only way to tell video and content streams apart is by the mediaStreamType property: for video, the value is “Video” and for content, it’s “ScreenSharing”.
Putting together a production-ready solution that incorporates both video and screen sharing can be a little tricky because it’s necessary to subscribe to the availability of both streams for each participant, as well as keeping track of participants leaving and joining to make sure you add new event handlers for new people. For that reason, today’s sample is deliberately simplified and does NOT use any events. Instead, there’s a Refresh button that takes the current state of all participants and display any available streams. It’s based on joining a Teams meeting to make it easier to test.
Here’s the code: don’t forget, on Line 19, replace the placeholder text with the full URL of your Azure Function created in Day 3, including the code parameter:
Testing it out
Similar to previous days, this one is relatively straightforward to test out. As before, use a command-line to run this command then browse to the sample application in your browser (usually http://localhost:8080):
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Try joining a Teams meeting with at least one participant that is showing video and/or content. Once the ACS client has connected to the meeting, click the Refresh Remote Media button.
What’s the code doing?
As I said earlier, this sample is deliberately simplistic in not using any events. Instead, everything happens on the click of the Refresh button (line 78). I build up a collection of divs that contain the stream content each time, tearing down the previous ones before I start. Then, for each participant, I identify both the video and content-sharing streams (lines 99/100). These streams are always there, even if no video or content sharing is happening. I look at the isAvailable property and if it’s true, render the stream by creating a view and appending it to one of the divs that hold the stream content.
Today, we showed video and content sharing from other remote participants. Tomorrow is all about Chat. Links for all blog posts can be found at learnACS.dev. You can also subscribe to my YouTube channel for videos about ACS (and much more!).