Add tabCapture sample (#933)
* Add tabCapture sample * Add README * Update receiver.html * Fix variable loss caused by idle * Use windows.create * Remove unnecessary logs * Update README * Update api-samples/tabCapture/README.md Co-authored-by: Oliver Dunk <oliver@oliverdunk.com> * Update api-samples/tabCapture/README.md Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> * Update api-samples/tabCapture/README.md Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> * Update api-samples/tabCapture/README.md Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> * Rename background.js * Remove unnecessary async function * Move the script to the body * Update api-samples/tabCapture/README.md Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> * Update README.md * Update api-samples/tabCapture/manifest.json Co-authored-by: Oliver Dunk <oliver@oliverdunk.com> --------- Co-authored-by: Oliver Dunk <oliver@oliverdunk.com> Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com>
This commit is contained in:
Родитель
ee2c6fcad0
Коммит
961028b1bf
|
@ -0,0 +1,21 @@
|
|||
# chrome.tabCapture
|
||||
|
||||
A sample that demonstrates how to use the [`chrome.tabCapture`](https://developer.chrome.com/docs/extensions/reference/tabCapture/) API.
|
||||
|
||||
## Overview
|
||||
|
||||
In this sample, the `chrome.tabCapture` API captures the contents of the active tab. The captured stream is displayed in a new window.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Use [`tabCapture.getMediaStreamId`](https://developer.chrome.com/docs/extensions/reference/tabCapture/#method-getMediaStreamId) to capture specific tabs.
|
||||
|
||||
The `targetTabId` and `consumerTabId` are obtained in the Service Worker, and then passed to the receiver page through the [`tabs.sendMessage`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-sendMessage) method.
|
||||
|
||||
See the [Audio recording and Screen capture guide](https://developer.chrome.com/docs/extensions/mv3/screen_capture/#audio-and-video) for a more detailed implementation.
|
||||
|
||||
## Running this extension
|
||||
|
||||
1. Clone this repository.
|
||||
2. Load this directory in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked).
|
||||
3. Click the extension's action icon.
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 3.0 KiB |
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Tab Capture Example",
|
||||
"description": "Capture a tab and play in a <video> element in a separate window.",
|
||||
"version": "1",
|
||||
"manifest_version": 3,
|
||||
"action": {
|
||||
"default_icon": "icon.png"
|
||||
},
|
||||
"background": {
|
||||
"service_worker": "service-worker.js"
|
||||
},
|
||||
"permissions": ["tabs", "tabCapture"]
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<!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" />
|
||||
<title>receiver</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="echo-msg"></p>
|
||||
<video id="player" width="100%"></video>
|
||||
<script src="./receiver.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,91 @@
|
|||
let currentStream = null;
|
||||
|
||||
function printErrorMessage(message) {
|
||||
const element = document.getElementById('echo-msg');
|
||||
element.innerText = message;
|
||||
console.error(message);
|
||||
}
|
||||
|
||||
// Stop video play-out and stop the MediaStreamTracks.
|
||||
function shutdownReceiver() {
|
||||
if (!currentStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
const player = document.getElementById('player');
|
||||
player.srcObject = null;
|
||||
const tracks = currentStream.getTracks();
|
||||
for (let i = 0; i < tracks.length; ++i) {
|
||||
tracks[i].stop();
|
||||
}
|
||||
currentStream = null;
|
||||
}
|
||||
|
||||
// Start video play-out of the captured MediaStream.
|
||||
function playCapturedStream(stream) {
|
||||
if (!stream) {
|
||||
printErrorMessage(
|
||||
'Error starting tab capture: ' +
|
||||
(chrome.runtime.lastError.message || 'UNKNOWN')
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (currentStream != null) {
|
||||
shutdownReceiver();
|
||||
}
|
||||
currentStream = stream;
|
||||
const player = document.getElementById('player');
|
||||
player.addEventListener(
|
||||
'canplay',
|
||||
function () {
|
||||
this.volume = 0.75;
|
||||
this.muted = false;
|
||||
this.play();
|
||||
},
|
||||
{
|
||||
once: true
|
||||
}
|
||||
);
|
||||
player.setAttribute('controls', '1');
|
||||
player.srcObject = stream;
|
||||
}
|
||||
|
||||
function testGetMediaStreamId(targetTabId, consumerTabId) {
|
||||
chrome.tabCapture.getMediaStreamId(
|
||||
{ targetTabId, consumerTabId },
|
||||
function (streamId) {
|
||||
if (typeof streamId !== 'string') {
|
||||
printErrorMessage(
|
||||
'Failed to get media stream id: ' +
|
||||
(chrome.runtime.lastError.message || 'UNKNOWN')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.webkitGetUserMedia(
|
||||
{
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'tab', // The media source must be 'tab' here.
|
||||
chromeMediaSourceId: streamId
|
||||
}
|
||||
}
|
||||
},
|
||||
function (stream) {
|
||||
playCapturedStream(stream);
|
||||
},
|
||||
function (error) {
|
||||
printErrorMessage(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (request) {
|
||||
const { targetTabId, consumerTabId } = request;
|
||||
testGetMediaStreamId(targetTabId, consumerTabId);
|
||||
});
|
||||
|
||||
window.addEventListener('beforeunload', shutdownReceiver);
|
|
@ -0,0 +1,36 @@
|
|||
async function closePrevReceiverTab() {
|
||||
const tabs = await chrome.tabs.query({
|
||||
url: chrome.runtime.getURL('receiver.html')
|
||||
});
|
||||
|
||||
await Promise.all(tabs.map((tab) => chrome.tabs.remove(tab.id)));
|
||||
}
|
||||
|
||||
chrome.action.onClicked.addListener(async (tab) => {
|
||||
const currentTabId = tab.id;
|
||||
|
||||
await closePrevReceiverTab();
|
||||
|
||||
// Open a new tab with the receiver.html page
|
||||
const { tabs } = await chrome.windows.create({
|
||||
url: chrome.runtime.getURL('receiver.html')
|
||||
});
|
||||
|
||||
const receiverTabId = tabs[0].id;
|
||||
|
||||
// Wait for the receiver tab to load
|
||||
await new Promise((resolve) => {
|
||||
chrome.tabs.onUpdated.addListener(function listener(tabId, info) {
|
||||
if (tabId === receiverTabId && info.status === 'complete') {
|
||||
chrome.tabs.onUpdated.removeListener(listener);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Send a message to the receiver tab
|
||||
chrome.tabs.sendMessage(receiverTabId, {
|
||||
targetTabId: currentTabId,
|
||||
consumerTabId: receiverTabId
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче