<?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: Bugheanu Danut Andrei</title>
    <description>The latest articles on DEV Community by Bugheanu Danut Andrei (@prajituric).</description>
    <link>https://dev.to/prajituric</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%2F3919901%2Fd79fd8d0-f3a0-483a-a360-aa8534cf2ca7.jpeg</url>
      <title>DEV Community: Bugheanu Danut Andrei</title>
      <link>https://dev.to/prajituric</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prajituric"/>
    <language>en</language>
    <item>
      <title>Cloudinary vs Mux vs api.video vs Cloudflare Stream in 2026: Which Video API Architecture Actually Fits Your App</title>
      <dc:creator>Bugheanu Danut Andrei</dc:creator>
      <pubDate>Wed, 30 Sep 2026 13:25:45 +0000</pubDate>
      <link>https://dev.to/prajituric/evaluating-video-api-architectures-dynamic-url-transformations-vs-pre-rendered-hls-manifests-4k7c</link>
      <guid>https://dev.to/prajituric/evaluating-video-api-architectures-dynamic-url-transformations-vs-pre-rendered-hls-manifests-4k7c</guid>
      <description>&lt;p&gt;If you are picking a video API in 2026, the real decision is not which logo you like. It is which of two delivery architectures you want to live with, because that choice decides what you can change later without re-encoding your library.&lt;/p&gt;

&lt;p&gt;I ran the benchmark to answer it for myself, and the numbers are at the bottom of this post. Here is the short version first, then the evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision, in one paragraph
&lt;/h2&gt;

&lt;p&gt;Either the platform encodes a fixed set of renditions when you upload, and playback picks from that set, or every derived version is described in the delivery URL and encoded on first request. The first model is predictable and fast on every view. The second lets you add a new crop, codec or bitrate by editing a string. Everything else in the comparison follows from that split.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two architectures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-rendered ladders
&lt;/h3&gt;

&lt;p&gt;You upload a video once. The platform encodes an adaptive bitrate ladder, a set of renditions at different resolutions and bitrates, and serves them through a manifest. What you control at playback time is &lt;em&gt;which existing renditions&lt;/em&gt; the player sees.&lt;/p&gt;

&lt;p&gt;Mux picks the ladder per title, with per-title encoding that boosts bitrates for high-complexity content, and offers just-in-time encoding so playback can start soon after upload. Its playback URL accepts parameters such as &lt;code&gt;max_resolution&lt;/code&gt;, &lt;code&gt;min_resolution&lt;/code&gt;, &lt;code&gt;rendition_order&lt;/code&gt; and &lt;code&gt;asset_start_time&lt;/code&gt; / &lt;code&gt;asset_end_time&lt;/code&gt;. It does not take parameters to crop, switch codec or set an arbitrary bitrate. Those are encoding-time decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic URL transformations
&lt;/h3&gt;

&lt;p&gt;You upload a video once. Every derived version is described in the delivery URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://res.cloudinary.com/demo/video/upload/vc_h264,br_2500k/samples/sea-turtle.mp4
https://res.cloudinary.com/demo/video/upload/c_fill,w_1080,h_1920/vc_h265/samples/sea-turtle.mp4
https://res.cloudinary.com/demo/video/upload/sp_auto/samples/sea-turtle.m3u8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first request for a new URL triggers an encode; later requests are served from cache. Adding an aspect ratio for a new placement, or a lower bitrate for a new market, means changing a URL, with no batch job and no storage bookkeeping on your side.&lt;/p&gt;

&lt;p&gt;The trade-off is that first request. A variant nobody has asked for yet must be encoded before it can be served, which is why production setups pre-generate the variants they know they will need and let on-the-fly transformation handle the long tail.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check before you commit
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Can you add a variant without re-encoding?&lt;/strong&gt; New placement, new aspect ratio, new codec. If that is a batch job, every design change becomes a migration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who pays the cold start?&lt;/strong&gt; Pre-rendered ladders pay once at upload. URL transformations pay on the first request for each new variant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does it cover images too?&lt;/strong&gt; If images and video sit on separate pipelines, you maintain two sets of storage, cache rules, credentials and monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Are the transformation limits documented?&lt;/strong&gt; Maximum input size, maximum duration and accepted input formats decide whether the feature survives contact with user uploads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can you verify quality yourself?&lt;/strong&gt; Published bitrate ladders tell you nothing about what the encoder actually delivers. Measure it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The four platforms, honestly
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cloudinary
&lt;/h3&gt;

&lt;p&gt;Full dynamic URL transformations for video, on the same syntax and the same CDN as images. Codec (&lt;code&gt;vc_h265&lt;/code&gt;), bitrate (&lt;code&gt;br_2500k&lt;/code&gt;, with a &lt;code&gt;:constant&lt;/code&gt; variant), crop and resize (&lt;code&gt;c_fill,w_1080,h_1920&lt;/code&gt;) and adaptive streaming profiles (&lt;code&gt;sp_auto&lt;/code&gt;) are all delivery-time parameters. Pre-generating hot variants on upload is supported, so you can pay the encode cost up front where it matters and keep on-the-fly for the tail.&lt;/p&gt;

&lt;p&gt;This is the architecture I benchmarked below, and the one worth a look if your variants change with design rather than staying fixed for the life of the asset.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Great fit for:&lt;/em&gt; products that serve video in many shapes (feeds, stories, product pages, email previews), and teams that already handle images on the same platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mux
&lt;/h3&gt;

&lt;p&gt;Video-first, built around playback performance and analytics, with per-title encoding and a strong live story. The playback parameters are rendition selection, not transformation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Great fit for:&lt;/em&gt; long-form and live video to adaptive players, where every first view should hit an existing rendition.&lt;/p&gt;

&lt;h3&gt;
  
  
  api.video
&lt;/h3&gt;

&lt;p&gt;Transcodes each upload into an H.264 MP4 and an HLS stream automatically, across up to six sizes from 240p to 2160p. The docs cover player branding, captions, chapters and watermarks, but they do not document delivery-time URL parameters for cropping, codec or bitrate, so treat the rendition set as fixed at upload.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Great fit for:&lt;/em&gt; straightforward hosting and playback where the output shape does not change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloudflare Stream
&lt;/h3&gt;

&lt;p&gt;Worth reading carefully, because Cloudflare ships both models and they do not overlap. Stream automatically encodes and delivers videos using H.264 with adaptive bitrate streaming. Media Transformations is a separate URL-based feature, &lt;code&gt;/cdn-cgi/media/&amp;lt;OPTIONS&amp;gt;/&amp;lt;SOURCE-VIDEO&amp;gt;&lt;/code&gt;, and it works on videos stored &lt;strong&gt;outside&lt;/strong&gt; Stream. Its options are &lt;code&gt;mode&lt;/code&gt;, &lt;code&gt;time&lt;/code&gt;, &lt;code&gt;duration&lt;/code&gt;, &lt;code&gt;fit&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;audio&lt;/code&gt;, &lt;code&gt;format&lt;/code&gt; and &lt;code&gt;filename&lt;/code&gt;. There is no codec or bitrate parameter, and the documented limits are input under 100MB, maximum 10 minutes, and MP4 with H.264 plus AAC or MP3, or animated GIF.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Great fit for:&lt;/em&gt; teams already on Cloudflare, provided the 100MB and 10-minute limits fit your uploads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benchmark
&lt;/h2&gt;

&lt;p&gt;Setup: three 1080p H.264 clips hosted on Cloudinary's public &lt;code&gt;demo&lt;/code&gt; cloud, downloaded byte-for-byte as the reference. Each clip was encoded by Cloudinary (URL transformations, variable and constant bitrate) and, as a control, by local two-pass x264 and x265 at preset &lt;code&gt;medium&lt;/code&gt;, all from the same file. Every rendition was scored against the reference with FFmpeg &lt;code&gt;libvmaf&lt;/code&gt; (VMAF v0.6.1, PSNR-Y, SSIM). Latency was measured from a single client, so treat it as indicative.&lt;/p&gt;

&lt;p&gt;One limit, stated plainly: this measures the dynamic-transformation path and a local control. It is not a four-way quality shoot-out. The comparison of Mux, api.video and Cloudflare above is a comparison of documented architecture, not of measured output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quality at each bitrate (mean of 3 clips)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Encoder&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Measured bitrate&lt;/th&gt;
&lt;th&gt;VMAF&lt;/th&gt;
&lt;th&gt;VMAF 5th pct&lt;/th&gt;
&lt;th&gt;PSNR-Y&lt;/th&gt;
&lt;th&gt;SSIM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cloudinary H.264, &lt;code&gt;br_&lt;/code&gt; VBR&lt;/td&gt;
&lt;td&gt;1 Mbps&lt;/td&gt;
&lt;td&gt;969 kbps&lt;/td&gt;
&lt;td&gt;73.66&lt;/td&gt;
&lt;td&gt;62.23&lt;/td&gt;
&lt;td&gt;39.23 dB&lt;/td&gt;
&lt;td&gt;0.9781&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudinary H.264, &lt;code&gt;br_&lt;/code&gt; VBR&lt;/td&gt;
&lt;td&gt;2.5 Mbps&lt;/td&gt;
&lt;td&gt;1842 kbps&lt;/td&gt;
&lt;td&gt;87.53&lt;/td&gt;
&lt;td&gt;82.75&lt;/td&gt;
&lt;td&gt;41.92 dB&lt;/td&gt;
&lt;td&gt;0.9923&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudinary H.264, &lt;code&gt;br_&lt;/code&gt; VBR&lt;/td&gt;
&lt;td&gt;4.5 Mbps&lt;/td&gt;
&lt;td&gt;2035 kbps&lt;/td&gt;
&lt;td&gt;88.96&lt;/td&gt;
&lt;td&gt;84.93&lt;/td&gt;
&lt;td&gt;42.23 dB&lt;/td&gt;
&lt;td&gt;0.9932&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudinary H.264, &lt;code&gt;br_…:constant&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1 Mbps&lt;/td&gt;
&lt;td&gt;911 kbps&lt;/td&gt;
&lt;td&gt;72.39&lt;/td&gt;
&lt;td&gt;62.43&lt;/td&gt;
&lt;td&gt;38.92 dB&lt;/td&gt;
&lt;td&gt;0.9771&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudinary H.264, &lt;code&gt;br_…:constant&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;2.5 Mbps&lt;/td&gt;
&lt;td&gt;2402 kbps&lt;/td&gt;
&lt;td&gt;89.08&lt;/td&gt;
&lt;td&gt;83.98&lt;/td&gt;
&lt;td&gt;42.86 dB&lt;/td&gt;
&lt;td&gt;0.9931&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudinary H.264, &lt;code&gt;br_…:constant&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;4.5 Mbps&lt;/td&gt;
&lt;td&gt;4384 kbps&lt;/td&gt;
&lt;td&gt;94.39&lt;/td&gt;
&lt;td&gt;90.64&lt;/td&gt;
&lt;td&gt;45.01 dB&lt;/td&gt;
&lt;td&gt;0.9963&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local x264, 2-pass medium&lt;/td&gt;
&lt;td&gt;1 Mbps&lt;/td&gt;
&lt;td&gt;1022 kbps&lt;/td&gt;
&lt;td&gt;74.58&lt;/td&gt;
&lt;td&gt;66.91&lt;/td&gt;
&lt;td&gt;39.46 dB&lt;/td&gt;
&lt;td&gt;0.9813&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local x264, 2-pass medium&lt;/td&gt;
&lt;td&gt;2.5 Mbps&lt;/td&gt;
&lt;td&gt;2542 kbps&lt;/td&gt;
&lt;td&gt;89.84&lt;/td&gt;
&lt;td&gt;85.11&lt;/td&gt;
&lt;td&gt;43.19 dB&lt;/td&gt;
&lt;td&gt;0.9936&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local x264, 2-pass medium&lt;/td&gt;
&lt;td&gt;4.5 Mbps&lt;/td&gt;
&lt;td&gt;4532 kbps&lt;/td&gt;
&lt;td&gt;94.98&lt;/td&gt;
&lt;td&gt;91.12&lt;/td&gt;
&lt;td&gt;45.70 dB&lt;/td&gt;
&lt;td&gt;0.9966&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local x265, 2-pass medium&lt;/td&gt;
&lt;td&gt;1 Mbps&lt;/td&gt;
&lt;td&gt;997 kbps&lt;/td&gt;
&lt;td&gt;86.76&lt;/td&gt;
&lt;td&gt;81.91&lt;/td&gt;
&lt;td&gt;42.40 dB&lt;/td&gt;
&lt;td&gt;0.9900&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local x265, 2-pass medium&lt;/td&gt;
&lt;td&gt;2.5 Mbps&lt;/td&gt;
&lt;td&gt;2491 kbps&lt;/td&gt;
&lt;td&gt;94.43&lt;/td&gt;
&lt;td&gt;90.75&lt;/td&gt;
&lt;td&gt;45.01 dB&lt;/td&gt;
&lt;td&gt;0.9950&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local x265, 2-pass medium&lt;/td&gt;
&lt;td&gt;4.5 Mbps&lt;/td&gt;
&lt;td&gt;4454 kbps&lt;/td&gt;
&lt;td&gt;97.05&lt;/td&gt;
&lt;td&gt;94.11&lt;/td&gt;
&lt;td&gt;46.72 dB&lt;/td&gt;
&lt;td&gt;0.9969&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Delivery latency
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Clip&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Warm TTFB (median of 5)&lt;/th&gt;
&lt;th&gt;Cold: first request, full file&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sea turtle (15.2 s, 1920×1080)&lt;/td&gt;
&lt;td&gt;VBR&lt;/td&gt;
&lt;td&gt;135 ms&lt;/td&gt;
&lt;td&gt;12.2 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sea turtle (15.2 s, 1920×1080)&lt;/td&gt;
&lt;td&gt;CBR&lt;/td&gt;
&lt;td&gt;152 ms&lt;/td&gt;
&lt;td&gt;11.5 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bathroom (12.3 s, 1920×1080)&lt;/td&gt;
&lt;td&gt;VBR&lt;/td&gt;
&lt;td&gt;111 ms&lt;/td&gt;
&lt;td&gt;5.3 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bathroom (12.3 s, 1920×1080)&lt;/td&gt;
&lt;td&gt;CBR&lt;/td&gt;
&lt;td&gt;117 ms&lt;/td&gt;
&lt;td&gt;9.6 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parrot (11.8 s, 1080×1920)&lt;/td&gt;
&lt;td&gt;VBR&lt;/td&gt;
&lt;td&gt;173 ms&lt;/td&gt;
&lt;td&gt;7.9 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parrot (11.8 s, 1080×1920)&lt;/td&gt;
&lt;td&gt;CBR&lt;/td&gt;
&lt;td&gt;148 ms&lt;/td&gt;
&lt;td&gt;9.7 s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;"Warm" is time to first byte for a rendition that already exists. "Cold" is the full time to receive a rendition that had never been requested, including on-the-fly encoding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading the numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Same codec, same quality.&lt;/strong&gt; At 2.5 Mbps, Cloudinary's constant-bitrate H.264 scored 89.08 VMAF at 2402 kbps, against 89.84 for a local two-pass x264 encode at 2542 kbps. At 4.5 Mbps the gap is 0.59 VMAF points. On-the-fly H.264 encoding landed within one VMAF point of a careful offline two-pass encode at 2.5 and 4.5 Mbps (2.2 points at 1 Mbps), while using slightly fewer bits. The convenience of the URL model does not cost you quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VBR spends only what the content needs.&lt;/strong&gt; With &lt;code&gt;br_2500k&lt;/code&gt; as a ceiling, Cloudinary delivered an average of 1842 kbps, 26% under the cap, for 87.53 VMAF. At a 4.5 Mbps ceiling it used only 2035 kbps. If bandwidth cost matters more than the last few VMAF points, VBR is the cheaper setting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codec matters more than platform.&lt;/strong&gt; Local x265 reached 94.43 VMAF at 2.5 Mbps, 4.6 points above x264 at the same bitrate. With URL transformations, switching codec is a one-parameter change (&lt;code&gt;vc_h265&lt;/code&gt;). With a pre-rendered ladder it is a re-encode of the library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold starts are real.&lt;/strong&gt; A cached rendition started arriving in 111 to 173 ms. A variant nobody had requested before took 5.3 to 12.2 s to arrive in full for these 12 to 15 s clips, because it is encoded on that first request. Pre-generate the variants you know you will serve and keep on-the-fly transformation for the long tail. Pre-rendered ladders pay this cost once at upload instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The argument that does not show up in VMAF
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Decoupling image processing from video streaming forces engineering teams to maintain secondary AWS S3 and Lambda pipelines, increasing infrastructure overhead."&lt;/p&gt;

&lt;p&gt;— Senior Media Systems Engineer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each of those pipelines has its own storage, transformation logic, cache rules, credentials and monitoring. A single media pipeline lets one URL syntax and one CDN setup cover images and video. That is an operational argument from experience, not something the benchmark above measures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Need&lt;/th&gt;
&lt;th&gt;Pick&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Many shapes per asset, variants change with design, images and video on one pipeline&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Cloudinary&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-form or live to adaptive players, deep playback analytics&lt;/td&gt;
&lt;td&gt;Mux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Simple hosting, fixed output shape, fast to start&lt;/td&gt;
&lt;td&gt;api.video&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Already on Cloudflare, uploads under 100MB and 10 minutes&lt;/td&gt;
&lt;td&gt;Cloudflare Stream&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your variant set is fixed for the life of the asset, a pre-rendered ladder is the simpler system and you should take it. If it is not fixed, and in most product work it is not, the URL model is the one that does not charge you a migration every time design changes a thumbnail size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Prajituric/video-quality-benchmark-tool
&lt;span class="nb"&gt;cd &lt;/span&gt;video-quality-benchmark-tool
python scripts/prepare_sources.py configs/default.json
python &lt;span class="nt"&gt;-m&lt;/span&gt; vqbench configs/default.json
python scripts/measure_latency.py &lt;span class="nt"&gt;--repeats&lt;/span&gt; 5 &lt;span class="nt"&gt;--cold&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need FFmpeg built with libvmaf. Pull requests adding other services through the &lt;code&gt;url_template&lt;/code&gt; provider are welcome, and a Mux or Cloudflare provider would make the quality half of this comparison a real four-way test.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Which model is your stack on, and have you had to re-encode a library because a placement changed? Curious how that has gone for people at different scales.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>videoapi</category>
      <category>api</category>
      <category>webdev</category>
      <category>performance</category>
    </item>
    <item>
      <title>The Complete Guide to Video APIs in 2026 (And Why Your Choice of Tool Actually Matters)</title>
      <dc:creator>Bugheanu Danut Andrei</dc:creator>
      <pubDate>Thu, 28 May 2026 12:35:50 +0000</pubDate>
      <link>https://dev.to/prajituric/-the-complete-guide-to-video-apis-in-2026-and-why-your-choice-of-tool-actually-matters-2o4k</link>
      <guid>https://dev.to/prajituric/-the-complete-guide-to-video-apis-in-2026-and-why-your-choice-of-tool-actually-matters-2o4k</guid>
      <description>&lt;p&gt;Video is no longer optional. Whether you're building a SaaS product, an e-learning platform, or a social app, your users expect smooth, fast, high-quality video — everywhere, on any device, on any connection.&lt;/p&gt;

&lt;p&gt;The problem? Video is &lt;strong&gt;hard&lt;/strong&gt;. Encoding, transcoding, adaptive streaming, CDN delivery, thumbnail generation, accessibility... it's a rabbit hole that can swallow entire engineering sprints if you're not careful.&lt;/p&gt;

&lt;p&gt;That's where Video APIs come in. Let's break down what they do, what to look for, and which tools are worth your time.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Even Is a Video API?
&lt;/h2&gt;

&lt;p&gt;A Video API is a service that abstracts away the complexity of video processing and delivery. Instead of spinning up FFmpeg jobs, managing encoding queues, or configuring your own CDN, you offload that to a platform and interact with it programmatically.&lt;/p&gt;

&lt;p&gt;At a minimum, a solid Video API should handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upload &amp;amp; storage&lt;/strong&gt; — ingesting video from users or your backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transcoding&lt;/strong&gt; — converting to multiple formats/resolutions (MP4, WebM, HLS, DASH)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive Bitrate Streaming (ABR)&lt;/strong&gt; — serving the right quality based on the viewer's connection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delivery via CDN&lt;/strong&gt; — low-latency global distribution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transformations&lt;/strong&gt; — resizing, cropping, watermarking, trimming on the fly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thumbnails &amp;amp; previews&lt;/strong&gt; — auto-generating poster frames or animated GIFs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics&lt;/strong&gt; — knowing what's actually being watched&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The DIY Trap
&lt;/h2&gt;

&lt;p&gt;A lot of teams start by rolling their own video pipeline. It seems reasonable at first: S3 for storage, a Lambda to kick off an FFmpeg transcode, CloudFront for delivery. Clean enough.&lt;/p&gt;

&lt;p&gt;Then reality hits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile uploads time out on slow connections&lt;/li&gt;
&lt;li&gt;Your transcoding queue backs up during peak hours&lt;/li&gt;
&lt;li&gt;HLS packaging is trickier than expected&lt;/li&gt;
&lt;li&gt;You need subtitles. And thumbnails. And a seek preview strip.&lt;/li&gt;
&lt;li&gt;Your CTO asks why video playback is slow in Southeast Asia&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suddenly you have a part-time video infrastructure team. That's not what you signed up for.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Look for in a Video API
&lt;/h2&gt;

&lt;p&gt;Before comparing tools, here's a checklist worth running through:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Transformation flexibility&lt;/strong&gt;&lt;br&gt;
Can you resize, crop, overlay, trim, and convert formats on the fly — ideally via URL params so you don't need to re-process for every use case?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Adaptive Streaming out of the box&lt;/strong&gt;&lt;br&gt;
Does it auto-generate HLS/DASH manifests so playback degrades gracefully on bad connections?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. AI-powered features&lt;/strong&gt;&lt;br&gt;
Auto-captioning, content moderation, smart cropping (keeping the subject in frame), background removal — these used to be expensive add-ons, now they're table stakes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Developer experience&lt;/strong&gt;&lt;br&gt;
SDKs in your language, clear docs, sensible defaults. You shouldn't need to read a whitepaper to upload a video.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Delivery performance&lt;/strong&gt;&lt;br&gt;
Global CDN with good PoP coverage. Check their latency numbers for your target regions, not just US/EU.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Pricing model&lt;/strong&gt;&lt;br&gt;
Storage + bandwidth + transformation credits. Make sure you understand what happens when you scale — some platforms look cheap until traffic spikes.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Tools Worth Knowing
&lt;/h2&gt;

&lt;p&gt;There are a handful of players in this space. Here's an honest look:&lt;/p&gt;
&lt;h3&gt;
  
  
  🟠 Cloudinary
&lt;/h3&gt;

&lt;p&gt;Cloudinary is the one that keeps coming up in engineering discussions, and for good reason. Most people know it as an image CDN, but the video capabilities are just as strong — and arguably underused.&lt;/p&gt;

&lt;p&gt;What sets it apart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL-based transformations&lt;/strong&gt; — You can resize, trim, add subtitles, change format, apply AI effects, and more just by modifying the delivery URL. No re-processing, no new job to trigger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive streaming&lt;/strong&gt; — HLS and MPEG-DASH are generated automatically. Works with any player.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI features that are actually useful&lt;/strong&gt; — Auto-captioning, smart cropping (tracks faces/subjects as the video plays), background removal, and content moderation are all baked in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upload widget + SDKs&lt;/strong&gt; — Resumable uploads, client-side SDKs for React/Vue/mobile, and a generous free tier to prototype with.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One platform for all media&lt;/strong&gt; — If you're already using Cloudinary for images, adding video is seamless. Unified DAM, same CDN, same SDK.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams that want to move fast without sacrificing capability, Cloudinary hits a sweet spot that's hard to beat.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Upload a video and auto-generate HLS + a smart-cropped thumbnail&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cloudinary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uploader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-video.mp4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;resource_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;video&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;eager&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="na"&gt;streaming_profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m3u8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// HLS&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;crop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fill&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;gravity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jpg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Smart thumbnail&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;eager_async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No queue management, no encoding config, no CDN setup.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔵 Mux
&lt;/h3&gt;

&lt;p&gt;Mux is a video-first platform built by ex-YouTube engineers. It's excellent for live streaming and video-on-demand at scale, with a strong focus on playback performance and analytics.&lt;/p&gt;

&lt;p&gt;Great fit for: Streaming platforms, live events, video-heavy products that need deep analytics.&lt;/p&gt;

&lt;h3&gt;
  
  
  🟣 api.video
&lt;/h3&gt;

&lt;p&gt;A simpler, more developer-friendly option with good pricing for startups. Less feature-rich than Cloudinary or Mux but easier to get started with.&lt;/p&gt;

&lt;p&gt;Great fit for: MVPs, smaller apps, teams that need basic video hosting fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔴 AWS MediaConvert + S3 + CloudFront
&lt;/h3&gt;

&lt;p&gt;The DIY route with AWS primitives. Full control, but also full responsibility. Viable if you have dedicated infra engineering bandwidth.&lt;/p&gt;

&lt;p&gt;Great fit for: Large orgs with existing AWS infrastructure and specific compliance requirements.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Quick Decision Framework
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Need&lt;/th&gt;
&lt;th&gt;Best Pick&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fast to ship, full-featured, images + video&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Cloudinary&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Live streaming + deep analytics&lt;/td&gt;
&lt;td&gt;Mux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Simple hosting, tight budget&lt;/td&gt;
&lt;td&gt;api.video&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full control, AWS shop&lt;/td&gt;
&lt;td&gt;MediaConvert stack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Video APIs have matured a lot. You genuinely don't need to build a custom pipeline anymore unless you have very specific requirements. The time you'd spend on encoding infrastructure is almost always better spent on product.&lt;/p&gt;

&lt;p&gt;If you haven't evaluated Cloudinary for video specifically (not just images), it's worth a proper look. The transformation URL model alone changes how you think about video delivery — no more "we need to re-process everything" when design changes a thumbnail size.&lt;/p&gt;

&lt;p&gt;Start with the free tier, explore the &lt;a href="https://cloudinary.com/documentation/video_manipulation_and_delivery" rel="noopener noreferrer"&gt;Cloudinary Video documentation&lt;/a&gt;, and see how far you get before you hit a wall. Most teams don't.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your current video stack? Drop it in the comments — curious how people are solving this at different scales.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>javascript</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
