```
Later, we will put click handlers on the start and stop buttons to call [`startStream`](/sdks/browser-sdk/video/room-session.md#startstream) and [`stopStream`](/sdks/browser-sdk/video/room-session-stream.md#stop) respectively. The [`startStream`](/sdks/browser-sdk/video/room-session.md#startstream) function is available on the Room Session object, so first we need to use the [`setupRoomSession`](/video/conference/technical-reference.md) callback function on the PVC to get that object. So, the `VideoConference` constructor at the end of the embed script should look like this:
```js
SignalWire.AppKit.VideoConference({
token: "vpt_40b...458",
setupRoomSession: setRoomSession,
});
```
We can then access `setRoomSession` in the external JavaScript file and use the Room Session object returned to set event listeners and click handlers. The JavaScript file will look something like this:
```js
let roomSession;
let stream;
const stopStream = () => {
if (stream) {
stream.stop();
}
};
const setRoomSession = (session) => {
roomSession = session;
roomSession.on("room.left", () => {
stopStream();
});
};
document.addEventListener("DOMContentLoaded", () => {
document.getElementById("rtmp-form").onsubmit = async (e) => {
e.preventDefault();
const url = document.getElementById("stream-url").value;
try {
stream = await roomSession.startStream({ url });
} catch (error) {
console.log(error);
alert(
"There was an error starting the stream. Please check your URL and try again."
);
}
};
document.getElementById("stop").onclick = (e) => {
e.preventDefault();
try {
stopStream();
} catch (e) {
console.log(e);
}
};
});
```
The full demo application has some cosmetic additions, but these two files are all you need to get an RTMP outbound stream set up from any application with an embedded PVC. You should be able to see your stream in the streaming service within a few seconds of pressing "Start Stream".
While this demo used a PVC, you can use the same methods on a video room without the prebuilt UI. For a complete guide on building video rooms without a prebuilt UI, see [Simple Video Demo](/video/getting-started/simple-video-demo.md). From there, you can add start and stop stream buttons and hook them up in the same way as above.
### Wrap up
We showed the options to configure an RTMP stream that allows you to stream the content of your video room to any compatible streaming service: the Dashboard UI, a POST request, or an SDK application is all you need.
### Resources
* [API Streams Reference](/rest/signalwire-rest/endpoints/video/list-streams-by-room-id)
* [SDK Streaming Demo](https://github.com/signalwire/guides/tree/main/Video/RTMP-Streaming)
* [SDK Streaming Reference](/sdks/browser-sdk/video/room-session-stream.md)
* [PVC Reference](/video/conference/technical-reference.md)
---
#### Switching Webcams or Microphones During a Call
SignalWire Video API allows you to host real-time video calls and conferences on your website. In this guide, we'll learn to allow users to change the camera and microphone that's being used in the call.
#### Getting Started[](#getting-started "Direct link to Getting Started")
It is very easy to switch between input devices once you have the SDK up and running. However, if you haven't yet set up a video conference project using the Video SDK, you can check out the [Simple Video Demo](/video/getting-started/simple-video-demo.md) guide first.
#### Getting a list of supported input devices[](#getting-a-list-of-supported-input-devices "Direct link to Getting a list of supported input devices")
First, we want to find out what devices are available as input. Getting the list of media devices is handled by the `WebRTC` object available via `SignalWire.WebRTC` from the SDK. The methods in the `WebRTC` allow you to get the list of microphones, cameras, and speakers.
##### Listing webcams[](#listing-webcams "Direct link to Listing webcams")
To get the list of connected devices that can be used via the browser, we use the `getCameraDevicesWithPermissions()` method in `WebRTC`. The method returns an array of [InputDeviceInfo](https://developer.mozilla.org/en-US/docs/Web/API/InputDeviceInfo) object, each of which have two attributes of interest to us here: `InputDeviceInfo.deviceId` and `InputDeviceInfo.label`. The `label` will be used to refer to the webcam via the UI, and looks like 'Facetime HD Camera' or 'USB camera'. The `deviceId` is used in your code to address a particular device.
```javascript
const cams = await SignalWire.WebRTC.getCameraDevicesWithPermissions();
cams.forEach((cam) => {
console.log(cam.label, cam.deviceId);
});
```
##### Listing microphones[](#listing-microphones "Direct link to Listing microphones")
Exactly as with `getCameraDevicesWithPermissions()`, we can use the `getMicrophoneDevicesWithPermissions()` to get a list of allowed microphones.
```javascript
const mics = await SignalWire.WebRTC.getMicrophoneDevicesWithPermissions();
mics.forEach((mic) => {
console.log(mic.label, mic.deviceId);
});
```
#### Changing webcams and microphones[](#changing-webcams-and-microphones "Direct link to Changing webcams and microphones")
Once you have set up the video call with `SignalWire.Video.joinRoom()` or equivalent methods, we can use `Room.updateCamera()` and `Room.updateMicrophone()` to change devices.
As a simplified example:
```javascript
const roomSession = new SignalWire.Video.RoomSession({
token,
rootElement: document.getElementById("root"), // an html element to display the video
iceGatheringTimeout: 0.01,
requestTimeout: 0.01,
});
try {
await roomSession.join();
} catch (error) {
console.error("Error", error);
}
const cams = await SignalWire.WebRTC.getCameraDevicesWithPermissions();
const mics = await SignalWire.WebRTC.getMicrophoneDevicesWithPermissions();
// Pick the first camera in the list as the new video input device
roomSession.updateCamera({
deviceId: cams[0].deviceId,
});
// Pick the first microphone in the list as the new audio input device
roomSession.updateMicrophone({
deviceId: mics[0].deviceId,
});
```
*Note that you don't explicitly have to update camera and microphone. SignalWire Video SDK chooses the preferred input devices by default on setup. Only `updateCamera` or `updateMicrophone` when you want to switch to a non-default device.*
---
#### Video Overlays
SignalWire renders the video of your room in the cloud. This means that everyone sees the same content, and you could have a virtually unlimited number of connected users: the network link between your computer and SignalWire's server will only need to carry a single video stream, no matter what.
To give your clients metadata about the position of the different video members within the cloud-rendered video stream, SignalWire APIs support the concept of *layers*. In a few words layers indicate, at any instant of time, the semantic content of each portion of the video stream.
We can use this information for example to show the name of a member whenever the user hovers its mouse over it, and much more. In this demo app, we will just show how to display a selection indicator as follows:

#### Frontend[](#frontend "Direct link to Frontend")
We will make all our changes to the `