This is a demo showing how to use Chrome region capture api and how to integrate it with Qiniu RTC.
Key Steps
1. define crop region
This is simple. Just get target element and create a cropId.
const cropId = await navigator.mediaDevices.produceCropId(document.getElementById(id));
2. capture stream
Region capture is only supported in current tab stream, so we use the preferCurrentTab
option.
const stream = await navigator.mediaDevices.getDisplayMedia({
preferCurrentTab: true,
video: {
cursor: "always"
}
});
This will show a current tab option on the chrome native UI.
A extra check is needed to make sure the stream is current tab.
currentTabTrack.label.startsWith("current-web-contents-media-stream://")
3. crop a stream
After a stream is captured and we can crop a track with previous cropId.
await currentTabTrack.cropTo(cropIds.get(key));
4. publish
Track cropping will automatically change the content in track. No other operations are required.
await client.join(roomToken);
const track = QNRTC.createCustomVideoTrack({ mediaStreamTrack: currentTabTrack });
await client.publish(track);
demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://docs.qnsdk.com/qnweb-rtc.js"></script>
<title>Region Capture Demo</title>
<style>
body {
background-color: rgb(241, 238, 238);
margin: 2rem 0;
}
.main {
width: 80%;
margin: 0 auto;
padding: 2rem 1rem;
/* min-height: 100vh; */
box-sizing: border-box;
background-color: white;
}
.regions {
padding: 1rem 0;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
column-gap: 1rem;
}
.regions>div {
aspect-ratio: 4/3;
font-size: 2rem;
display: flex;
justify-content: center;
align-items: center;
}
.regions>div:nth-child(1) {
background-color: bisque;
}
.regions>div:nth-child(2) {
background-color: pink;
}
.regions>div:nth-child(3) {
background-color: rgb(28, 199, 28);
}
.control {
padding: 1rem 0;
display: grid;
grid-template-columns: 1fr;
justify-items: center;
}
#player {
width: 300px;
aspect-ratio: 4/3;
margin: 1rem 0;
background-color: lightgray;
}
</style>
</head>
<body>
<div class="main">
<div id="not-support" hidden>
<p>
Unsupported.
The Region Capture API has only been supported since chrome98 and can only be used when capture current tab
stream.
</p>
</div>
<div class="regions">
<div id="region-1">Region 1</div>
<div id="region-2">Region 2</div>
<div id="region-3">Region 3</div>
</div>
<div class="control">
<video id="player" autoplay></video>
<div>
<button onclick="captureSelectedTrack('region-1')">region-1</button>
<button onclick="captureSelectedTrack('region-2')">region-2</button>
<button onclick="captureSelectedTrack('region-3')">region-3</button>
<button onclick="captureSelectedTrack('original')">original</button>
</div>
</div>
</div>
<script>
console.log("current version", QNRTC.VERSION);
const roomToken = "your room token";
const client = QNRTC.createClient();
const videoPlayer = document.getElementById("player");
if (!navigator.mediaDevices.produceCropId) {
document.getElementById("not-support").hidden = false;
}
let currentTabTrack;
let cropIds = new Map();
async function init() {
for (const id of ["region-1", "region-2", "region-3"]) {
const cropId = await navigator.mediaDevices.produceCropId(document.getElementById(id));
cropIds.set(id, cropId);
}
console.log(cropIds);
}
init();
async function captureSelectedTrack(key) {
if (!currentTabTrack) {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
preferCurrentTab: true,
video: {
cursor: "always"
}
});
currentTabTrack = stream.getVideoTracks()[0];
if (!currentTabTrack.label.startsWith("current-web-contents-media-stream://")) {
currentTabTrack.stop();
currentTabTrack = undefined;
document.getElementById("not-support").hidden = false;
return;
}
videoPlayer.srcObject = stream;
currentTabTrack.onended = () => {
currentTabTrack = undefined;
videoPlayer.srcObject = null;
client.leave();
};
publish();
} catch (e) {
console.error(e);
return;
}
}
switch (key) {
case "original":
await currentTabTrack.cropTo("");
break;
case "region-1":
case "region-2":
case "region-3":
console.log(cropIds, cropIds.get(key));
await currentTabTrack.cropTo(cropIds.get(key));
break;
}
}
async function publish() {
await client.join(roomToken);
console.log("join room success");
const track = QNRTC.createCustomVideoTrack({ mediaStreamTrack: currentTabTrack });
await client.publish(track);
console.log("publish success");
}
</script>
</body>
</html>