* 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:
Xuezhou Dai 2023-06-01 17:51:54 +08:00 коммит произвёл GitHub
Родитель ee2c6fcad0
Коммит 961028b1bf
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 176 добавлений и 0 удалений

Просмотреть файл

@ -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.

Двоичные данные
api-samples/tabCapture/icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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
});
});