test : stream cap
This commit is contained in:
79
tools/stream-capture/background.js
Normal file
79
tools/stream-capture/background.js
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copie les segments média que Firefox télécharge déjà, sans les redemander.
|
||||
*
|
||||
* `filterResponseData` donne accès au flux de réponse d'une requête que la page
|
||||
* a elle-même initiée. On lit les octets au passage et on les réécrit aussitôt
|
||||
* vers la page : le lecteur continue de fonctionner normalement, et l'extension
|
||||
* n'émet aucune requête vers la plateforme.
|
||||
*
|
||||
* C'est la différence avec un script qui irait rechercher le flux : ici on ne
|
||||
* fait que conserver ce que la session authentifiée a légitimement reçu.
|
||||
*/
|
||||
|
||||
const RECEIVER = 'http://127.0.0.1:8099/ingest';
|
||||
|
||||
// Playlists et segments servis par le CDN média de la plateforme.
|
||||
const MEDIA_PATTERN = /\.(m3u8|m4s|mp4|ts)(\?|$)/i;
|
||||
|
||||
let copied = 0;
|
||||
let failed = 0;
|
||||
|
||||
function updateBadge() {
|
||||
const text = failed ? `${copied}/${failed}!` : String(copied);
|
||||
browser.browserAction.setBadgeText({ text: copied || failed ? text : '' });
|
||||
browser.browserAction.setBadgeBackgroundColor({ color: failed ? '#b91c1c' : '#2563eb' });
|
||||
}
|
||||
|
||||
async function forward(url, chunks) {
|
||||
try {
|
||||
const blob = new Blob(chunks);
|
||||
const body = await blob.arrayBuffer();
|
||||
|
||||
await fetch(RECEIVER, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/octet-stream',
|
||||
'x-source-url': url,
|
||||
},
|
||||
body,
|
||||
});
|
||||
|
||||
copied += 1;
|
||||
} catch (err) {
|
||||
// Récepteur non lancé : on n'interrompt surtout pas la lecture pour autant.
|
||||
failed += 1;
|
||||
console.warn('stream-capture : envoi impossible', err);
|
||||
}
|
||||
updateBadge();
|
||||
}
|
||||
|
||||
browser.webRequest.onBeforeRequest.addListener(
|
||||
(details) => {
|
||||
if (!MEDIA_PATTERN.test(details.url)) return {};
|
||||
|
||||
const filter = browser.webRequest.filterResponseData(details.requestId);
|
||||
const chunks = [];
|
||||
|
||||
filter.ondata = (event) => {
|
||||
chunks.push(event.data);
|
||||
// Réécriture immédiate : la page reçoit son flux inchangé.
|
||||
filter.write(event.data);
|
||||
};
|
||||
|
||||
filter.onstop = () => {
|
||||
filter.disconnect();
|
||||
void forward(details.url, chunks);
|
||||
};
|
||||
|
||||
filter.onerror = () => {
|
||||
// Le filtre a lâché : la requête suit son cours normalement.
|
||||
console.warn('stream-capture : filtre interrompu', filter.error);
|
||||
};
|
||||
|
||||
return {};
|
||||
},
|
||||
{ urls: ['*://*.doppiocdn.com/*'] },
|
||||
['blocking'],
|
||||
);
|
||||
|
||||
console.log('stream-capture : actif, récepteur attendu sur', RECEIVER);
|
||||
Reference in New Issue
Block a user