Как устранить ошибку в коде расширения Chrome, которое перезаписывает изображения лиц Google-Meet в режиме реального времени?

  1. URL-адрес после https://meet.google.com/ установлен неправильно и ссылается на файл js.

  1. document.body.insertBefore(script, document.body.firstChild) в loader.js выдает ошибку, могу ли я использовать его в манифесте V3?
  • Отображается следующее сообщение об ошибке.  ※Не удалось опубликовать подробный текст ошибки, поскольку сайт был помечен как спам.

  • Кажется, особенно здесь ошибка
    ・loader.js
    document.body.insertBefore(скрипт, document.body.firstChild)


Отказался загружать скрипт https://meet.google.com/tf-core.js, поскольку он нарушает директиву политики безопасности контента.

  • Нам кажется странным, что по какой-то причине здесь ссылка на js-файл находится за https://meet.google.

Отказано в выполнении встроенного сценария, поскольку он нарушает директиву политики безопасности контента.


Непойманное (обещающее) событие Контекст https://meet.google.com/ Трассировки стека loader.js:36 (безымянная функция)


  • Extension.sh — это код для загрузки файлов js в коде. Эта оболочка использовалась для загрузки файлов.

  • Структура папок
    расширение
    -face-kandmarks-detection.js
    -ImMarkIMG.js
    -extensions.sh
    -main.js
    -loader.js
    -manifest.json
    -tf-backend-webgl.js
    -tf-converter.js
    -tf-core.js


расширения.sh

#!/usr/bin/env bash

#NOTE: if you are on macOS, update to bash v4 i.e brew install bash

rm -rf extension extension.zip
cp -r public extension 
cd extension
 
declare -A scripts0=(
    [file]='tf-core.js'
    [url]='https://unpkg.com/@tensorflow/[email protected]/dist/tf-core.js'
)
declare -A scripts1=(
    [file]='tf-converter.js'
    [url]='https://unpkg.com/@tensorflow/[email protected]/dist/tf-converter.js'
)
declare -A scripts2=(
    [file]='tf-backend-webgl.js'
    [url]='https://unpkg.com/@tensorflow/[email protected]/dist/tf-backend-webgl.js'
)
declare -A scripts3=(
    [file]='face-landmarks-detection.js'
    [url]='https://unpkg.com/@tensorflow-models/[email protected]/dist/face-landmarks-detection.js'
)

declare -n scripts
for scripts  in ${!scripts@}; do
  curl ${scripts[url]} -o ${scripts[file]}
  sed -i"" -e "s|${scripts[url]}|${scripts[file]}|g" main.js
done

zip -r extension.zip *
mv extension.zip ../



манифест.js

{
  "manifest_version": 3,
  "name": "Meet Face Hack Extension",
  "version": "0.0.1",
  "description": "Meet hack",
    "host_permissions": [
    "https://meet.google.com/"
  ],
  "content_scripts": [
    {
      "js": ["lmMarkImg.js","tf-core.js","tf-converter.js","tf- backend-webgl.js","face-landmarks-detection.js","loader.js","main.js"],
      "matches": ["https://meet.google.com/*"],
      "run_at": "document_start"
    }
  ]
}

загрузчик.js

function loadScript(src) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.src = src
    script.onload = () => {
      console.info(`loaded: ${src}`)
      resolve()
    }
    script.onerror = (e) => reject(e)
    document.body.insertBefore(script, document.body.firstChild)
  })
}

async function loadLocalScript(path) {
  const res = await fetch(chrome.runtime.getURL(path), {method: 'GET'})
  const text = await res.text()
  const script = document.createElement('script')
  script.textContent = text
  document.body.insertBefore(script, document.body.firstChild)
}


async function load() {
  loadLocalScript("lmMarkImg.js")
  
  await loadScript("tf-core.js")
  await loadScript("tf-converter.js")
  await loadScript("tf-backend-webgl.js")
  await loadScript("face-landmarks-detection.js")

  loadLocalScript("main.js")
}

window.addEventListener('load', async (evt) => {
  await load()
})

main.js

const video = document.createElement('video')
const canvas = document.createElement('canvas')
const canvasCtx = canvas.getContext('2d')
let model = null
let keepAnimation = false

let imageIndex = 0
function getImage() {
  const image = lmMarkImages[imageIndex]
  imageIndex += 1
  if (imageIndex == lmMarkImages.length) {
    imageIndex = 0
  }

  return image
}

function drawImage(prediction) {
  let imageIndex = 0
  const boundingBox = prediction.boundingBox
  const x = boundingBox.topLeft[0]
  const y = boundingBox.topLeft[1]
  const w = boundingBox.bottomRight[0] - x
  const h = boundingBox.bottomRight[1] - y

  // draw Rectangle for debug
  // canvasCtx.strokeStyle = "rgb(255, 0, 0)";
  // canvasCtx.strokeRect(x, y, w, h)

  const image = getImage()
  canvasCtx.drawImage(image, x, y, w, h)
}

async function updateCanvas() {
  if (!keepAnimation) return

  if (model) {
    canvasCtx.drawImage(video, 0, 0, canvas.width, canvas.height)

    const predictions = await model.estimateFaces({ input: video })
    for (const prediction of predictions) {
      drawImage(prediction)
    }
  }
  requestAnimationFrame(updateCanvas)
}

function isScreenSharing(constraints) {
  return !constraints.video.deviceId
}

function replaceStopFunction(stream, videoTrack) {
  if (!videoTrack) return

  videoTrack._stop = videoTrack.stop
  videoTrack.stop = function () {
    keepAnimation = false
    videoTrack._stop()
    stream.getTracks().forEach((track) => {
      track.stop()
    })
  }
}

const _getUserMedia = navigator.mediaDevices.getUserMedia.bind(
  navigator.mediaDevices
)

navigator.mediaDevices.getUserMedia = async function (constraints) {
  const srcStream = await _getUserMedia(constraints)

  if (isScreenSharing(constraints)) {
    return srcStream
  }

  video.srcObject = srcStream
  video.onloadedmetadata = function (e) {
    video.play()
    video.volume = 0.0
    video.width = video.videoWidth
    video.height = video.videoHeight
    canvas.width = video.width
    canvas.height = video.height

    keepAnimation = true
    updateCanvas()
  }

  const outStream = canvas.captureStream(10)
  const videoTrack = outStream.getVideoTracks()[0]
  replaceStopFunction(srcStream, videoTrack)

  return outStream
}

async function loadModel() {
  model = await faceLandmarksDetection.load(
    faceLandmarksDetection.SupportedPackages.mediapipeFacemesh
  )
  //console.info("model: loaded")
}

function main() {
  loadModel()
}

main()


Поскольку необходимо было вставить минимальное количество кода, файл main.js не был вставлен. При необходимости добавлю.

Структура папок изменена.

moca 06.04.2024 19:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Скрипты контента, работающие в ИЗОЛИРОВАННОМ мире по умолчанию в ManifestV3, не могут устанавливать textContent элемента script. Используйте src с chrome.runtime.getURL.
  2. Не вызывайте loadScript для tf-скриптов, потому что у вас их нет, они являются частью main.js.

Вот весь файл loader.js:

const scripts = [
  'lmMarkImg.js',
  'main.js',
];
(function loadSequentially() {
  const el = document.createElement('script')
  el.src = chrome.runtime.getURL(scripts.shift());
  if (scripts[0]) el.onload = loadSequentially;
  document.documentElement.appendChild(el);
  el.remove();
})();

Большое спасибо за ответ на мой вопрос. Если возможно, буду рад ответить на дополнительные вопросы. К вопросу был добавлен main.js. Я получил следующую ошибку в main.js. Неперехваченный (в обещании) ReferenceError: faceLandmarksDetection не определен - Контекст: meet.google.com/~~~ (это моя ссылка на встречу) - Stack Trace: model = await faceLandmarksDetection.load(

moca 06.04.2024 19:57

Смотрите фиксированный ответ.

woxxom 06.04.2024 20:55

Знаете ли вы, как устранить эту ошибку?

moca 06.04.2024 21:18

Как я уже сказал, я исправил ответ, используйте новый код. Если он по-прежнему не работает, значит, вы не использовали extensions.sh или он сломан. При правильном использовании ваш файл main.js должен содержать все эти tf-скрипты.

woxxom 06.04.2024 22:24

Возможно, вы захотите использовать browserify вместо extensions.sh и просто import каждый пакет в main.js, а затем запустить на нем браузерификацию, чтобы создать выходной файл, содержащий весь импортированный код. Этот выходной файл следует использовать в окончательном расширении вместо исходного файла main.js.

woxxom 06.04.2024 22:33

Переход на измененную версию предоставленного кода не устранил ошибку. faceLandmarksDetection ссылается на face-landmarks-detection.js, но ``` typeof define === 'function' && define.amd ? define(['exports', '@tensorflow/tfjs-core', '@tensorflow/tfjs-converter'], Factory) : (global = global || self, Factory(global.faceLandmarksDetection = {}, global.tf, глобальный.tf)); ``` Возможно ли, что "global.tf" препятствует ссылке?

moca 07.04.2024 20:36

Спасибо за предложение "браузеризировать". Я не знаю, как этим пользоваться, поэтому сейчас изучаю его.

moca 07.04.2024 20:48

Может быть, document.documentElement.appendChild(el) не работает, потому что пакет не содержит html? Извините, если я ошибаюсь.

moca 08.04.2024 01:23

Он запускается на веб-странице, поэтому documentElement всегда присутствует.

woxxom 08.04.2024 01:54

Я понял . Что вы думаете о global.tf? (3 предыдущих комментария)

moca 08.04.2024 04:43

Если вы правильно используете браузерификацию, это решит проблему, поскольку создаст единый пакет.

woxxom 08.04.2024 05:55

Нужно ли мне добавлять или переписывать какой-либо новый код при использовании браузера? Это проблема, которую можно решить только в командной строке?

moca 10.04.2024 00:30

Пожалуйста, ознакомьтесь с демо-версией/документацией для браузера. AFAIK, это действительно просто: просто импортируйте или require модули в main.js, затем запустите браузер и используйте выходной файл. Вы, конечно, можете сделать то же самое вручную, загрузив сценарии, объединив их и поместив в IIFE для изоляции (это то, что должен делать ваш файл Extensions.sh, но, видимо, это неправильно).

woxxom 10.04.2024 02:01
import * as faceLandmarksDetection from '@tensorflow-models/face-landmarks-detection'; Я думал, что смогу это сделать, но получил ошибку. У меня также возникла ошибка при попытке запустить $ npm install @tensorflow-models/face-landmarks-detection Да $ npm install @tensorflow-models/face-landmarks-detection
moca 11.04.2024 00:48

и мне сказали, что произошел конфликт с другим файлом js, поскольку это была другая версия. Я просмотрел браузерную/демо-версию и, переписав код на let require=~, переписал package.json (не знаю...) и добавил npm install @tensorflow-models/face-landmarks-detection , и мне сказали, что произошел конфликт, потому что другие js-файлы имели разные версии. . и делай npm install {module}. Извините, что спрашиваю так много раз, пожалуйста, дайте мне знать, как решить эту проблему.

moca 11.04.2024 00:48

Я думаю, вам следует просто импортировать/требовать те же URL-адреса CDN, которые вы сейчас используете в Extension.sh.

woxxom 11.04.2024 01:38
Uncaught (in promise) ReferenceError: faceLandmarksDetection is not definedmodel = await faceLandmarksDetection.load( Я думал, что надо его "импортировать", но может стоит переписать loader.js?
moca 11.04.2024 10:08

Почему вы загружаете эти файлы как элементы сценария, а не просто указываете их в «content_scripts» как «js»?

woxxom 11.04.2024 21:23

Что вы имеете в виду? Я предполагаю, что вы имеете в виду манифест.js. Как, по вашему мнению, это следует исправить?

moca 12.04.2024 03:15

Просто поместите скрипты в каталог расширений и перечислите их в content_scripts->js вместо loader.js и web_accessible_resources.

woxxom 12.04.2024 05:33

Исправлен манифест.js. Однако следующий код не является частью ` model = await faceLandmarksDetection.load(` часть model = await faceLandmarksDetection.load()', говорит Uncaught (in promise) ReferenceError: faceLandmarksDetection is not defined. ошибка сохраняется.

moca 12.04.2024 06:57

Скрипты, перечисленные в js, выполняются в указанном порядке, поэтому файл face-landmarks-detection.js следует указывать перед скриптами, которые его используют.

woxxom 12.04.2024 07:03

Исправлен манифест.json. Ошибка устранена, но lmMarkImage.js не применяется и лицо не перезаписывается изображением. Если вы что-нибудь знаете, пожалуйста, дайте мне знать.

moca 12.04.2024 09:28

Попробуйте добавить "world": "MAIN" в объявление content_scripts.

woxxom 12.04.2024 10:06

В этом разделе появляется сообщение об ошибке Uncaught TypeError: chrome.runtime.getURL is not a function. Кроме того, примечание Your application contains ops that are small enough to be executed on the CPU backend, however the CPU backend cannot be found. Consider importing the CPU backend (@tensorflow/tfjs-backend-cpu) for better performance. Это проблема с моим компьютером?

moca 12.04.2024 11:31

Вам не нужен chrome.runtime.getURL, нет необходимости создавать элементы сценария с помощью этого подхода. Что касается сообщения об ошибке, в нем говорится, что вы не добавляли tfjs-backend-cpu.js, поэтому просто добавьте его или попробуйте поискать в Google сообщение об ошибке или спросите об этом пакете на форуме/репозитории.

woxxom 12.04.2024 12:26

Я переписал js-часть content_scripts в манифесте, и она работает правильно. "js": ["tf-core.js", "tf-converter.js", "tf-backend-webgl.js", "face-landmarks-detection.js", "lmMarkImg.js", "loader.js", "main.js", Спасибо вам большое. Я бы не справился без тебя.

moca 12.04.2024 15:05

Однако ошибка не устранена.... - Изображение распадается каждые 2 секунды. - Могу ли я удалить строку getURL?

moca 12.04.2024 15:12

Вам не нужен loader.js, удалите его.

woxxom 12.04.2024 15:36

Loader.js был удален. Your application contains ops that are small enough to be executed on the CPU backend, however the CPU backend cannot be found. backend (@tensorflow/tfjs-backend-cpu) for better performance. отображается. Я думаю, @tensorflow/tfjs-backend-cpu — это не js-файл, а каталог, поэтому мне придется импортировать его с помощью веб-пакета или чего-то еще. Сообщение об ошибке следующее. console.warn('Your application contains ops that are small enough to be

moca 12.04.2024 15:48

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

moca 12.04.2024 15:49

Попробуйте создать новый вопрос с тегами для tensorflow, чтобы эксперты могли помочь.

woxxom 13.04.2024 01:02

Другие вопросы по теме