Новая вкладка Firefox WebExtension <video> кратковременно мигает черным между плакатом и первым кадром, хотя исходное виJavascript

Форум по Javascript
Ответить
Anonymous
 Новая вкладка Firefox WebExtension <video> кратковременно мигает черным между плакатом и первым кадром, хотя исходное ви

Сообщение Anonymous »

Я создаю веб-расширение Firefox «Новая вкладка», которое показывает полноэкранные зацикленные видеообои (кошка + камин). Из соображений производительности я стараюсь мгновенно отображать статический предварительный просмотр, а затем плавно переходить в живое видео.
Базовая структура в моем new-tab.html выглядит следующим образом: CSS (упрощенный):

Код: Выделить всё

body {
margin: 0;
background: #000;              /* never white */
overflow: hidden;
}

#wallpaper-layer {
position: fixed;
inset: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
/* same image as the video poster */
background-image: url("assets/fireplace_poster.webp");
}

.background-video {
position: fixed;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
background-color: #000;         /* also black, not white */
}
И JS, который подключает выбранное пользователем видео в new-tab.js (упрощенно):

Код: Выделить всё

async function loadWallpaper() {
const video = document.getElementById('bg-video-a');

// In the real code this comes from browser.storage.local
// as a Blob, then we create an object URL:
const response = await fetch(browser.runtime.getURL('assets/fireplace_loop.mp4'));
const blob = await response.blob();
const url = URL.createObjectURL(blob);

video.src = url;
video.poster = 'assets/fireplace_poster.webp'; // same as #wallpaper-layer
video.load();

// I keep the static layer visible so the tab looks instant:
document.getElementById('wallpaper-layer').style.opacity = '1';

video.addEventListener('loadeddata', () => {
// Once the video is ready, start playback and then fade out the static layer
video.play().catch(console.error);

// Tried both immediate and delayed hide:
setTimeout(() => {
document.getElementById('wallpaper-layer').style.opacity = '0';
}, 50); // also tried 0, 100, 200 ms, etc.
});
}

document.addEventListener('DOMContentLoaded', loadWallpaper);
Проблема
Когда я открываю новую вкладку:
  • Я мгновенно вижу статические обои (как и предполагалось).
  • Затем, когда начинается видео, появляется ровно один кадр со скоростью 60 кадров в секунду, где вся область видео полностью черная.
  • После этого единственного черного кадра видео воспроизводится обычно.
Чтобы отладить это, я записал экран со скоростью 60 кадров в секунду и прошёл между кадрами. Кадры 1–3 (иногда 1–6) показывают постер/статичные обои, затем 1 черный кадр, а затем движущиеся кадры видео.
Я проверил, что в самом исходном видео нет черного первого кадра, с помощью ffmpeg:

Код: Выделить всё

cd "C:\Users\rokon\OneDrive\Desktop\IPTV-master\ffmpeg"

ffmpeg -i "C:\Users\rokon\Downloads\video.mp4" -vframes 10 frame_%02d.png
Глядя на Frame_01.png через Frame_10.png, ни один из них не черный — все они показывают кота + камин, поэтому черная рамка появляется только во время воспроизведения в Firefox.
Что я уже пробовал
  • Перекодировать видео, чтобы первые 2 секунды были идентичны плакату (черного нигде нет).
    />
  • Использование preload="auto", preload="metadata" и preload="none" в теге .
  • Удаление шага URL-адреса объекта и назначение video.src непосредственно упакованному ресурсу (

    Код: Выделить всё

    browser.runtime.getURL("assets/fireplace_loop.mp4")
    ).
  • Ожидание canplay, canplaythrough и загруженных данных перед вызовом play().
  • Задержка исчезновения #wallpaper-layer на различное время (0–500 мс).
  • Попытка с атрибутом плаката и без него (зависит только от #wallpaper-layer).
  • Тестирование в Chrome и Edge: я не вижу там черную рамку; пока что я воспроизвожу это только в Firefox со страницей новой вкладки WebExtension.
Я также обратился за помощью к Gemini и ChatGPT. Они предлагали такие вещи, как сохранение статического наложения до изменения timeupdate, изменение предварительной загрузки или перекодирование первого кадра, но ни один из этих подходов не удаляет черную рамку в Firefox.
Вопросы
  • Что именно делает Firefox между плакатом и первым декодированным кадром, что может вызвать этот единственный черный кадр?
    • Очищает ли он поверхность композитора или видеослой становятся черными до того, как декодер выводит кадр 0?
    • Это специфично для страниц «новой вкладки» WebExtension?
  • Есть ли какой-нибудь надежный обходной путь на стороне расширения, чтобы избежать этой черной вспышки? Например:
    • Заставить Firefox продолжать показывать плакат до тех пор, пока currentTime > 0? (Я мог бы отслеживать обновление времени, но черная рамка уже появляется сразу после начала воспроизведения.)
    • Использовать другую комбинацию предварительной загрузки/автозапуска?
    • Принудительно декодировать видео кадр 0 за кадром (например, скрытый , искать(0), затем показать)?
  • Если это неизбежная деталь реализации в Firefox, существует ли какой-либо известный шаблон (даже хакерский), который авторы расширений используют, чтобы скрыть это? Я могу сохранить отдельный слой или , если это необходимо, я просто не могу избавиться от этой черной рамки.
Любые эксперты по Firefox/video или WebExtension, которые могут объяснить, что здесь происходит и как это обойти, будут очень признательны.

Подробнее здесь: https://stackoverflow.com/questions/798 ... ter-and-fi
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»