<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Martin Stark</title>
    <description>The latest articles on Forem by Martin Stark (@martinstark).</description>
    <link>https://forem.com/martinstark</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F251163%2Fcad1be70-048e-4c47-87e5-aae83c0630e5.png</url>
      <title>Forem: Martin Stark</title>
      <link>https://forem.com/martinstark</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/martinstark"/>
    <language>en</language>
    <item>
      <title>nvoc - linux OC/UV cli utility for RTX-50 series</title>
      <dc:creator>Martin Stark</dc:creator>
      <pubDate>Fri, 26 Sep 2025 08:22:26 +0000</pubDate>
      <link>https://forem.com/martinstark/nvoc-linux-ocuv-cli-utility-for-rtx-50-series-3fgd</link>
      <guid>https://forem.com/martinstark/nvoc-linux-ocuv-cli-utility-for-rtx-50-series-3fgd</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/martinstark/nvoc/" rel="noopener noreferrer"&gt;https://github.com/martinstark/nvoc/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I got tired of having to create multi-line scripts for applying a semblance of overclocking/undervolting on Linux, so I wrote a cli app that does it in a single line, example for 5090:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo nvoc -c 200,2820 -o 900 -m 3000 -p 105&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;-c = min,max core clocks&lt;br&gt;
-o = graphics offset&lt;br&gt;
-m = memory offset&lt;br&gt;
-p = power limit&lt;/p&gt;

&lt;p&gt;Since it's only possible to set a full curve offset on Linux (there is no per-voltage offset like in MSI Afterburner), and I don't want my idle clocks to be ~1100mhz, I wanted a utility to quickly apply and reset the OC when I need it.&lt;/p&gt;

&lt;p&gt;NVIDIA kindly removed the ability to query GPU voltage from their Linux APIs. Due to that, I think the only way to simulate MSI Afterburner-like behaviour, where you can have default idle clocks (200mhz) and have an offset for higher load scenarios, would be to set up an elevated service that applies the OC as soon as the GPU goes above ~2000mhz, and resets the OC if the clocks drop down below 2000mhz for a number of seconds.&lt;/p&gt;

&lt;p&gt;Functionality&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Show GPU information&lt;/span&gt;
nvoc info

&lt;span class="c"&gt;# OC&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nvoc &lt;span class="nt"&gt;-c&lt;/span&gt; MIN,MAX &lt;span class="nt"&gt;-o&lt;/span&gt; OFFSET &lt;span class="nt"&gt;-m&lt;/span&gt; MEM_OFFSET &lt;span class="nt"&gt;-p&lt;/span&gt; POWER_LIMIT

&lt;span class="c"&gt;# Reset&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nvoc reset

&lt;span class="c"&gt;# Dry Run&lt;/span&gt;
nvoc &lt;span class="nt"&gt;-c&lt;/span&gt; 200,2800 &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;info output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;nvoc info
Driver 580.82.09
0: NVIDIA GeForce RTX 5090
Blackwell v16777240
GPU: 1177MHz
GPU Offset: 960MHz
Mem: 15501MHz
Temp: 56°C
Power: 45W
Power Limit: 600W &lt;span class="o"&gt;(&lt;/span&gt;104% of default&lt;span class="o"&gt;)&lt;/span&gt;
Power Range: 400W-575W &lt;span class="o"&gt;(&lt;/span&gt;hard limit: 600W&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>tooling</category>
      <category>performance</category>
      <category>cli</category>
      <category>linux</category>
    </item>
    <item>
      <title>Client Side Ad Insertion Crash Course</title>
      <dc:creator>Martin Stark</dc:creator>
      <pubDate>Wed, 29 May 2024 12:43:28 +0000</pubDate>
      <link>https://forem.com/video/client-side-ad-insertion-crash-course-4fdm</link>
      <guid>https://forem.com/video/client-side-ad-insertion-crash-course-4fdm</guid>
      <description>&lt;p&gt;This guide acts as a quick overview of concepts relevant to CSAI, it is not meant to act as a complete tutorial. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is CSAI?
&lt;/h2&gt;

&lt;p&gt;Client Side Ad Insertion means that the app on the user's device is responsible for fetching and displays advertisement as part of the streaming experience. This is in contrast to Server Side Ad Insertion, where the ads are stitched into the video on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  VMAP
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.iab.com/guidelines/vmap/" rel="noopener noreferrer"&gt;VMAP&lt;/a&gt; is fetched or polled by the client, it is parsed to check when an ad break should occur.  &lt;/p&gt;

&lt;h2&gt;
  
  
  VAST
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.iab.com/guidelines/vast/" rel="noopener noreferrer"&gt;VAST&lt;/a&gt; document is fetched and parsed by the client, it represents the content of an ad break.&lt;/p&gt;

&lt;p&gt;The VAST document can contain several types of ads. For example: video, images, and companion links.&lt;/p&gt;

&lt;p&gt;The VAST specifies how an ad should be tracked. It says which events need to be sent to a tracking server in order to verify if and how much of the ad was watched and/or interacted with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Displaying the Ads
&lt;/h2&gt;

&lt;p&gt;When it is time to show the ad to the user, it is usually handled by pausing the content stream, creating a new video element, overlaying it on the content stream, and playing the ad(s). When the ad break is finished, remove the ad specific video element and resume the content stream.&lt;/p&gt;

</description>
      <category>csai</category>
      <category>ads</category>
      <category>video</category>
      <category>streaming</category>
    </item>
    <item>
      <title>Interpreting HTML5 Video Events</title>
      <dc:creator>Martin Stark</dc:creator>
      <pubDate>Mon, 13 Mar 2023 12:05:55 +0000</pubDate>
      <link>https://forem.com/video/interpreting-html5-video-events-2j54</link>
      <guid>https://forem.com/video/interpreting-html5-video-events-2j54</guid>
      <description>&lt;p&gt;When building a HTML5 web video player, it tends to need a user interface, quality of service tracking, user interaction tracking, and sometimes ad tracking. To achieve this, the &lt;a href="https://html.spec.whatwg.org/multipage/media.html#mediaevents" rel="noopener noreferrer"&gt;HTML5 Media Event&lt;/a&gt; standard needs to be interpreted.&lt;/p&gt;

&lt;p&gt;After building multiple web video players, and having worked on more than one iteration of an event interpreter, something didn't feel right. Things weren't kept &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;DRY&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When repetition strikes, it's usually a good idea to do something about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Media Event Filter
&lt;/h2&gt;

&lt;p&gt;Enter &lt;a href="https://www.npmjs.com/package/@eyevinn/media-event-filter" rel="noopener noreferrer"&gt;@eyevinn/media-event-filter&lt;/a&gt;, a filter that interprets HTML5 media events in a way that makes sense.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This filter aims to provide a single source of truth that can be used across player engines and native browser playback.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whether using one or multiple player engines, like &lt;a href="https://github.com/shaka-project/shaka-player/" rel="noopener noreferrer"&gt;Shaka Player&lt;/a&gt;, &lt;a href="https://github.com/video-dev/hls.js/" rel="noopener noreferrer"&gt;HLS.js&lt;/a&gt;, or &lt;a href="https://github.com/Dash-Industry-Forum/dash.js/" rel="noopener noreferrer"&gt;dash.js&lt;/a&gt;, the filter will output a standardised event sequence. It does so without relying on events output by the player engine, giving applications a single, player agnostic, source of truth for video playback state updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Implementation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getMediaEventFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FilteredMediaEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@eyevinn/media-event-filter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;videoElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;video&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mediaEventFilter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getMediaEventFilter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;videoElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FilteredMediaEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;FilteredMediaEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LOADED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// handle loaded&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;FilteredMediaEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BUFFERING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// handle buffering&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;FilteredMediaEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BUFFERED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;// handle buffered&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create a player, using your engine of choice&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;videoElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Load a manifest and play&lt;/span&gt;
&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Call when done&lt;/span&gt;
&lt;span class="nx"&gt;mediaEventFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;teardown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Live Example
&lt;/h2&gt;

&lt;p&gt;See a barebones &lt;a href="https://codepen.io/atlimar/pen/wvEmpXM" rel="noopener noreferrer"&gt;React + Shaka + Media Event Filter&lt;/a&gt; example over at codepen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;While making the filter open source is recent, it has been battle tested for years. With millions of playback sessions, multiple third party tracking systems have been validated using the filter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Sequence
&lt;/h2&gt;

&lt;p&gt;The sequence follows the &lt;a href="https://github.com/Eyevinn/player-analytics-specification" rel="noopener noreferrer"&gt;Eyevinn Player Analytics Specification&lt;/a&gt;, which maps directly to many popular tracking service provider SDKs.&lt;/p&gt;

&lt;p&gt;Sample event sequence comparison, using &lt;code&gt;&amp;lt;video autoplay&amp;gt;&lt;/code&gt; with Shaka Player in Firefox, excluding &lt;code&gt;timeupdate&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Native&lt;/th&gt;
&lt;th&gt;Filtered&lt;/th&gt;
&lt;th&gt;Comment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Shaka sets playback rate to 0 to control buffering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;durationchange&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;resize&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;loadedmetadata&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;loadeddata&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplay&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;play&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplaythrough&lt;/td&gt;
&lt;td&gt;loaded&lt;/td&gt;
&lt;td&gt;video is ready to start playing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;video is playing, play event missing due to autoplay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pause&lt;/td&gt;
&lt;td&gt;pause&lt;/td&gt;
&lt;td&gt;manual pause&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;seeking while paused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Shaka sets playback rate to 0 to control buffering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;play&lt;/td&gt;
&lt;td&gt;play&lt;/td&gt;
&lt;td&gt;Play requested during a seek&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;waiting&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplay&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplaythrough&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;video element thinks it can start playing, but playback rate is 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;shaka returns playback rate to normal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;video is playing again after previous pause&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pause&lt;/td&gt;
&lt;td&gt;pause&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;play&lt;/td&gt;
&lt;td&gt;play&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;seeking while playing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;waiting&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplay&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplaythrough&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;seek finished, video is rolling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;buffering&lt;/td&gt;
&lt;td&gt;buffer empty, shaka sets playbackrate to 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplaythrough&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;video element thinks it can start playing, but playback rate is 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;buffered&lt;/td&gt;
&lt;td&gt;shaka returns playback rate to normal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;waiting&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplay&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplaythrough&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ratechange&lt;/td&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;durationchange&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;seeking&lt;/td&gt;
&lt;td&gt;seeking within buffer, no ratechange&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;waiting&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;seeked&lt;/td&gt;
&lt;td&gt;seek finished&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplay&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;playing&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;canplaythrough&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pause&lt;/td&gt;
&lt;td&gt;pause&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ended&lt;/td&gt;
&lt;td&gt;ended&lt;/td&gt;
&lt;td&gt;end of stream reached&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;emptied&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Download it at &lt;a href="https://www.npmjs.com/package/@eyevinn/media-event-filter" rel="noopener noreferrer"&gt;npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Contribute at &lt;a href="https://github.com/Eyevinn/media-event-filter" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>streaming</category>
      <category>typescript</category>
      <category>html5video</category>
    </item>
    <item>
      <title>HTML5 subtitles with dynamic width on OSX</title>
      <dc:creator>Martin Stark</dc:creator>
      <pubDate>Thu, 17 Mar 2022 15:28:46 +0000</pubDate>
      <link>https://forem.com/video/html5-subtitles-with-dynamic-width-on-osx-1da1</link>
      <guid>https://forem.com/video/html5-subtitles-with-dynamic-width-on-osx-1da1</guid>
      <description>&lt;p&gt;If you've run into subtitles taking up 100% width of the HTML5 video player window, which is common in Chrome or Safari on OSX, here is a neat styling trick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;::-webkit-media-text-track-display&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;prevent&lt;/span&gt; &lt;span class="err"&gt;subtitles&lt;/span&gt; &lt;span class="err"&gt;from&lt;/span&gt; &lt;span class="err"&gt;taking&lt;/span&gt; &lt;span class="err"&gt;up&lt;/span&gt; &lt;span class="err"&gt;100%&lt;/span&gt; &lt;span class="err"&gt;width&lt;/span&gt;
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;while&lt;/span&gt; &lt;span class="err"&gt;remaining&lt;/span&gt; &lt;span class="err"&gt;centered&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;prevent&lt;/span&gt; &lt;span class="err"&gt;unexpected&lt;/span&gt; &lt;span class="err"&gt;line&lt;/span&gt; &lt;span class="err"&gt;breaks,&lt;/span&gt; &lt;span class="err"&gt;since&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt;  
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;above&lt;/span&gt; &lt;span class="err"&gt;styling&lt;/span&gt; &lt;span class="err"&gt;will&lt;/span&gt; &lt;span class="err"&gt;otherwise&lt;/span&gt; &lt;span class="err"&gt;force&lt;/span&gt; &lt;span class="err"&gt;50%&lt;/span&gt; &lt;span class="err"&gt;width&lt;/span&gt;
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;on&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;subtitle&lt;/span&gt; &lt;span class="err"&gt;element&lt;/span&gt;
  &lt;span class="nl"&gt;white-space&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will center the subtitle element, make sure it keeps a dynamic width, and prevent unexpected line-breaks.&lt;/p&gt;

&lt;p&gt;Since the fix maintains native subtitle rendering, it allows for operating system level accessibility options to be applied.&lt;/p&gt;

</description>
      <category>html5video</category>
      <category>subtitles</category>
      <category>css</category>
      <category>ttml</category>
    </item>
    <item>
      <title>The equivalent of componentWillMount using React hooks</title>
      <dc:creator>Martin Stark</dc:creator>
      <pubDate>Thu, 29 Apr 2021 12:29:48 +0000</pubDate>
      <link>https://forem.com/video/the-equivalent-of-componentwillmount-using-react-hooks-11em</link>
      <guid>https://forem.com/video/the-equivalent-of-componentwillmount-using-react-hooks-11em</guid>
      <description>&lt;h2&gt;
  
  
  Given that
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;the goal is to execute some code once, before the ui is updated&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;componentWillMount&lt;/code&gt; is deprecated (&lt;a href="https://reactjs.org/docs/react-component.html#unsafe_componentwillmount" rel="noopener noreferrer"&gt;1&lt;/a&gt;, &lt;a href="https://stackoverflow.com/questions/49206280/componentwillmount-is-deprecated-and-will-be-removed-in-the-next-major-version-0/49213753#49213753" rel="noopener noreferrer"&gt;2&lt;/a&gt;, &lt;a href="https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html" rel="noopener noreferrer"&gt;3&lt;/a&gt;), and that the suggested replacement is executing code in the &lt;code&gt;constructor&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;code executed before the return statement of a functional component is implicitly run before rendering it&lt;/li&gt;
&lt;li&gt;the rough equivalent of mounting a class component is the initial call of a functional component&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The solution would be
&lt;/h2&gt;

&lt;p&gt;Calling a function in the body of the functional component once. This can potentially be achieved with &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useMemo&lt;/code&gt;, or &lt;code&gt;useEffect&lt;/code&gt;, depending on the timing required for the use case.&lt;/p&gt;

&lt;p&gt;Since the code needs to run before the initial render is committed to the screen, this disqualifies &lt;code&gt;useEffect&lt;/code&gt;, as “The function passed to useEffect will run after the render is committed to the screen.” &lt;a href="https://reactjs.org/docs/hooks-reference.html#useeffect" rel="noopener noreferrer"&gt;4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since we want to guarantee that the code will only run once, this disqualifies &lt;code&gt;useMemo&lt;/code&gt;, as "In the future, React may choose to “forget” some previously memoized values and recalculate them on next render" &lt;a href="https://reactjs.org/docs/hooks-reference.html#usememo" rel="noopener noreferrer"&gt;5&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useState&lt;/code&gt; supports &lt;a href="https://reactjs.org/docs/hooks-reference.html#lazy-initial-state" rel="noopener noreferrer"&gt;lazy initial state&lt;/a&gt; calculations that are guaranteed to only run once during the initial render, which seems like a good candidate for the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example with useState:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runOnceBeforeRender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runOnceBeforeRender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  As a custom hook:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runOnceBeforeRender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useBeforeInitialRender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useBeforeInitialRender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runOnceBeforeRender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;runOnceBeforeRender&lt;/code&gt; function can optionally return a state that will be available immediately upon the first render of the function, triggering no re-renders.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://www.npmjs.com/package/@martinstark/use-once" rel="noopener noreferrer"&gt;use-once&lt;/a&gt; on npm.&lt;/p&gt;

</description>
      <category>react</category>
      <category>hooks</category>
      <category>componentwillmount</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
