<?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: Ronald Gosso</title>
    <description>The latest articles on DEV Community by Ronald Gosso (@ronaldgosso).</description>
    <link>https://dev.to/ronaldgosso</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4167250%2F5a2f27e8-acb9-47c8-ae72-0136d9c47167.jpg</url>
      <title>DEV Community: Ronald Gosso</title>
      <link>https://dev.to/ronaldgosso</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ronaldgosso"/>
    <language>en</language>
    <item>
      <title>I got tired of fighting ffmpeg for basic video trimming, so I built clipflow</title>
      <dc:creator>Ronald Gosso</dc:creator>
      <pubDate>Wed, 07 Oct 2026 03:06:10 +0000</pubDate>
      <link>https://dev.to/ronaldgosso/i-got-tired-of-fighting-ffmpeg-for-basic-video-trimming-so-i-built-clipflow-4eb4</link>
      <guid>https://dev.to/ronaldgosso/i-got-tired-of-fighting-ffmpeg-for-basic-video-trimming-so-i-built-clipflow-4eb4</guid>
      <description>&lt;p&gt;I got tired of fighting &lt;code&gt;ffmpeg&lt;/code&gt; for basic video trimming. So I built &lt;code&gt;clipflow&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You know the drill. You just want to trim a 10-minute video. &lt;/p&gt;

&lt;p&gt;You open a terminal and type:&lt;br&gt;
&lt;code&gt;ffmpeg -i input.mp4 -ss 00:30 -to 02:15 -c copy output.mp4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then you pray you got the flags right. &lt;/p&gt;

&lt;p&gt;But wait, you need frame-accurate cutting. So you scrap &lt;code&gt;-c copy&lt;/code&gt;. Now you are re-encoding a 4 GB file. Twenty minutes later, you are still staring at a progress bar.&lt;/p&gt;

&lt;p&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%2F7u5n5izznoc4a08zgnp4.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%2F7u5n5izznoc4a08zgnp4.png" alt="R.I.P. to the 400MB node_modules folder" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hit this wall for the fifteenth time last month. Honestly, enough was enough. I decided to build a better way.&lt;/p&gt;
&lt;h3&gt;
  
  
  What &lt;code&gt;clipflow&lt;/code&gt; actually does
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;clipflow&lt;/code&gt; is a typed Python API and CLI for video clipping. &lt;/p&gt;

&lt;p&gt;It manages &lt;code&gt;ffmpeg&lt;/code&gt; for you. It auto-downloads the binary on first use, caches it locally, and falls back to your system &lt;code&gt;PATH&lt;/code&gt; if you already have it installed. &lt;/p&gt;

&lt;p&gt;No manual setup. No "install ffmpeg first" warnings.&lt;/p&gt;

&lt;p&gt;Here is the core idea. It builds and runs &lt;code&gt;ffmpeg&lt;/code&gt; commands directly as subprocess calls. &lt;/p&gt;

&lt;p&gt;No NumPy array conversions. No memory-heavy frame processing. Just clean, typed dataclasses going in and structured results coming out.&lt;/p&gt;
&lt;h3&gt;
  
  
  Three things I obsessed over
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lossless stream-copy by default.&lt;/strong&gt; Trimming a 10 GB file takes seconds with zero quality loss. Need frame-accurate cuts? Just flip a &lt;code&gt;compress&lt;/code&gt; flag and it re-encodes properly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Highlights as a first-class concept.&lt;/strong&gt; Most Python video libraries treat highlights as an afterthought. In &lt;code&gt;clipflow&lt;/code&gt;, you mark a clip with &lt;code&gt;highlight=True&lt;/code&gt;. It automatically copies that slice to a &lt;code&gt;highlights/&lt;/code&gt; directory. That is it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero runtime dependencies.&lt;/strong&gt; The library uses only the Python standard library plus the &lt;code&gt;ffmpeg&lt;/code&gt; binary it manages. No bloated dependency tree to debug.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Quick taste
&lt;/h3&gt;

&lt;p&gt;Here is what the Python API looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;clipflow&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;clipflow&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ClipSpec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parse_range&lt;/span&gt;

&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clipflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;raw_footage.mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;ClipSpec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;parse_range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;05:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;06:30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;highlight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;compress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COMPRESS_HIGH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;aspect_ratio&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AR_9_16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hero_moment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;output_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;highlight_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# out/highlights/hero_moment.mp4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the CLI is just as straightforward:&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;# Lossless trim&lt;/span&gt;
clipflow trim lecture.mp4 01:00-02:30

&lt;span class="c"&gt;# Compress + crop + highlight&lt;/span&gt;
clipflow trim concert.mp4 05:00-06:30 &lt;span class="nt"&gt;--compress&lt;/span&gt; high &lt;span class="nt"&gt;--aspect&lt;/span&gt; 9:16 &lt;span class="nt"&gt;--highlight&lt;/span&gt;

&lt;span class="c"&gt;# Inspect metadata&lt;/span&gt;
clipflow inspect documentary.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&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%2F0coocq37wmwgsqbf6bag.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%2F0coocq37wmwgsqbf6bag.png" alt="Scenario A: 20 minutes and 4GB of re-encode. Scenario B: 2 seconds, lossless." width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why not just use &lt;code&gt;moviepy&lt;/code&gt; or &lt;code&gt;ffmpeg-python&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Good question. I asked myself the same thing.&lt;/p&gt;

&lt;p&gt;Most Python video libraries convert frames to NumPy arrays. That is slow. It is memory-heavy. And it is completely unnecessary for simple trimming.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clipflow&lt;/code&gt; does not touch a single frame. It just constructs the &lt;code&gt;ffmpeg&lt;/code&gt; command and runs it as a subprocess. &lt;/p&gt;

&lt;p&gt;The entire subprocess layer is isolated in &lt;code&gt;clipflow/_ffmpeg.py&lt;/code&gt;. You can audit exactly what is being executed. No magic.&lt;/p&gt;

&lt;p&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%2Fqa1p9lnna9o726zkrm9f.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%2Fqa1p9lnna9o726zkrm9f.png" alt="" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Under the hood
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Pure Python (requires ≥ 3.9). No Swift or Rust wrappers.&lt;/li&gt;
&lt;li&gt;Cross-platform support for macOS 14+, Windows, and Linux.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ffmpeg&lt;/code&gt; auto-downloaded and cached per platform.&lt;/li&gt;
&lt;li&gt;82 tests with &amp;gt;90% coverage.&lt;/li&gt;
&lt;li&gt;Docker-ready for instant local development.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What is next
&lt;/h3&gt;

&lt;p&gt;I am currently working on batch processing improvements and a highlight-reel example script. &lt;/p&gt;

&lt;p&gt;The repo is open and MIT licensed. &lt;/p&gt;

&lt;p&gt;If you have ever spent more time fighting &lt;code&gt;ffmpeg&lt;/code&gt; than actually editing video, give it a shot. And if something breaks, open an issue. I read every single one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;GitHub: &lt;a href="//github.com/ronaldgosso/clipflow"&gt;github.com/ronaldgosso/clipflow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docker Hub: &lt;a href="https://hub.docker.com/r/ronaldgosso/clipflow" rel="noopener noreferrer"&gt;ronaldgosso/clipflow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyPI: &lt;code&gt;pip install clipflow&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>python</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>ffmpeg</category>
    </item>
  </channel>
</rss>
