How Z-API Handles Video Conversion <meta name="title" content="How Z-API Handles Video Conversion"> <meta name="description" content="A technical walkthrough of the pipeline that normalizes arbitrary video uploads into universally playable MP4 files."> <!-- Open Graph / Facebook --> <meta property="og:type" content="website"> <meta property="og:url" content="https://joaomadeira.xyz/en/blog/how-z-api-handles-video-conversion/"> <meta property="og:title" content="How Z-API Handles Video Conversion"> <meta property="og:description" content="A technical walkthrough of the pipeline that normalizes arbitrary video uploads into universally playable MP4 files."> <meta property="og:image" content="https://joaomadeira.xyz/blog-placeholder-1.jpg"> <!-- Twitter --> <meta property="twitter:card" content="summary_large_image"> <meta property="twitter:url" content="https://joaomadeira.xyz/en/blog/how-z-api-handles-video-conversion/"> <meta property="twitter:title" content="How Z-API Handles Video Conversion"> <meta property="twitter:description" content="A technical walkthrough of the pipeline that normalizes arbitrary video uploads into universally playable MP4 files."> <meta property="twitter:image" content="https://joaomadeira.xyz/blog-placeholder-1.jpg">

How Z-API Handles Video Conversion


A technical walkthrough of the pipeline that normalizes arbitrary video uploads into universally playable MP4 files.


Introduction

Z-API is a WhatsApp integration platform that moves a huge volume of user-generated media every day. Among all media types, video is the most demanding: files arrive in dozens of different containers (MP4, MOV, MKV, 3GP, WEBM, AVI…), produced by everything from flagship smartphones to screen recorders and legacy cameras. Each source may use a different codec, pixel format, frame-rate strategy, and audio configuration.

The problem this creates is simple but unforgiving: a file that plays perfectly on the sender’s device may refuse to play, or play with broken audio, wrong colors, or stuttering on the recipient’s device. To guarantee delivery, Z-API runs every video through a normalization pipeline whose job is to produce an MP4 file with H.264 video + AAC audio, optimized for progressive (streaming) playback on any modern device.

This post explains that pipeline from the ground up. It starts with the fundamentals of digital video (Section 1), then walks through the specific tools that make the normalization possible FFmpeg and the x264 encoder (Section 2), and then finishes by detailing how Z-API actually orchestrates these pieces, including the decision logic, adaptive parameters, and trade-offs behind each choice (Section 3).


Section 1 — Media Fundamentals

Before we can reason about any conversion pipeline, we need to understand what a “video file” actually is.

1.1 Containers vs. Codecs

A video file is not a monolithic blob, it is a container that wraps one or more codec-encoded streams [1][4].

  • A container (.mp4, .mkv, .mov, .avi, .webm) is the outer format: it defines how streams and metadata are packaged and how they are kept in sync via timestamps [4].
  • A codec (H.264, HEVC, VP9, AV1 for video; AAC, MP3, Opus for audio) is the compression algorithm applied to the actual media data.

A single container like MP4 can legally hold many different codec combinations like, for example, H.264+AAC, HEVC+AAC, and the container alone tells you nothing about whether the file will play on a given device [1][4]. This is why, at Z-API, the file extension is never trusted: the pipeline must always inspect the codecs inside the container.

The process of wrapping streams into a container is called muxing; the reverse process is demuxing [1].

1.2 Bitrate, File Size, and Duration

These three quantities are linked by a single approximation:

File Size (bits) ≈ Bitrate (bits/second) × Duration (seconds)

Bitrate is the amount of data allocated to each second of media. The strategy used to allocate those bits is called rate control, and it is the dominant factor determining the trade-off between visual quality and file size [7].

Two families of rate control exist:

  • CBR (Constant Bitrate): allocates the same amount of data to every second, regardless of visual complexity. Simple scenes are “overpaid” while complex scenes are “underpaid,” producing visible artifacts during motion or detailed scenes [7].
  • VBR (Variable Bitrate): allocates more bits to complex scenes and fewer to simple ones. This is the modern standard [7].

The most useful VBR method for on-demand processing is Constant Rate Factor (CRF) covered in detail in Section 2.

1.3 GOP, Keyframes, and Frame Types

To compress video, an encoder does not store every frame as a full image. Frames are grouped into GOPs (Group of Pictures), each starting with a keyframe:

  • I-frames (Intra-coded / keyframes): a complete self-contained image, similar to a JPEG. A video can only be seeked to an I-frame.
  • P-frames (Predicted): store only the changes relative to the previous I- or P-frame. Much smaller than an I-frame.
  • B-frames (Bi-directional predicted): predict from both past and future frames. They offer the best compression but require the decoder to process a later frame before decoding them, which is why media pipelines need both a Presentation Timestamp (PTS) and a separate Decoding Timestamp (DTS) [2].

A longer GOP (more P/B-frames between I-frames) yields better compression, but worsens seek precision because players can only jump to keyframes.

1.4 Pixel Formats and Chroma Subsampling

Video is not stored as RGB. It is stored in a luma/chroma (YUV) color space, where **** is brightness and U/V are color-difference components.

Human vision is far more sensitive to brightness than to color, and chroma subsampling exploits this by storing color at a lower spatial resolution than brightness [6]. The near-universal pixel format for consumer video is yuv420p: for every 2×2 block of luma samples there is a single U/V pair, cutting color data by ~75% with almost no perceptual loss [6].

This matters enormously for compatibility: the hardware H.264 decoders embedded in the vast majority of smartphones, browsers, and smart TVs only support yuv420p [5]. Delivering an H.264 file encoded in yuv422p or yuv444p (common in professional capture) will result in playback failure or distorted colors on most consumer devices [5]. Forcing the output pixel format to yuv420p is therefore not an optimization, it is a compatibility requirement.

1.5 Frame Rate: CFR vs. VFR

  • CFR (Constant Frame Rate): the time between frames is fixed (e.g., 30 FPS). Standard for professional delivery.
  • VFR (Variable Frame Rate): frame interval changes over time. Screen recordings and many smartphone captures use VFR to save power.

Naively transcoding VFR video often leads to audio/video desynchronization or stuttering in the output [1]. The fix is to force a CFR on the output (in FFmpeg, via -vsync cfr), which duplicates or drops frames as needed to enforce a constant cadence [1].

1.6 Audio Fundamentals

Audio is simpler but equally important. AAC (Advanced Audio Coding) is the de-facto lossy audio codec for MP4, offering better quality than MP3 at the same bitrate. Within AAC, the most universally supported profile is AAC-LC (Low Complexity), which is what FFmpeg’s built-in aac encoder produces by default. Pairing AAC-LC with a stereo channel layout, 44.1 or 48 kHz sample rate, and 128 kbps is a well-known “safe default” for maximum compatibility.

1.7 The moov Atom and faststart

The MP4 container stores all of its indexing metadata, track information, duration, and timescale in a structure called the moov atom. By default, many encoders write the moov atom at the end of the file, after all video/audio payload has been written.

For streaming, this is fatal: a web player cannot start playback until it has read the index, so if the index is at the end, the player must download the entire file first. The -movflags +faststart flag makes FFmpeg run a post-pass that relocates the moov atom to the beginning of the file, enabling progressive playback.

For any service that delivers MP4 to browsers, +faststart is non-negotiable.


Section 2 — FFmpeg and x264

Z-API’s conversion step is built on FFmpeg [2], the de-facto multimedia framework. Inside FFmpeg, H.264 video encoding is performed by libx264, one of the most mature software encoders in existence.

2.1 The FFmpeg Transcoding Pipeline

Every FFmpeg job follows the same logical pipeline [1]:

  1. Demuxer — reads the input container and splits it into elementary streams (video, audio, subtitles), emitting compressed packets [1].
  2. Decoder — turns each packet into raw frames (pixel arrays for video, PCM samples for audio). This reverses the original compression and is CPU-intensive [1].
  3. Filtergraph (optional) — operates on raw frames to scale, convert pixel formats, deinterlace, crop, change frame rate, etc. [1].
  4. Encoder — re-compresses the raw frames using the target codec (libx264, aac). This is typically the most expensive stage of the entire pipeline [1].
  5. Muxer — interleaves the newly encoded packets according to their timestamps and wraps them in the output container (e.g., MP4) [1].

With FFmpeg 7.0, these stages can run as parallel threads, which improves CPU utilization and throughput on multicore hardware [1][3].

2.2 Stream Copy: Skipping the Expensive Stages

FFmpeg supports an alternative “short-circuit” path: if the streams inside the source already match the desired output codecs, the decode/filter/encode stages can be skipped entirely. This is called stream copy and is invoked with -c copy (or -c:v copy / -c:a copy) [1].

In a stream copy, packets flow straight from the demuxer to the muxer, so the file is simply repackaged into the new container. The implications are significant:

  • Extremely fast, because no decoding or encoding occurs.
  • Perfect quality preservation, because no generational loss is introduced.
  • Very low CPU cost, which matters at scale.

The catch is that stream copy only works when the source codecs are already what you want and no filtering is required [1]. Any operation that touches the raw frames (scaling, frame-rate conversion, pixel-format conversion) forces a full transcode.

2.3 CRF: Targeting Quality Instead of Bitrate

Inside libx264, the recommended rate-control mode for on-demand workloads is Constant Rate Factor (CRF). Instead of targeting a specific bitrate, CRF targets a constant perceptual quality level, letting the bitrate rise and fall with scene complexity [8].

CRF values range from 0 (lossless) to 51 (worst), with 23 as the default. Rough rules of thumb [8]:

  • CRF 18 — visually lossless, large file.
  • CRF 23 — good default; high quality, moderate size.
  • CRF 26–28 — visibly reduced quality, but still acceptable for many use cases; noticeably smaller files.

CRF is a form of VBR and produces better quality-per-byte than CBR for on-demand content [7][8]. Its main limitation is unpredictable bitrate spikes: in very complex scenes, the encoder may temporarily emit a bitrate far above the average to preserve quality. For bandwidth-constrained streaming, this can be mitigated with a “Capped CRF” (CRF + -maxrate + -bufsize) configuration [8].

2.4 Presets: Trading CPU Time for Compression Efficiency

libx264 exposes an orthogonal knob called the preset, which controls how much CPU effort the encoder spends searching for the best way to compress each frame. The presets range from ultrafast (least effort, largest files) through superfast, veryfast, faster, fast, medium (the default), slow, slower, veryslow, to placebo.

The crucial idea: the preset changes encoding speed and compression efficiency, but not the target quality [8][9]. A slower preset produces a smaller file at the same CRF, because the encoder does a more exhaustive search for redundancy. Slower presets give the highest compression efficiency (best quality per bit) and are what libx264 is known for [9].

For a high-throughput service, the preset is where CPU-vs-size trade-offs are actually made.

2.5 Faststart: The Non-Negotiable MP4 Flag

As described in Section 1.7, -movflags +faststart relocates the moov atom to the beginning of the file, enabling progressive playback in browsers. Any MP4 that will be streamed over HTTP needs this flag.

2.6 Hardware vs. Software Encoding

An alternative to libx264 is hardware-accelerated H.264 encoding using dedicated silicon on modern GPUs (NVIDIA NVENC, Intel Quick Sync Video) [9]. Hardware encoders can be dramatically faster and offer higher stream density per server, which matters for real-time or high-volume workloads [9].

The trade-off is flexibility and compression efficiency: software encoding with libx264 at slower presets generally still produces the best quality-per-bit [9]. In practice, hybrid strategies (hardware for speed, software for quality) are common [9].


Section 3 — How Z-API Implements Video Conversion

With the fundamentals in place, we can now look at how Z-API actually normalizes videos. The service is written in Go and orchestrates FFmpeg/ffprobe under the hood. It is designed around three principles:

  1. Universal output: every file that leaves the pipeline must be H.264 + AAC in an MP4 container with faststart.
  2. Do the minimum work possible: if the source is already compatible, avoid re-encoding.
  3. Adapt to the source: encoding parameters change based on file size and duration, so small clips and large clips are not processed identically.

3.1 The Pipeline

Each conversion goes through a fixed sequence of stages:

Download → Size Validation → Probe (ffprobe) → Decide → Execute (FFmpeg) → Upload → Cleanup
  1. Download — the source video is fetched from its origin.
  2. Size validation — enforces an upper bound on file size (a lower, stricter limit applies to WhatsApp status media; a larger limit applies to general media) so the pipeline does not process unbounded input.
  3. Probeffprobe is invoked with a bounded timeout. It demuxes the file only to inspect it [1], returning the video codec, pixel format, and audio codec without decoding any frames. This inspection is the foundation of every subsequent decision.
  4. Decide — based on the probe output, the service picks between stream copy and full transcode.
  5. Execute — the chosen FFmpeg command is run. Whether copy or transcode, the output is always an MP4 with +faststart.
  6. Upload — the normalized file is pushed to its destination.
  7. Cleanup — temporary files are removed.

Each stage emits structured logs (start, download, codec detection, branch decision, audio handling, completion, errors) and is wrapped in OpenTelemetry spans, which lets the operations team observe where a given conversion spent its time and why a particular branch was taken.

3.2 Decision Logic and Resource Management

The core stage of the normalization pipeline is the decision engine that determines the most efficient processing route for each file. Rather than applying a universal and costly transformation to every upload, the system leverages metadata extracted during the probing phase to classify content and minimize computational overhead.

Optimization via Short-Circuiting (Stream Copy)

The primary strategy for ensuring high throughput and original fidelity is the use of short-circuiting. If the detected video and audio streams already comply with global interoperability standards (H.264 and AAC), the pipeline bypasses the decoding and re-encoding stages entirely.

This process, known as Stream Copy, offers three critical advantages:

  • Near-Zero Latency: The file is simply repackaged into the new container, an operation limited strictly by disk I/O.
  • Data Integrity: It eliminates the risk of generational loss, preserving the exact visual quality of the original file.
  • Operational Efficiency: Saving CPU cycles allows the system to handle massive volumes without performance degradation.

Interoperability and Compliance Criteria

When compatibility is not guaranteed, the system routes the file for a full transcode. This decision is not based solely on the codec, but on specific technical properties that ensure playback on consumer-grade devices:

  1. Color Space and Pixel Format: Even modern codecs (like HEVC) can fail if they use professional profiles (such as yuv422p). The pipeline ensures conversion to yuv420p, the industry standard for hardware decoders in smartphones and web browsers.
  2. Cadence Synchronization: Files with Variable Frame Rate (VFR) — common in screen recordings — are forced into a Constant Frame Rate (CFR) to prevent audio/video desynchronization issues.
  3. Audio Normalization: Audio streams in legacy or complex formats are normalized to AAC-LC, ensuring consistent playback across all modern media players.

Managing Trade-offs in Transcoding

For files requiring processing, the execution logic prioritizes output stability. The ultimate goal is to transform an arbitrary technical input into a predictable asset: an MP4 container with the moov atom relocated to the beginning of the file (faststart), enabling progressive playback so users can begin watching the video while the download is still in progress.

3.3 Adaptive Encoding Strategy

When a transcode is required, Z-API does not rely on a single fixed configuration. Instead, encoding parameters are adapted dynamically based on input characteristics, primarily file size and duration.

The goal is to balance three competing dimensions:

  • Perceptual quality
  • Output file size
  • Processing latency / CPU cost

Rather than exposing fixed thresholds, the system groups inputs into broad workload classes (e.g., short clips vs. long-form content, small vs. large files) and adjusts encoding behavior accordingly.

Quality Targeting with CRF

Z-API uses CRF (Constant Rate Factor) as the primary rate-control mechanism [8]. Lower CRF values are used when preserving visual fidelity is more important, while higher values are selected when reducing file size and transfer cost becomes a priority.

In practice:

  • Smaller or shorter videos are encoded with more conservative compression (lower CRF), preserving detail where file size is already manageable.
  • Videos larger or longer videos are encoded with slightly more aggressive compression (higher CRF), keeping output sizes under control and avoiding excessive bandwidth usage.

This follows the standard CRF trade-off curve documented by x264: increasing CRF reduces bitrate exponentially while degrading quality gradually [8].

Preset Selection: CPU vs Compression Efficiency

CRF defines what quality to target, but the preset defines how much CPU effort is spent to achieve it [8][9].

Z-API adjusts presets based on expected return on CPU investment:

  • For short or lightweight inputs, faster presets are preferred.
    The absolute size savings from slower presets are minimal, while the latency penalty is significant.

  • For longer or heavier inputs, slower presets are used.
    In these cases, improved compression efficiency leads to meaningful reductions in file size, which compounds across storage and delivery costs.

This reflects a well-known property of x264: slower presets yield better compression efficiency (smaller files at the same quality), but with diminishing returns relative to encoding time [9].

Why Both Axes Matter

CRF and preset operate on orthogonal axes:

  • CRF → controls quality vs bitrate
  • Preset → controls time vs compression efficiency

Optimizing only one of them leads to suboptimal outcomes. By adapting both simultaneously, the pipeline ensures that:

  • CPU is spent where it has measurable impact
  • Latency is minimized where it does not
  • Output files remain within practical size bounds without sacrificing compatibility

Design Principle

The guiding principle is simple:

Spend computation proportionally to how much the result will cost to store and deliver.

Short clips are processed quickly with minimal overhead.
Longer or heavier content justifies additional encoding effort because even small percentage gains in compression translate into significant absolute savings.

3.4 Always-Applied Output Flags

Regardless of whether the pipeline takes the stream-copy path or the transcode path, every output file is produced with:

  • -f mp4 — forces the MP4 container regardless of the input extension, so the output is always the expected format.
  • -movflags faststart — relocates the moov atom to the beginning of the file, enabling progressive playback in browsers. This is mandatory for web delivery.
  • H.264 video + AAC audio — the universally supported codec pair for MP4 [9]. When stream copying, this is already true of the source by construction of the decision logic; when transcoding, it is enforced by libx264 + aac.
  • yuv420p pixel format on transcode forced via -pix_fmt yuv420p because consumer H.264 decoders only reliably support this chroma-subsampled format [5][6].
  • AAC at 44.1 kHz, 128 kbps, stereo when audio is re-encoded, the industry-standard safe defaults for MP4.

3.5 Observability and Safety

Several operational choices make the pipeline resilient in production:

  • Bounded ffprobe timeout. Probing runs with a fixed maximum duration, so a malformed or pathological input cannot stall the pipeline indefinitely [1].
  • Explicit size limits. Input files beyond an absolute maximum are rejected before any CPU work begins.
  • Structured logging of branch decisions. Every job emits the probe results and the chosen branch (copy vs. transcode), so the ratio of cheap vs. expensive work is measurable.
  • OpenTelemetry tracing. Each stage (download, probe, decide, execute, upload) is its own span, making bottleneck analysis straightforward.

Conclusion

Z-API’s video-conversion pipeline is an applied exercise in matching each input to the cheapest operation that still guarantees universal playback. Three ideas underpin it:

  1. Probe first, decide second. ffprobe lets the system make informed decisions without spending CPU on decoding [1]. The output of the probe (video codec, pixel format, audio codec) is sufficient to choose between a millisecond-scale stream copy and a full transcode.
  2. Stream copy when the source is already compliant. H.264, and HEVC already in yuv420p, are re-muxed into MP4 with +faststart rather than re-encoded [1]. This preserves quality, saves CPU, and is the single biggest performance win at scale.
  3. When transcoding is required, adapt. CRF and preset vary with source size and duration so that the encoder spends effort proportional to how much the output will be viewed and transferred [8][9]. Combined with compatibility-mandatory defaults (H.264, yuv420p [5][6], AAC-LC, faststart CFR), the pipeline produces an MP4 that plays everywhere, every time.

The lesson for anyone building a similar system is that a video pipeline is not a single FFmpeg command — it is a decision tree where the right command for each input depends on what that input already is. A fast probe and a well-chosen decision table can cut the cost of video normalization by an order of magnitude compared to naively re-encoding everything.


References

  1. ffmpeg Documentation, ffmpeg.org. https://ffmpeg.org/ffmpeg.html
  2. FFmpeg, FFmpeg Project. https://www.ffmpeg.org/
  3. FFmpeg/FFmpeg architectural overview, DeepWiki. https://deepwiki.com/FFmpeg/FFmpeg
  4. What is a codec?, red5.net. https://www.red5.net/blog/what-is-a-codec/
  5. Which pixel format for web mp4 video, Stack Overflow. https://stackoverflow.com/questions/32829514/which-pixel-format-for-web-mp4-video
  6. A Comprehensive Guide to Chroma Subsampling, Cablematters. https://www.cablematters.com/Blog/HDMI/a-comprehensive-guide-to-chroma-subsampling
  7. What is CBR, VBR, CRF, Capped CRF? Rate Control Explained., OTTVerse. https://ottverse.com/what-is-cbr-vbr-crf-capped-crf-rate-control-explained/
  8. Rate Control revisited, slhck.info. https://slhck.info/video/2017/03/01/rate-control.html
  9. GPU vs CPU Transcoding: Which One Delivers Better Streaming, Ant Media. https://antmedia.io/gpu-vs-cpu-transcoding-for-streaming/