<?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>DEV Community: nRn World</title>
    <description>The latest articles on DEV Community by nRn World (@nrnworld).</description>
    <link>https://dev.to/nrnworld</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4192738%2F3860350f-43d0-4703-a7ec-171d43448078.gif</url>
      <title>DEV Community: nRn World</title>
      <link>https://dev.to/nrnworld</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nrnworld"/>
    <language>en</language>
    <item>
      <title>Why seeking in Electron's video player stutters – and how I fixed it</title>
      <dc:creator>nRn World</dc:creator>
      <pubDate>Sun, 18 Oct 2026 19:06:38 +0000</pubDate>
      <link>https://dev.to/nrnworld/why-seeking-in-electrons-stutters-and-how-i-fixed-it-16m5</link>
      <guid>https://dev.to/nrnworld/why-seeking-in-electrons-stutters-and-how-i-fixed-it-16m5</guid>
      <description>&lt;p&gt;I built a video player called &lt;a href="https://github.com/nRn-World/DoggyPlayer" rel="noopener noreferrer"&gt;Doggy Player&lt;/a&gt; because seeking in the players I tried always felt janky. When I moved to Electron, I hit the same problem in a new form: Chromium's &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; element is great at playing files and surprisingly bad at jumping around in some of them. This is what I found, and what I did about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why seeking is slow
&lt;/h2&gt;

&lt;p&gt;To show a frame at an arbitrary position, a decoder has to start from the previous keyframe (IDR) and decode forward from there. If keyframes are 8 seconds apart, a seek can mean decoding several seconds of video before anything appears.&lt;/p&gt;

&lt;p&gt;In my measurements on files of identical size, the median seek took about &lt;strong&gt;217 ms with an 8.3 s GOP&lt;/strong&gt; and about &lt;strong&gt;30 ms with a 1 s GOP&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 1: ".mp4" files that are not MP4
&lt;/h2&gt;

&lt;p&gt;Some files carry an &lt;code&gt;.mp4&lt;/code&gt; extension but are really MPEG-TS. Chromium plays them, but freezes for about a second on every seek.&lt;/p&gt;

&lt;p&gt;The fix: probe the real container with ffprobe, and if it doesn't match, remux once with stream copy and &lt;code&gt;-movflags +faststart&lt;/code&gt;. There is no quality loss, it takes seconds, and the result is cached so the next open is instant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 2: sparse keyframes
&lt;/h2&gt;

&lt;p&gt;For long-GOP sources, the only way to get YouTube/VLC-class seeking is to re-encode with a dense keyframe interval. That is lossy and slow, so I only do it in the background for files shorter than 30 minutes, cache the result (capped at 10 GB) and clean up leftovers from interrupted conversions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 3: the seek controller
&lt;/h2&gt;

&lt;p&gt;Even with good files, the UI layer matters. Early versions seeked on key-down &lt;em&gt;and&lt;/em&gt; key-up, which replayed a fraction of a second after every press and was audible as a stutter. The rules I settled on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one key press = exactly one seek&lt;/li&gt;
&lt;li&gt;holding an arrow key scrubs smoothly and resumes playback on release&lt;/li&gt;
&lt;li&gt;rapid presses coalesce (last one wins) instead of stacking decode jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A security note
&lt;/h2&gt;

&lt;p&gt;Serving local files to the renderer over HTTP means any web page could try to read them. The local media server now requires a per-run random token, and file names are never passed through a shell when reading video length.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Doggy Player is source-available and free for personal use, with builds for Windows, macOS and Linux:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/nRn-World" rel="noopener noreferrer"&gt;
        nRn-World
      &lt;/a&gt; / &lt;a href="https://github.com/nRn-World/DoggyPlayer" rel="noopener noreferrer"&gt;
        DoggyPlayer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🐶 Doggy Player a modern Electron video player for Windows with VLC-style gapless seeking, subtitles, playlists and IPTV.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/nRn-World/DoggyPlayer/public/logo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fraw.githubusercontent.com%2FnRn-World%2FDoggyPlayer%2FHEAD%2Fpublic%2Flogo.gif" alt="Doggy Player logo" width="160"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Doggy Player 🐶&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;b&gt;A fast, dark, modern video player with VLC-style instant seeking, zoom &amp;amp; rotate, subtitles and built-in IPTV.&lt;/b&gt;&lt;br&gt;
  Source-available · Free for personal use · Windows · macOS · Linux
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://github.com/nRn-World/DoggyPlayer/releases/latest" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4e84520b2821cb1beed47de0cfc912a446769cbb5aece71594a9204f5df49e58/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f254532254143253837253230446f776e6c6f61642d6c617465737425323072656c656173652d3265613434663f7374796c653d666f722d7468652d6261646765" alt="Download latest release"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://github.com/nRn-World/DoggyPlayer/releases/latest" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9db36bc1ec0c53d5c4ff584542cb4fe019dafe646ac75ca910ddd8c631fb2e17/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6e526e2d576f726c642f446f676779506c617965723f736f72743d73656d766572266c6162656c3d6c617465737426636f6c6f723d326561343466" alt="Latest release"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/nRn-World/DoggyPlayer/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3ac89b86d59d80d162fbbbe26997bce0b5e0f4ab1d42dd23d4af64c7038e9735/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f6e526e2d576f726c642f446f676779506c617965722f746f74616c3f6c6162656c3d646f776e6c6f61647326636f6c6f723d626c7565" alt="Downloads"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/nRn-World/DoggyPlayer/stargazers" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ccdfe435b627ed7633d9b1666a15d2da50555b621346f51260a312a2615ad4e0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6e526e2d576f726c642f446f676779506c617965723f7374796c653d666c6174266c6162656c3d737461727326636f6c6f723d79656c6c6f77" alt="Stars"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/nRn-World/DoggyPlayer/LICENSE.txt" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f1ed873d4738816be06818bef4a0abe62ee838e28a659ccaa21c323c85f78892/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d434325323042592d2d4e43253230342e302d7265642e737667" alt="License: CC BY-NC 4.0"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/2e3acb0c0e597fd1e491cbb906fac7143a1bae1960b213a26428ef32bc2461b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d57696e646f77732532302537432532306d61634f532532302537432532304c696e75782d3030373844362e737667"&gt;&lt;img src="https://camo.githubusercontent.com/2e3acb0c0e597fd1e491cbb906fac7143a1bae1960b213a26428ef32bc2461b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d57696e646f77732532302537432532306d61634f532532302537432532304c696e75782d3030373844362e737667" alt="Platforms"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/26b9cbcf9f4ee98cae591cd10d77cc9b68c9083fb82c84fe21a8c8750e209a76/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f456c656374726f6e2d526561637425323031392d3631444146422e737667"&gt;&lt;img src="https://camo.githubusercontent.com/26b9cbcf9f4ee98cae591cd10d77cc9b68c9083fb82c84fe21a8c8750e209a76/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f456c656374726f6e2d526561637425323031392d3631444146422e737667" alt="Electron + React"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://github.com/nRn-World/DoggyPlayer/Screenshot/Sc1.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FnRn-World%2FDoggyPlayer%2FHEAD%2FScreenshot%2FSc1.png" alt="Doggy Player main interface" width="80%"&gt;&lt;/a&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why Doggy Player?&lt;/h2&gt;
&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;strong&gt;Seeking that just works.&lt;/strong&gt; Jump anywhere in a long film instantly — no stutter, no audio "vibration", no frozen frame. Files Chromium can't seek well are quietly converted once in the background and cached.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Zoom into the picture.&lt;/strong&gt; Mouse-wheel zoom, click-to-pan, or hold &lt;code&gt;Shift&lt;/code&gt; and draw a rectangle to zoom into a detail.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Fix bad videos on the fly.&lt;/strong&gt; Rotate with &lt;code&gt;Alt + Arrow&lt;/code&gt;, adjust brightness 50–150 %, and lock the setting per video so it comes back next time.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Everything in one place.&lt;/strong&gt; Playlists, subtitles (&lt;code&gt;.srt&lt;/code&gt; &lt;code&gt;.vtt&lt;/code&gt; &lt;code&gt;.ass&lt;/code&gt;), an equalizer and IPTV (Xtream Codes, M3U, EPG) — no plugins to hunt for.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Private by design.&lt;/strong&gt; Nothing leaves your machine except an…&lt;/li&gt;

&lt;/ul&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/nRn-World/DoggyPlayer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;If you have a file that seeks badly, please open an issue. That's the best feedback I can get, and there are a few &lt;code&gt;good first issue&lt;/code&gt; tasks if you'd like to contribute.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2m30u0gz9jwwbct1gk81.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2m30u0gz9jwwbct1gk81.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>electron</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
