{"id":83094,"date":"2022-07-28T10:01:42","date_gmt":"2022-07-28T08:01:42","guid":{"rendered":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/"},"modified":"2020-09-16T18:21:03","modified_gmt":"2020-09-16T21:21:03","slug":"realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback","status":"publish","type":"post","link":"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/","title":{"rendered":"Perform efficient per frame video operations on video with requestVideoFrameCallback ()"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_86 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewbox=\"0 0 24 24\" version=\"1.2\" baseprofile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#Diferencia-con-requestAnimationFrame\" >Difference with requestAnimationFrame ()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#%C2%BFLo-que-hay-en-un-nombre\" >What&#039;s in a name?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#Soporte-de-navegador-y-deteccion-de-funciones\" >Browser support and feature detection<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#Usando-el-metodo-requestVideoFrameCallback\" >Using the requestVideoFrameCallback () method<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#Si-las-cosas-parecen-un-cuadro-de-distancia-%E2%80%A6\" >If things seem like a box away ...<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#Manifestacion\" >Manifestation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#Conclusiones\" >Conclusions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#Agradecimientos\" >Thanks<\/a><\/li><\/ul><\/nav><\/div>\n<p><\/p>\n<div>\n<header class=\"w-article-header\">\n<p class=\"w-article-header__subhead w-mb--non\">\n<p>          Learn to use the <code>requestVideoFrameCallback ()<\/code> to work more efficiently with videos in the browser.<\/p>\n<p>\n          <time>June 29, 2020<\/time><br \/>\n            Updated <time>17 Aug 2020<\/time>\n        <\/p>\n<\/header>\n<p>There is a new web API in the block, defined in the<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/wicg.github.io\/video-rvfc\/\"><code>HTMLVideoElement.requestVideoFrameCallback ()<\/code><\/a><\/p>\n<p>specification. the <code>requestVideoFrameCallback ()<\/code> The method allows web authors to record a callback that runs through the rendering steps when a new video frame is sent to the composer. This is intended to enable developers to perform efficient operations per frame of video to video, such as video processing and painting on a canvas, video analysis, or syncing with external audio sources.<\/p>\n<h2 id=\"difference-with-requestanimationframe()\"><span class=\"ez-toc-section\" id=\"Diferencia-con-requestAnimationFrame\"><\/span>Difference with requestAnimationFrame () <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Operations such as drawing a video frame on a canvas using<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/CanvasRenderingContext2D\/drawImage\"><code>drawImage ()<\/code><\/a><\/p>\n<p>made through this API will be synchronized as best effort with the frame rate of the video that is played on the screen. Different from<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/window\/requestAnimationFrame\"><code>window.requestAnimationFrame ()<\/code><\/a>, which typically fires about 60 times per second,<br \/>\n<code>requestVideoFrameCallback ()<\/code> is tied to the actual video frame rate, with an important<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/wicg.github.io\/video-rvfc\/#ref-for-update-the-rendering%E2%91%A2:~:text=Note%3A%20The%20effective%20rate%20at%20which,browser%20would%20fire%20callbacks%20at%2060hz.\">exception<\/a>:<\/p>\n<blockquote>\n<p>The effective rate at which callbacks are executed is the lower rate of the video rate and the browser rate. This means that a 25fps video played in a browser that paints at 60Hz would trigger callbacks at 25Hz. A 120fps video on that same 60Hz browser would trigger 60Hz callbacks.<\/p>\n<\/blockquote>\n<h2 id=\"what's-in-a-name\"><span class=\"ez-toc-section\" id=\"%C2%BFLo-que-hay-en-un-nombre\"><\/span>What&#039;s in a name? <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Due to its similarity to <code>window.requestAnimationFrame ()<\/code>, the method initially was <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/discourse.wicg.io\/t\/proposal-video-requestanimationframe\/3691\">proposed as <code>video.requestAnimationFrame ()<\/code><\/a>, but I&#039;m happy with the new name,<br \/>\n<code>requestVideoFrameCallback ()<\/code>, which was agreed after a <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/WICG\/video-rvfc\/issues\/44\">long discussion<\/a>. Hurrah, <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/css-tricks.com\/what-is-bikeshedding\/\">bikes<\/a> for the victory!<\/p>\n<h2 id=\"browser-support-and-feature-detection\"><span class=\"ez-toc-section\" id=\"Soporte-de-navegador-y-deteccion-de-funciones\"><\/span>Browser support and feature detection <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The method is<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/chromestatus.com\/feature\/6335927192387584\">implemented in Chromium<\/a><br \/>\nalready, and<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/mozilla.github.io\/standards-positions\/#requestVideoFrameCallback\">Mozilla people like<\/a>. For what it&#039;s worth, I&#039;ve also submitted a<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=211945\">WebKit error<\/a> asking for it. API feature detection works like this:<\/p>\n<p><web-copy-code><\/p>\n<pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token string\">'requestVideoFrameCallback'<\/span> <span class=\"token keyword\">in<\/span> <span class=\"token class-name\">HTMLVideoElement<\/span><span class=\"token punctuation\">.<\/span>prototype<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br><span class=\"token punctuation\">}<\/span><\/code><\/pre>\n<p><\/web-copy-code><\/p>\n<h2 id=\"using-the-requestvideoframecallback()-method\"><span class=\"ez-toc-section\" id=\"Usando-el-metodo-requestVideoFrameCallback\"><\/span>Using the requestVideoFrameCallback () method <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If you have ever used the <code>requestAnimationFrame ()<\/code> method, you will immediately feel at home with the <code>requestVideoFrameCallback ()<\/code> method. You register an initial callback once and then re-register each time the callback is triggered.<\/p>\n<p><web-copy-code><\/p>\n<pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">doSomethingWithTheFrame<\/span> <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">now<span class=\"token punctuation\">,<\/span> metadata<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><br>console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>now<span class=\"token punctuation\">,<\/span> metadata<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br>video<span class=\"token punctuation\">.<\/span><span class=\"token function\">requestVideoFrameCallback<\/span><span class=\"token punctuation\">(<\/span>doSomethingWithTheFrame<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br>video<span class=\"token punctuation\">.<\/span><span class=\"token function\">requestVideoFrameCallback<\/span><span class=\"token punctuation\">(<\/span>doSomethingWithTheFrame<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p><\/web-copy-code><\/p>\n<p>In the callback, <code>now<\/code> is a <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/DOMHighResTimeStamp\"><code>DOMHighResTimeStamp<\/code><\/a><\/p>\n<p>and <code>metadata<\/code> is a <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/wicg.github.io\/video-rvfc\/#dictdef-videoframemetadata\"><code>VideoFrameMetadata<\/code><\/a><\/p>\n<p>dictionary with the following properties:<\/p>\n<ul>\n<li><code>presentationTime<\/code>, of type <code>DOMHighResTimeStamp<\/code>: The time when the user agent sent the frame for composition.<\/li>\n<li><code>expectedDisplayTime<\/code>, of type <code>DOMHighResTimeStamp<\/code>: The time when the user agent expects the frame to be visible.<\/li>\n<li><code>width<\/code>, of type <code>unsigned long<\/code>: The width of the video frame, in media pixels.<\/li>\n<li><code>height<\/code>, of type <code>unsigned long<\/code>: The height of the video frame, in multimedia pixels.<\/li>\n<li><code>mediaTime<\/code>, of type <code>double<\/code>: The media display timestamp (PTS) in seconds of the displayed frame (for example, your timestamp in the <code>video.currentTime<\/code> timeline).<\/li>\n<li><code>presentedFrames<\/code>, of type <code>unsigned long<\/code>: Count of the number of frames sent for composition. Allows customers to determine if frames were lost between instances of <code>VideoFrameRequestCallback<\/code>.<\/li>\n<li><code>processingDuration<\/code>, of type <code>double<\/code>: The elapsed duration in seconds since the sending of the packet encoded with the same presentation time stamp (PTS) as this frame (for example, the same as the <code>mediaTime<\/code>) to the decoder until the decoded frame is ready for presentation.<\/li>\n<\/ul>\n<p>For WebRTC applications, additional properties may appear:<\/p>\n<ul>\n<li><code>captureTime<\/code>, of type <code>DOMHighResTimeStamp<\/code>: For video frames coming from a local or remote source, this is the moment the camera captured the frame. For a remote source, capture time is estimated using RTCP sender clock synchronization and reporting to convert RTP timestamps to capture time.<\/li>\n<li><code>receiveTime<\/code>, of type <code>DOMHighResTimeStamp<\/code>: For video frames that come from a remote source, this is the time the platform received the encoded frame, that is, the time the last packet belonging to this frame was received through the network.<\/li>\n<li><code>rtpTimestamp<\/code>, of type <code>unsigned long<\/code>: The RTP timestamp associated with this video frame.<\/li>\n<\/ul>\n<div class=\"w-aside w-aside--note\">\n<p>Note that <code>width<\/code> and <code>height<\/code> may differ from <code>videoWidth<\/code> and <code>videoHeight<\/code> in certain cases (for example, an anamorphic video may have rectangular pixels).<\/p>\n<\/div>\n<p>Of special interest in this list is <code>mediaTime<\/code>. In the Chromium implementation, we use the audio clock as the time source that supports <code>video.currentTime<\/code>, Meanwhile he <code>mediaTime<\/code> is populated directly by the <code>presentationTimestamp<\/code> of the frame. the <code>mediaTime<\/code> is what to use if you want to accurately identify the frames in a reproducible way, even to identify exactly the frames that were lost.<\/p>\n<div class=\"w-aside w-aside--note\">\n<p>Unfortunately, the video element does not guarantee frame accuracy <em>searching<\/em>. This has been a continuous <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/w3c\/media-and-entertainment\/issues\/4\">topic of discussion<\/a>.<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/WICG\/web-codecs\">WebCodecs<\/a> it will eventually allow for frame-accurate applications.<\/p>\n<\/div>\n<h3 id=\"if-things-seem-one-frame-off...\"><span class=\"ez-toc-section\" id=\"Si-las-cosas-parecen-un-cuadro-de-distancia-%E2%80%A6\"><\/span>If things seem like a box away ... <span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Vertical sync (or simply vsync) is a graphics technology that synchronizes the frame rate of a video and the refresh rate of a monitor. As <code>requestVideoFrameCallback ()<\/code> runs in the main thread, but under the hood video compositing happens in the composer thread, everything from this API is a best effort and we do not offer any strict guarantees. What may be happening is that the API may lag a vsync relative to when a video frame is rendered. A vsync is required for changes made to the web page via the API to appear on the screen (same as <code>window.requestAnimationFrame ()<\/code>). So if you keep updating <code>mediaTime<\/code> or the frame number on your web page and compare it to the numbered video frames, eventually the video will look like it is one frame ahead.<\/p>\n<p>What is actually happening is that the frame is ready in vsync x, the callback fires, and the frame is processed in vsync x + 1, and the changes made to the callback are processed in vsync x + 2. You can check if the callback is a late vsync (and the frame is already rendered on the screen) by checking if the <code>metadata.expectedDisplayTime<\/code> is approximately <code>now<\/code> or a vsync in the future. If it is within five to ten microseconds of <code>now<\/code>, the frame is already rendered; If he <code>expectedDisplayTime<\/code> it&#039;s roughly sixteen milliseconds into the future (assuming your browser \/ screen updates to 60Hz), then it&#039;s in sync with the frame.<\/p>\n<h2 id=\"demo\"><span class=\"ez-toc-section\" id=\"Manifestacion\"><\/span>Manifestation <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I have created a small<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/requestvideoframecallback.glitch.me\/\">Glitch demo<\/a><br \/>\nwhich shows how frames are drawn on a canvas at exactly the frame rate of the video and where frame metadata is recorded for debugging purposes. The core logic is just a couple of lines of JavaScript.<\/p>\n<p><web-copy-code><\/p>\n<pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">let<\/span> paintCount <span class=\"token operator\">=<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token keyword\">let<\/span> startTime <span class=\"token operator\">=<\/span> <span class=\"token number\">0.0<\/span><span class=\"token punctuation\">;<\/span><p><span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">updateCanvas<\/span> <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">now<span class=\"token punctuation\">,<\/span> metadata<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><br><span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>startTime <span class=\"token operator\">===<\/span> <span class=\"token number\">0.0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br>startTime <span class=\"token operator\">=<\/span> now<span class=\"token punctuation\">;<\/span><br><span class=\"token punctuation\">}<\/span><\/p><p>ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">drawImage<\/span><span class=\"token punctuation\">(<\/span>video<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> canvas<span class=\"token punctuation\">.<\/span>width<span class=\"token punctuation\">,<\/span> canvas<span class=\"token punctuation\">.<\/span>height<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p><p><span class=\"token keyword\">const<\/span> elapsed <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">(<\/span>now <span class=\"token operator\">-<\/span> startTime<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">\/<\/span> <span class=\"token number\">1000.0<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token keyword\">const<\/span> fps <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">++<\/span>paintCount <span class=\"token operator\">\/<\/span> elapsed<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toFixed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">3<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br>fpsInfo<span class=\"token punctuation\">.<\/span>innerText <span class=\"token operator\">=<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`<\/span><span class=\"token string\">video fps: <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>fps<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token template-punctuation string\">`<\/span><\/span><span class=\"token punctuation\">;<\/span><br>metadataInfo<span class=\"token punctuation\">.<\/span>innerText <span class=\"token operator\">=<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">stringify<\/span><span class=\"token punctuation\">(<\/span>metadata<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p><p>video<span class=\"token punctuation\">.<\/span><span class=\"token function\">requestVideoFrameCallback<\/span><span class=\"token punctuation\">(<\/span>updateCanvas<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p><p>video<span class=\"token punctuation\">.<\/span><span class=\"token function\">requestVideoFrameCallback<\/span><span class=\"token punctuation\">(<\/span>updateCanvas<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p><\/code><\/pre>\n<p><\/web-copy-code><\/p>\n<p>\n  <iframe allow=\"camera; clipboard; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi; vr\" loading=\"lazy\" src=\"https:\/\/glitch.com\/embed\/#!\/embed\/requestvideoframecallback?attributionHidden=true&amp;sidebarCollapsed=true&amp;path=script.js&amp;previewSize=100\" style=\"height: 100%; width: 100%; border: 0;\" title=\"requestvideoframecallback on Glitch\"><\/iframe>\n<\/p>\n<h2 id=\"conclusions\"><span class=\"ez-toc-section\" id=\"Conclusiones\"><\/span>Conclusions <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I&#039;ve done frame-level processing for a long time, not having access to the actual frames, just based on <code>video.currentTime<\/code>. I implemented segmentation of video shots in JavaScript in a rough way; you can still read the attachment<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/www2012.universite-lyon.fr\/proceedings\/nocompanion\/DevTrack_028.pdf\">research work<\/a>. Had the <code>requestVideoFrameCallback ()<\/code> existed back then, my life would have been much simpler ...<\/p>\n<h2 id=\"acknowledgements\"><span class=\"ez-toc-section\" id=\"Agradecimientos\"><\/span>Thanks <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>the <code>requestVideoFrameCallback<\/code> The API was specified and implemented by<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/tguilbert-google\">Thomas guilbert<\/a>. This article was reviewed by <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/jpmedley\">Joe medley<\/a><br \/>\nand <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/kaycebasques\">Kayce Basques<\/a>.<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/unsplash.com\/photos\/tV80374iytg\">Hero image<\/a> for<br \/>\n<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/unsplash.com\/@dmjdenise\">Denise Jans<\/a> on Unsplash.<\/p>\n<p>    <web-feedback additional-questions=\"api\"><\/web-feedback>\n  <\/div>","protected":false},"excerpt":{"rendered":"<p>Learn how to use requestVideoFrameCallback() to work more efficiently with videos in the browser. June 29, 2020 Updated August 17, 2020 There is a new\u2026<\/p>","protected":false},"author":1,"featured_media":83095,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1356],"tags":[],"class_list":["post-83094","post","type-post","status-publish","format-standard","has-post-thumbnail","category-dev"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.0 (Yoast SEO v28.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Realice operaciones eficientes por fotograma de video en video con requestVideoFrameCallback () - R Marketing Digital<\/title>\n<meta name=\"description\" content=\"Aprenda a usar el requestVideoFrameCallback() para trabajar de manera m\u00e1s eficiente con videos en el navegador. 29 de junio de 2020 Actualizado 17 de\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Realice operaciones eficientes por fotograma de video en video con requestVideoFrameCallback ()\" \/>\n<meta property=\"og:description\" content=\"Aprenda a usar el requestVideoFrameCallback() para trabajar de manera m\u00e1s eficiente con videos en el navegador. 29 de junio de 2020 Actualizado 17 de\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/\" \/>\n<meta property=\"og:site_name\" content=\"R Marketing Digital\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-28T08:01:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/hero-1067606.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"360\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"R Marketing Digital\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/\"},\"author\":{\"name\":\"R Marketing Digital\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#\\\/schema\\\/person\\\/7c0d9782b2977b840b3740f00c69a73e\"},\"headline\":\"Realice operaciones eficientes por fotograma de video en video con requestVideoFrameCallback ()\",\"datePublished\":\"2022-07-28T08:01:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/\"},\"wordCount\":1240,\"image\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/hero-1067606.jpg\",\"articleSection\":[\"Dev\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/\",\"url\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/\",\"name\":\"Realice operaciones eficientes por fotograma de video en video con requestVideoFrameCallback () - R Marketing Digital\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/hero-1067606.jpg\",\"datePublished\":\"2022-07-28T08:01:42+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#\\\/schema\\\/person\\\/7c0d9782b2977b840b3740f00c69a73e\"},\"description\":\"Aprenda a usar el requestVideoFrameCallback() para trabajar de manera m\u00e1s eficiente con videos en el navegador. 29 de junio de 2020 Actualizado 17 de\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/dev\\\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\\\/#primaryimage\",\"url\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/hero-1067606.jpg\",\"contentUrl\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/hero-1067606.jpg\",\"width\":1200,\"height\":360,\"caption\":\"hero-1067606-2036267-jpg\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#website\",\"url\":\"https:\\\/\\\/rmarketingdigital.com\\\/\",\"name\":\"R Marketing Digital\",\"description\":\"Agencia SEO | Publicidad redes sociales | Community Management\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rmarketingdigital.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#\\\/schema\\\/person\\\/7c0d9782b2977b840b3740f00c69a73e\",\"name\":\"R Marketing Digital\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g\",\"caption\":\"R Marketing Digital\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Perform efficient operations per video frame on video with requestVideoFrameCallback() - R Digital Marketing","description":"Learn how to use the requestVideoFrameCallback () to work more efficiently with videos in the browser. June 29, 2020 Updated June 17","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/","og_locale":"en_US","og_type":"article","og_title":"Realice operaciones eficientes por fotograma de video en video con requestVideoFrameCallback ()","og_description":"Aprenda a usar el requestVideoFrameCallback() para trabajar de manera m\u00e1s eficiente con videos en el navegador. 29 de junio de 2020 Actualizado 17 de","og_url":"https:\/\/rmarketingdigital.com\/en\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/","og_site_name":"R Marketing Digital","article_published_time":"2022-07-28T08:01:42+00:00","og_image":[{"width":1200,"height":360,"url":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/hero-1067606.jpg","type":"image\/jpeg"}],"author":"R Marketing Digital","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#article","isPartOf":{"@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/"},"author":{"name":"R Marketing Digital","@id":"https:\/\/rmarketingdigital.com\/#\/schema\/person\/7c0d9782b2977b840b3740f00c69a73e"},"headline":"Realice operaciones eficientes por fotograma de video en video con requestVideoFrameCallback ()","datePublished":"2022-07-28T08:01:42+00:00","mainEntityOfPage":{"@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/"},"wordCount":1240,"image":{"@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#primaryimage"},"thumbnailUrl":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/hero-1067606.jpg","articleSection":["Dev"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/","url":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/","name":"Perform efficient operations per video frame on video with requestVideoFrameCallback() - R Digital Marketing","isPartOf":{"@id":"https:\/\/rmarketingdigital.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#primaryimage"},"image":{"@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#primaryimage"},"thumbnailUrl":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/hero-1067606.jpg","datePublished":"2022-07-28T08:01:42+00:00","author":{"@id":"https:\/\/rmarketingdigital.com\/#\/schema\/person\/7c0d9782b2977b840b3740f00c69a73e"},"description":"Learn how to use the requestVideoFrameCallback () to work more efficiently with videos in the browser. June 29, 2020 Updated June 17","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/rmarketingdigital.com\/dev\/realice-operaciones-eficientes-por-fotograma-de-video-en-video-con-requestvideoframecallback\/#primaryimage","url":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/hero-1067606.jpg","contentUrl":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/hero-1067606.jpg","width":1200,"height":360,"caption":"hero-1067606-2036267-jpg"},{"@type":"WebSite","@id":"https:\/\/rmarketingdigital.com\/#website","url":"https:\/\/rmarketingdigital.com\/","name":"R Digital Marketing","description":"SEO Agency | Advertising social networks | Community Management","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rmarketingdigital.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/rmarketingdigital.com\/#\/schema\/person\/7c0d9782b2977b840b3740f00c69a73e","name":"R Digital Marketing","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g","caption":"R Marketing Digital"}}]}},"_links":{"self":[{"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/posts\/83094","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/comments?post=83094"}],"version-history":[{"count":0,"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/posts\/83094\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/media\/83095"}],"wp:attachment":[{"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/media?parent=83094"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/categories?post=83094"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rmarketingdigital.com\/en\/wp-json\/wp\/v2\/tags?post=83094"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}