Capturing the feed of a users camera can be a daunting undertaking involving one or multiple third party packages. Often we opt for prompting the user to upload the video or image we need, causing more steps for the user and a more difficult user experience. Luckily, there is a simple and easy solution for this scenario
What is WebRTC?
WebRTC (Web Real-Time Communication) is an open source technology released by Google in 2011. It enables Web applications and sites to capture and optionally stream audio and/or video media, as well as to exchange arbitrary data between browsers without requiring an intermediary. The set of standards that comprise WebRTC makes it possible to share data and perform teleconferencing peer-to-peer, without requiring that the user install plug-ins or any other third-party software.
There are many different use-cases for WebRTC, from basic web apps that uses the camera or microphone, to more advanced video-calling applications and screen sharing. We’ll be looking at one of the simpler use cases, streaming video in the browser
Getting started
For simplicity, we’ll just build our photo capture feature in a basic JavaScript application. We’ll start with our index.html
<!doctype html>
<html>
<head>
<title>WebRTC Starter</title>
</head>
<body>
<div style="flex-direction: column;align-items: center;display: flex;" id="root">
<video id="video" autoplay></video>
<button
style="margin: 2rem 0;height: 2rem; width: 8rem;"
type="button"
id="start-button">
Start Video
</button>
<button
hidden
style="margin: 2rem 0;height: 2rem; width: 8rem;"
type="button"
id="stop-button">
Stop Video
</button>
</div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
There’s a few things going on here but this is the most important part
<button
style="margin: 2rem 0; height: 2rem; width: 8rem;"
type="button"
id="start-button">
Start Video
</button>
<button
hidden
style="margin: 2rem 0;height: 2rem; width: 8rem;"
type="button"
id="stop-button">
Stop Video
</button>
<video id="video" autoplay></video>
We have a button that we want to click to start the video, a button that is hidden that we will use to stop our video, and the video element to render our WebRTC stream. Next we move on to our JavaScript implementation
The JavaScript
First we’ll set a few variables for interacting with our video and buttons
const startButton = document.getElementById('start-button')
const stopButton = document.getElementById('stop-button')
const video = document.getElementById('video')
Next, we’ll define a couple of functions for starting and stopping our video
const playVideo = () => {
startButton.hidden = true
stopButton.hidden = false
const constraints = {
video: {
width: 500,
height: 500
}
}
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
video.srcObject = stream
video.play()
})
.catch((err) => {
console.log(err);
})
}
const stopVideo = () => {
startButton.hidden = false
stopButton.hidden = true
video.srcObject = null
}
Let’s unpack these functions a little.
getUserMedia()
const playVideo = () => {
startButton.hidden = true
stopButton.hidden = false
const constraints = {
video: {
width: 500,
height: 500
}
}
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
video.srcObject = stream
video.play()
})
.catch((err) => {
console.log(err);
})
}
The first 2 lines are pretty clear. As we start the video we hide our start button and show out stop button. The real meat of this function is in the getUserMedia function.
getUserMedia is a function given to us by WebRTC to be called on a MediaDevices object, which we have accessed by using navigator.mediaDevices. It returns a Promise that resolves to a MediaStream object, and accepts an object of constraints for things such as height, width, etc, defined above.
When our Promise resolves, we set the srcObject of our video element to the returned MediaStream, and call the play() function. We should now see the video stream from our primary camera
Stopping the video
Now stopping the video becomes as simple as nulling out the srcObject on the video and changing which button is displayed
const stopVideo = () => {
startButton.hidden = false
stopButton.hidden = true
video.srcObject = null
}
That’s it! WebRTC gives us the power to capture camera feed from the browser, using very little code. Note that this does not account for specific behavior in other browsers. We’ll go over that in a later post