Могут ли контент и фоновые сценарии Chrome совместно использовать URL-адреса BLOB-объектов? - PullRequest
0 голосов
/ 28 июня 2018

Я создаю поток getUserMedia в скрипте содержимого расширения Chrome и хочу передать его в фоновый скрипт.

Вы не можете передавать данные, не поддерживающие JSON, между ними, поэтому моя стратегия состоит в том, чтобы вместо этого генерировать URL-адрес созданного большого двоичного объекта в поток.

Содержимое скрипта:

function get_stream() {
    navigator.mediaDevices.getUserMedia({video: 1}).then(stream => {
        chrome.runtime.sendMessage({action: 'got_stream', params: {stream_url: URL.createObjectURL(stream)}});
    });

Фоновый скрипт:

chrome.runtime.onMessage.addListener(function(data) {
    switch (data.action) {
        case 'got_stream': got_stream(data.params); break;
    }
});

function got_stream(params) {
    let vid = document.createElement('video');
    alert(params.stream_url); //blob:http://...
    vid.src = params.stream_url; //error - file not found
}

Это нормально ... пока я не попытаюсь применить его к сгенерированному элементу <video />, после чего консоль сообщит, что файл не найден.

Я предполагаю, что это потому, что фоновые и контентные скрипты находятся в изолированной среде.

Есть ли способ обойти это без необходимости делать что-то ядерное, например, передавать поток буквально через WebRTC или что-то в этом роде?

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Я понял, что это проблема происхождения.

Сценарий содержимого выполняется в контексте текущей веб-страницы, тогда как фоновый сценарий выполняется в контексте расширения.

URL-адреса BLOB-объектов сгруппированы по происхождению, поэтому точно так же, как вы не можете обычно AJAX переходить с одного домена на другой, два домена также не могут быть уверены, что URL-адреса BLOB-объектов.

Это решается запуском сценария содержимого не на текущей веб-странице (поэтому не указывается в манифесте в content_scripts), а в новой вкладке или всплывающем окне.

Справочная информация:

window.open('content-page.html');

Страница содержимого:

<script src='content-script.js'></script>

Тогда любой URL-адрес BLOB-объекта, созданный content-script.js, будет доступен для чтения в фоновом режиме, поскольку теперь они оба работают в контексте расширения, то есть общего источника.

[EDIT]

Если вам не нравится идея всплывающего окна (в конце концов, на Mac они отображаются как полные вкладки), вы можете вместо этого вставить iframe в текущую вкладку и запустить оттуда скрипт contenet. .

Для этого вызовите скрипт содержимого из своего манифеста:

{
    "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["content-script-curr-tab.js"]
    }]
}

Тогда в том:

let ifr = document.createElement('iframe');
ifr.setAttribute('allow', 'microphone; camera'); //necessary for cross-origin frames that request permissions
ifr.style.display = 'none';
ifr.src = chrome.runtime.getURL('page-to-inject-into-iframe.html');
document.body.appendChild(ifr);

Затем, наконец, в page-to-inject-into-iframe.html:

<script src='script-to-inject-into-iframe.js'></script>

Тогда делай свое дело там!

0 голосов
/ 28 июня 2018

URL-адреса BLOB-объектов, скорее всего, связаны с источником, поэтому я не думаю, что это сработает. См. Обсуждение здесь в хранилище адаптеров.

Вы пытались создать RTCPeerConnection между контентом и фоновым скриптом и отправлять поток таким образом? Не идеально по ряду причин, но лучше, чем ничего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...