Я работаю над небольшим побочным проектом в форме расширения chrome, которое отображает локальный поток через API getUserMedia.
Сначала у меня возникли проблемы с запросом десен (getUserMedia), поскольку я пытался получить к нему доступ через всплывающее окно. js и фон. js. После некоторого тестирования я начал работать с контентом. js, но теперь проблема заключалась в том, что во всплывающем окне отображался поток. html. Дальнейшие исследования предложили использовать встроенный sendMessage из chrome (поскольку у скрипта контента нет доступа к всплывающему окну).
Таким образом, мой рабочий процесс теперь является прослушивателем onClick в моем всплывающем окне, по щелчку пользователя отправив уведомление в мой скрипт содержимого, запросив там жевательную резинку и выполнив функцию обратного вызова из полученного сообщения, которая устанавливает поток для моего видеоэлемента , Проблема теперь в том, что мой поток отправки изменяется, передавая его с помощью функции sendMessage, что приводит к ошибке установки потока для моего видеоэлемента, так как поток больше не является объектом MediaStream.
Мой подход - метод проб и ошибок, так как я не являюсь веб-разработчиком и не имею опыта работы с chrome -распространениями. Любые предложения или помощь о том, как я могу достичь этого, высоко ценятся
- всплывающее окно. js
let startStream = document.getElementById('gum');
function setStream(stream) {
if(stream != null){
video = document.getElementById('localStream');
if("srcObject" in video) {
console.log("videoelement supports scrObject.")
}
console.log('stream: ', stream)
video.srcObject = stream;
} else {
console.log("popup: passed stream is not definded")
}
}
startStream.onclick = function(element) {
console.log("popup start stream clicked");
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{from: 'popup', action: 'startStream'},
setStream);
});
};
- всплывающее окно. html
<!DOCTYPE html>
<html>
<head>
<style>
button {
height: 30px;
width: 30px;
outline: none;
}
</style>
</head>
<body>
<video controls id=localStream></video>
<button id="gum">Start</button>
<script src="popup.js"></script>
</body>
</html>
- содержание. js
console.log('content script init')
chrome.runtime.onMessage.addListener((msg, sender, response) => {
console.log(sender.tab ?
"message from a content script:" + sender.tab.url :
"message from the extension");
if (msg.from == "popup" && msg.action == "startStream"){
console.log('content script start stream action')
navigator.mediaDevices.getUserMedia({video:true, audio:true})
.then((stream) => {
console.log('content gum successfull: ', toString(stream));
console.log('stream: ', stream);
response(stream);
})
.catch((err) => {
console.log('content gum error: ' + error);
response(null);
});
return true;
}
});
- манифест. json
{
"version": "1.0",
"name": "Some test",
"description": "Build an Extension!",
"manifest_version": 2,
"permissions": ["declarativeContent", "storage", "activeTab", "tabs"],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_idle",
"all_frames": false
}],
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/icon-off-16.png",
"32": "images/icon-off-32.png",
"48": "images/icon-off-48.png",
"64": "images/icon-off-64.png",
"128": "images/icon-off-128.png"
},
"default_title": "World Domination"
},
"icons": {
"16": "images/icon-off-16.png",
"32": "images/icon-off-32.png",
"48": "images/icon-off-48.png",
"64": "images/icon-off-64.png",
"128": "images/icon-off-128.png"
}
}