HTMLVideoElement: метод requestVideoFrameCallback()
Базовая версия 2024
Новое
С октября 2024 года эта функция работает на последних устройствах и версиях браузеров. Возможно, эта функция не будет работать на более старых устройствах или браузерах.
Метод requestVideoFrameCallback() интерфейса HTMLVideoElement регистрирует функцию обратного вызова, которая выполняется при отправке нового кадра видео в композитор. Это позволяет разработчикам выполнять эффективные операции над каждым кадром видео.
Синтаксис
requestVideoFrameCallback(callback)
Параметры
callback-
Функция обратного вызова, которая выполняется при отправке нового кадра видео в композитор. Она содержит два параметра:
now-
DOMHighResTimeStamp, представляющий время, когда был вызван обратный вызов. metadata-
Объект, содержащий следующие свойства:
expectedDisplayTime-
DOMHighResTimeStamp, представляющий время, когда браузер ожидает отображения кадра. height-
Число, в пикселях медиа, представляющее высоту кадра видео (видимые декодированные пиксели без корректировок соотношения сторон).
mediaTime-
Число, в секундах, представляющее временную метку презентации медиа для отображаемого кадра. Оно равно временной метке кадра на временной шкале
HTMLMediaElement.currentTime. presentationTime-
DOMHighResTimeStamp, представляющий время, когда браузер отправил кадр для композиции. presentedFrames-
Число, представляющее количество кадров, отправленных на композицию до текущего обратного вызова. Его можно использовать для определения пропущенных кадров между вызовами обратного вызова.
processingDuration-
Число, в секундах, представляющее продолжительность времени между отправкой закодированного пакета с той же временной меткой презентации, что и этот кадр, в декодер (т. е.,
mediaTime) и готовностью декодированного кадра для презентации. width-
Число, в пикселях медиа, представляющее ширину кадра видео (видимые декодированные пиксели без корректировок соотношения сторон).
Дополнительные свойства метаданных могут быть доступны в обратных вызовах
requestVideoFrameCallback(), используемых в приложениях WebRTC:captureTime-
DOMHighResTimeStamp, представляющий время захвата кадра. Это относится к кадрам видео, поступающим из локального или удаленного источника. Для удаленного источника время захвата оценивается с использованием синхронизации часов и сообщений RTCP отправителя для преобразования временных меток RTP в время захвата. receiveTime-
DOMHighResTimeStamp, представляющий время, когда закодированный кадр был получен платформой. Это относится к кадрам видео, поступающим из удаленного источника. В частности, это соответствует моменту, когда последний пакет, относящийся к этому кадру, был получен по сети. rtpTimestamp-
Число, представляющее временную метку RTP, связанную с этим кадром видео.
Примечание: width и height могут отличаться от HTMLVideoElement.videoWidth и HTMLVideoElement.videoHeight в определенных случаях (например, анаморфное видео может иметь прямоугольные пиксели).
Значение возврата
Число, представляющее уникальный идентификатор обратного вызова.
Его можно передать в HTMLVideoElement.cancelVideoFrameCallback() для отмены регистрации обратного вызова.
Описание
Типичные случаи использования requestVideoFrameCallback() включают обработку видео и рисование на холсте, анализ видео и синхронизацию с внешними аудиоисточниками. Обработка по кадрам раньше выполнялась менее эффективным или точным способом, выполняя операции над текущим отображением видео всякий раз, когда срабатывало событие timeupdate. Эта техника не предоставляла доступа к самим кадрам видео.
requestVideoFrameCallback() используется так же, как Window.requestAnimationFrame(). Вы используете его для запуска функции обратного вызова, которая выполняет некоторую операцию, когда следующий кадр видео отправляется в композитор. Обратный вызов завершается вызовом requestVideoFrameCallback() снова для запуска обратного вызова, когда композируется следующий кадр видео, и так далее. Однако requestVideoFrameCallback() адаптирован для операций с видео несколькими способами:
-
requestVideoFrameCallback()предоставляет надежный доступ к каждому отдельному кадру видео. -
requestAnimationFrame()пытается согласоваться со скоростью обновления экрана, которая обычно составляет 60 Гц.requestVideoFrameCallback(), с другой стороны, пытается согласоваться со скоростью кадров видео. Более конкретно, обратный вызов будет выполняться с меньшей частотой из частоты кадров видео и частоты обновления отрисовки браузера. Например, видео со скоростью кадров 25 кадров/с, воспроизводимое в браузере, который отрисовывает с частотой 60 Гц, будет вызывать обратные вызовы с частотой 25 Гц. Видео со скоростью кадров 120 кадров/с, воспроизводимое в том же браузере с частотой 60 Гц, будет вызывать обратные вызовы с частотой 60 Гц. -
requestVideoFrameCallback()предоставляет полезные метаданные о видео в функции обратного вызова.
Следует иметь в виду, что requestVideoFrameCallback() не предоставляет никаких строгих гарантий, что вывод из вашего обратного вызова будет оставаться синхронизированным со скоростью кадров видео. Он может быть вызван на один вертикальный синхронизатор (v-sync) позже, чем при представлении нового кадра видео. (V-sync — это технология графики, которая синхронизирует скорость кадров видео со скоростью обновления монитора.)
API работает в основном потоке, в то время как композиция видео, вероятно, происходит в отдельном потоке композиции. Необходимо учитывать время, затрачиваемое на завершение этих операций, а также время, необходимое для отображения самого видео и результата вашей операции requestVideoFrameCallback() на экране.
Вы можете сравнить параметр обратного вызова now и свойство метаданных expectedDisplayTime для определения, является ли ваш обратный вызов отложенным на v-sync. Если expectedDisplayTime находится в пределах примерно пяти-десяти микросекунд от now, кадр уже отрисован. Если expectedDisplayTime находится примерно на шестнадцать миллисекунд в будущем (предполагая, что ваш браузер/экран обновляется с частотой 60 Гц), обратный вызов отложен на v-sync.
Примеры
Отрисовка кадров видео на холсте
В этом примере показано, как использовать requestVideoFrameCallback() для отрисовки кадров видео на элементе <canvas> с точной частотой кадров, равной частоте кадров видео. Также выводятся метаданные кадра в DOM для целей отладки.
if ("requestVideoFrameCallback" in HTMLVideoElement.prototype) {
let paintCount = 0;
let startTime = 0.0;
const updateCanvas = (now, metadata) => {
if (startTime === 0.0) {
startTime = now;
}
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const elapsed = (now - startTime) / 1000.0;
const fps = (++paintCount / elapsed).toFixed(3);
fpsInfo.innerText = `video fps: ${fps}`;
metadataInfo.innerText = JSON.stringify(metadata, null, 2);
// Re-register the callback to run on the next frame
video.requestVideoFrameCallback(updateCanvas);
};
// Initial registration of the callback to run on the first frame
video.requestVideoFrameCallback(updateCanvas);
} else {
alert("Your browser does not support requestVideoFrameCallback().");
}
См. Демонстрацию requestVideoFrameCallback для рабочей реализации приведенного выше кода.
Спецификации
| Спецификация |
|---|
| HTMLVideoElement.requestVideoFrameCallback() # dom-htmlvideoelement-requestvideoframecallback |
Совместимость с браузерами
| Рабочие столы | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
requestVideoFrameCallback |
83 | 83 | 132 | 69 | 15.4 | 83 | 132 | 59 | 15.4 | 13.0 | 83 |
См. также
- Элемент
<video> HTMLVideoElement.cancelVideoFrameCallback()-
Выполняйте эффективные операции по кадрам видео с помощью
requestVideoFrameCallback()на developer.chrome.com (2023)
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/requestVideoFrameCallback