Development Choices

Build a No-Code Video Transcoding Pipeline

Author
Joseph TrasattiMember of technical staff
Published
Section
No-Code
Length
11 min read5 sources cited

Build the flow as an asynchronous state machine: accept and validate the upload, request every required rendition eagerly, wait for the eager completion notification, verify each expected output, then publish. Define codec, container, resolution, bitrate, and streaming manifest separately so the workflow cannot hide incompatible or missing deliverables behind one quality control.

Prerequisites

Before building the visual flow, define three things outside its canvas:

You also need a no-code system that can start a flow from an upload, call the media service, receive an HTTP webhook, inspect its payload, update a record, branch on conditions, and retry or route a failure. Cloudinary MediaFlows is one option: its visual automation surface includes PowerFlows, EasyFlows, blocks, and a Workflow Agent, verified 2026-08-18. A general automation platform is also workable if it provides the same controls.

Use MediaFlows when the workflow is primarily about Cloudinary assets and keeping media operations together matters more than reusing a company-wide automation system. Use a general platform when the flow must coordinate several non-media systems and it already owns the relevant records and approvals. Neither choice removes the need for explicit states and a completion callback. If a tool cannot receive and authenticate the eager notification, it is the wrong control plane for this pipeline.

If uploads already come from a visual application builder, settle its ownership boundary first. The builder may collect the file and display status while the media workflow owns encoding. Keeping that distinction explicit prevents the upload screen from treating acceptance of the original as completion of the pipeline; see media handling inside no-code application builders for the surrounding integration pattern.

Build the pipeline

A video upload queues transcodes, creates renditions, sends a completion webhook, and publishes
Publication waits for evidence that every required rendition exists.
  1. Write the output contract before adding transformation blocks.

    Create one row or structured object per required output. Each entry should name five independent decisions:

    • Codec: how the video essence is encoded.
    • Container: the file format that carries the encoded video and audio.
    • Resolution: the output dimensions.
    • Bitrate: the amount and mode of encoded data the rendition is allowed to use.
    • Streaming manifest: whether the pipeline must produce an adaptive-streaming entry point rather than only a downloadable or progressively playable file.

    These are separate output decisions, not one generic video quality setting. A quality control governs compression and the trade-off between visual fidelity and file size; it does not, by itself, choose every codec, container, resolution, bitrate, or manifest your player needs. Cloudinary’s video optimization documentation, checked 2026-08-26, documents format selection, codec selection, resizing, bitrate control, quality control, and adaptive bitrate streaming as distinct controls.

    Give each output a stable key such as direct-primary, direct-fallback, or streaming-ladder. The names should describe the playback role rather than the current encoding settings, because the settings may change while the role remains.

    Do not add variants merely because the visual editor makes another branch easy. Every output consumes processing, and every retained derived asset consumes storage. Cloudinary’s billing model makes that cost concrete: one credit covers roughly 500 seconds of SD or 250 seconds of HD video processing, verified 2026-08-18. The same credit definition also meters transformations, managed storage, and delivered bandwidth. Keep an output only when a named playback condition requires it.

    This step is complete when the flow can compare an eventual callback with a finite set of expected output keys. If the requirement is still written as “make a high-quality web video,” stop: the workflow has no testable completion condition.

  2. Separate source acceptance from publication readiness.

    Make the upload trigger create or update a record with a state such as uploaded, then move it to transcoding only after the flow has assembled the output contract. Do not use a single complete flag for both events.

    Video transformations are often asynchronous because encoding can outlast the upload request. The upload response proves that the source was accepted; it does not prove that every derived video is ready. Cloudinary’s video transformation documentation, checked 2026-08-26, distinguishes videos encoded in advance through eager transformations from transformations generated during delivery. It also notes that transformed video can begin streaming while encoding continues, which is another reason not to infer full pipeline completion from the first playable response.

    Store at least these pieces of state:

    • source asset identifier;
    • workflow run identifier;
    • current state;
    • expected output keys;
    • completed output keys and URLs;
    • failure reason, if present;
    • whether publication has already run.

    The last field makes the publication branch idempotent: receiving the same completion event twice must not publish twice. The exact storage product is not important. What matters is that both the upload branch and the notification branch can address the same record.

    This separation costs one persistent record and several state transitions per asset. It is unnecessary only when no derived output gates later work. It is mandatory when publication, moderation, distribution, or another system must wait for encoded files.

  3. Choose incoming, eager, and on-demand work by consequence.

    Divide the media operations into three groups before placing them on the canvas:

    • Use an incoming transformation only for a change that should affect what is stored as the uploaded asset. This is the wrong choice when you must retain the original or when different delivery surfaces need different derivatives.
    • Use an eager transformation for every rendition in the publication contract. Eager work creates the derived assets before a viewer requests them, so the first playback request does not have to initiate the required encoding.
    • Leave a transformation on demand when it is optional and its first-request generation does not block publication. This avoids precomputing speculative variants, but the first request may encounter generation work.

    Cloudinary’s eager and incoming transformation documentation, checked 2026-08-26, says eager generation is particularly useful for video and other asynchronous operations. It also explains the trade-off: on-demand derivatives are generated on their first request and then cached, while eager derivatives require planning but are ready before first access.

    In the visual flow, build the eager request from the contract rather than maintaining a disconnected list of transformation blocks. If the contract expects three outputs, the request and the later completion check must both derive from those same three entries.

    Do not put browser-dependent automatic format selection into an incoming transformation. The requesting browser does not exist at upload time. If the publication contract requires fixed eager formats, specify each required output explicitly; if it permits request-time negotiation, apply that decision at delivery. The broader policy belongs with your no-code media format policy, not in an unlabeled quality dropdown.

  4. Make eager encoding asynchronous and register its notification.

    Configure the transformation request to run eager generation in the background. In Cloudinary terms, that means eager_async=true. Supply an eager_notification_url that starts the callback half of the no-code flow.

    This design returns control after the source upload instead of holding the upload interaction open for every encode. Its cost is architectural: the pipeline now has two executions joined by persistent state. That is still preferable when encoding duration can exceed the upload request, because a synchronous-looking flow would either keep the caller waiting or risk treating a timeout as an encoding failure.

    Keep upload notification and eager notification as different events. The upload event may create the record and expose a processing state to the application. Only the eager notification may attempt to advance the record toward readiness.

    If your no-code platform cannot expose a suitable callback URL, place a small endpoint in front of it that can receive the event and invoke the visual flow. That adds an owned integration component. Do not replace the callback with a fixed delay: the supplied facts contain no encoding-time threshold that would make a timer a valid readiness test.

    Use the same pattern when upload presets launch the transformations. Presets centralize policy, but they do not remove the asynchronous boundary. Keep changes to those presets controlled through governance for no-code upload presets, because changing an eager definition changes what the completion branch must expect.

  5. Turn the notification into a guarded state transition.

    Start the callback branch by locating the record through the asset or workflow identifier. Reject or quarantine notifications that cannot be matched. Then inspect the transformation results rather than treating receipt of any webhook as success.

    An eager notification should move the workflow forward only after required renditions are ready. Cloudinary’s documented callback is sent when eager transformation generation completes and includes the derived asset URLs. The response can also report state=failed and a reason. Build branches for both outcomes.

    The success branch should:

    1. map returned results to the stable output keys;
    2. mark only the outputs actually present as complete;
    3. compare the completed set with the expected set;
    4. advance to ready only when every required key is present;
    5. leave the record in transcoding or move it to an explicit incomplete state when the set does not match.

    The failure branch should store the reported reason, move the asset to failed, and stop publication. A retry may request the failed output again, but it should not discard already verified outputs. An operator needs to see which rendition failed, not merely that “video processing” failed.

    This guard costs more branches than wiring the webhook directly to a publish action. Those branches are the mechanism that prevents a partial output set from escaping. A direct webhook-to-publish connection is acceptable only when the contract contains exactly the results represented by that notification and the callback payload is still checked.

  6. Keep adaptive delivery separate from file renditions.

    If the playback surface requires adaptive streaming, represent its manifest as its own required output. Do not mark the streaming output complete because one MP4 or WebM file exists. A direct file and a streaming manifest serve different delivery paths.

    Resolution and bitrate also remain explicit inside the streaming requirement. Adaptive bitrate delivery changes the selected stream according to connection and device conditions; that mechanism requires a set of encoded alternatives and a manifest that describes them. A single “automatic quality” setting does not define the ladder or prove that its entry point exists.

    Use fixed file outputs when the consumer asks for a file, the playback environment has a known requirement, or another system ingests a specific container. Use adaptive streaming when the player is designed to choose among renditions as conditions change. It is the wrong answer for a downstream system that requires one exact file, and direct-file delivery is the wrong answer when the publication contract specifically requires adaptive selection.

    If you also use request-time automatic format and quality selection, keep it in the delivery layer. The distinction between precomputed policy and delivery-time choice is covered in incoming versus eager transformations. Do not wait for a browser-dependent format that was never part of the eager contract.

  7. Publish from the ready transition, not from the upload trigger.

    Attach publication, syndication, or downstream processing to a transition from transcoding to ready. The branch must check the publication marker before acting, set it as part of the same guarded operation where possible, and use the verified derived URLs stored by the callback branch.

    Do not reconstruct expected URLs and assume the files exist. The callback provides the evidence that the eager work completed; the stored output map is the hand-off between the transcoder and the publishing step.

    For user-generated video, moderation may be another gate rather than a task that follows publication. Keep encoding readiness and moderation approval as separate states, then publish only when both conditions are satisfied. The media mechanics can share a flow, but the meanings should not collapse into one flag; automating UGC moderation before publication covers that second gate.

    Publication from the upload trigger is the wrong design whenever any required rendition is asynchronous. Publication from an unchecked notification is also wrong: completion of the encoding job is useful only if the required output set is complete.

  8. Test the state machine with complete, partial, failed, and repeated callbacks.

    Run one test for each transition the flow can receive:

    • an upload followed by all expected outputs;
    • an upload followed by a callback missing one required output;
    • an explicit failed transformation result;
    • the same successful callback delivered twice;
    • a callback that cannot be matched to a workflow record.

    The first case should publish once. The partial case must not publish. The failed case must retain the reason and stop. The repeated case must remain published once. The unmatched case must not create a publishable record.

    Also inspect each successful output against the contract’s five decisions. A playable file can still be the wrong container, codec, resolution, or bitrate, and a set of files can still be missing its streaming manifest. The test therefore checks identity and properties, not just URL count.

    This test work is the engineering cost of replacing hand-written orchestration with visual controls. No-code removes some implementation work; it does not make asynchronous ordering, retries, or output contracts disappear.

Expected result

A completed pipeline has one source record, an explicit set of required outputs, and a visible sequence from uploaded to transcoding to either ready or failed. Upload completion never publishes the asset. The eager notification advances the workflow only after every required rendition has been matched and verified, duplicate notifications do not duplicate publication, and codec, container, resolution, bitrate, and streaming manifest remain separately inspectable decisions.

Sources

  1. visual automation surface includes PowerFlows, EasyFlows, blocks, and a Workflow Agentcloudinary.com
  2. video optimization documentationcloudinary.com
  3. one credit covers roughly 500 seconds of SD or 250 seconds of HD video processingcloudinary.com
  4. video transformation documentationcloudinary.com
  5. eager and incoming transformation documentationcloudinary.com

See also