A few months ago, Text-to-MOGRT was a collection of working hypotheses, scripts, and very specific editing problems. Today it is a full UXP plugin for Adobe Premiere Pro, approved by Adobe and available through Adobe Exchange.

Open Text-to-MOGRT in Adobe Exchange

Українська версія: прочитати цей пост українською.

This is not a story about writing a small automation one evening and pressing Publish the next morning. Between the first idea and the release were several architectures, dozens of disposable test projects, manual passes in multiple versions of Premiere, Windows in a virtual machine, separate rollback builds, a race condition inside the Premiere API, broken assumptions, and several moments when an almost-finished candidate had to be put aside.

That is why I wanted to tell this story properly. The most interesting part of a product like this does not happen when a button finally works. It happens in all the decisions that make the button safe enough to use on someone else’s editing project.

The problem that started it

When editing interviews, Shorts, explainers, and Reels, you often already have the text, the visual style, and the structure of the cut. The remaining task sounds simple: turn the text into dozens or hundreds of graphic clips, place them on the timeline, trim them, edit the text, and preserve the design.

Doing that manually means repeating the same operations again and again:

  • duplicate a Motion Graphics Template;
  • paste the next piece of text;
  • adjust its duration;
  • make sure clips do not overlap;
  • keep host lines and quotations in the correct sections;
  • avoid losing a word during line wrapping;
  • check that everything landed on the correct track.

One repetition is harmless. Fifty become routine. A few hundred become a production stage of their own, and a stage where it is easy to make a mistake simply because you are tired.

Text-to-MOGRT was supposed to remove exactly that part of the work. The editor prepares the text and timeline, chooses a MOGRT, reviews the insertion plan, and lets the plugin create editable graphics on the selected track.

Not “automatic subtitles,” but a bridge between text and the edit

An important distinction: Text-to-MOGRT does not try to recognize speech from audio, and it does not replace transcription. Its job begins when the text already exists and needs to become part of the edit.

The plugin supports two main workflows.

Document / Text

In this mode, the source is a TXT or DOCX file. Timing comes from selected tracks in the active sequence. V1, for example, can mark host sections while V2 marks quotations. The plugin reads those time windows, divides the source into screen-sized blocks, and places them into the corresponding sections.

DOCX files can also carry role formatting. This lets host paragraphs and quotations follow different anchor tracks while keeping the original document order intact.

Timed Subtitles

For SRT and WebVTT, the file itself is the timing source. Cue timecodes are preserved, and long cues can be divided into several adjacent, frame-aligned MOGRT clips.

In both modes, the result is not a flattened video layer or a cloud render. It is a set of normal, editable MOGRT clips in Premiere. After insertion, the editor remains in control and can change the text, duration, position, or design in the familiar timeline.

The feature list and installation details are available on the Text-to-MOGRT page in Adobe Exchange.

Why I moved the product to UXP

Earlier versions of this idea existed as Python scripts, Premiere project-rewriting tools, and a CEP panel prototype. All of them were useful. They helped validate the text-splitting rules, the structure of Premiere projects, MOGRT handling, and the real needs of an editing workflow.

But the product version became a UXP plugin.

The reasons were practical:

  • it works inside Premiere Pro;
  • it can read the active project and sequence;
  • the editor does not need to move into a terminal;
  • installation can happen through Adobe’s own ecosystem;
  • there is no separate Python runtime, local server, or companion application;
  • processing stays local.

The release build has no account system, telemetry, activation server, or cloud upload. TXT, DOCX, SRT, VTT, MOGRT, and project data remain on the user’s device. Adobe needs the internet for purchase and installation, but the plugin does not need it to generate clips.

That sounds like an obvious decision. In reality, it simply moves the complexity closer to the Premiere API.

Preview had to be a real preview

One of the non-negotiable requirements was a safe two-phase workflow.

First, Preview Batch builds a plan:

  • how many clips will be created;
  • where they will start and end;
  • which role each block belongs to;
  • how the text will be wrapped;
  • what duration is planned.

Preview must not modify the timeline. That sounds like a small detail, but it is the line between useful automation and a button you are afraid to press.

Only after reviewing the plan does the editor run Insert Batch. Before the first insertion, the plugin checks the output track again. If the required range is occupied, the collision guard stops the entire operation before any timeline change.

No half-created subtitle batch. No silent overwrite. No assumption that the user will clean it up later.

A MOGRT is not just a file

The plugin needed to support several ways of choosing the visual template:

  • a local .mogrt file;
  • a MOGRT installed in Premiere;
  • a prepared template clip on a dedicated timeline track.

The last option matters a lot in real editing. An editor may already have placed the correct graphic on a dedicated template track and checked the composition, color, opacity, motion, and other controls. It makes sense to let the plugin read that template and reuse the settings that Premiere exposes.

This revealed an important API limitation. Premiere does not expose every edited text-style property to a UXP plugin in the way I would like. Some non-text controls can be copied, but the font and size from a timeline template are not always available for full reconstruction. The selected MOGRT file therefore needs to contain the correct text defaults already.

Instead of hiding that limitation, the plugin explains it in the interface. A visible limitation is better than a result that mysteriously looks wrong.

Text wrapping became a product of its own

A character counter is not enough to lay out subtitles. If you simply cut a line at character 25, you can easily leave a preposition by itself, detach a particle, make direct speech look awkward, or break a word that exceeded the limit by a single character.

The rules gradually became more precise:

  • short function words should not be stranded without a reason;
  • manual line breaks should be respected;
  • long timed cues should be divided without gaps or overlaps;
  • Unicode, Cyrillic, and different dash characters should survive intact;
  • comma-attached forms such as ‑,, –,, —,, and −, should stay with the preceding text;
  • a dash beginning direct speech after a completed sentence should move to a new line;
  • when a single word only slightly exceeds the limit, it is better to allow a line up to roughly 1.5 times the limit than to break the word for one character.

These rules look minor until you see them across hundreds of real lines. Details like these make the tool feel as though it understands editing text rather than merely counting characters.

The V5 track the panel could not see

One late bug was wonderfully easy to demonstrate.

The project opened with V1 through V4, the panel read the sequence, and the track selectors were built. I then added V5 in Premiere, but it was impossible to select it as a timing, template, or output track. The panel continued to live inside the structure it had seen when it opened.

The problem was not V5. The problem was the lifecycle of the track catalogue.

There was not one sufficiently reliable “the user added a track” event across the Premiere and UXP versions I needed to support, so the solution became deliberately hybrid:

  • listen to project and sequence events;
  • refresh when focus returns to the panel;
  • provide an explicit Refresh Tracks button as a dependable fallback;
  • avoid parallel structure reads during Preview or Insert;
  • never silently switch the user to another track.

If the selected track is removed, it remains visible as missing and the dependent operation stops with a clear message. If the layout changes, the old Preview and template snapshot become invalid, but selected files and text-layout settings remain.

In Premiere 26, automatic refresh works well. In Premiere 25, manual Refresh Tracks remains an important fallback because it uses an older UXP runtime. It is a compromise, but a controlled and understandable one.

The hardest bug: the clip exists, but it does not exist yet

The most time-consuming problem was a race condition around Premiere TrackItem objects.

The original sequence looked reasonable:

  1. insert a MOGRT;
  2. obtain the TrackItem;
  3. change its end time;
  4. continue with the next clip.

The problem is that completion of the insertion call does not guarantee that the new TrackItem is already stable and visible through getTrackItems().

In one machine-driven run, the ninth MOGRT had been physically inserted while a fresh read of the track could see only five new items. In a completely manual run, the same failure appeared as early as the third clip. The position changed. The symptom did not.

Trying to use the wrapper returned directly by the insertion operation ended with A nullptr was dereferenced. That was useful evidence: the wrapper still existed in JavaScript, but the internal Premiere object behind it could not be treated as stable.

The good news was that rollback worked in both runs. The bad news was that a release with this race condition was unacceptable.

The first fix exposed another scenario

We added a batch visibility barrier: insert all clips, wait for the output-track collection to stabilize, match items to the planned rows, and then change durations using freshly acquired objects.

That eliminated the dangerous wrappers, but it exposed another Premiere behavior.

Before the durations were shortened, the long default-duration MOGRTs were already overlapping. In a control run, 19 physical insertions became 37 items on the track: 19 expected clips plus 18 tail fragments.

This was a very useful failure. The plugin did not swallow the extra items and declare success. Exact-prefix verification detected the wrong cardinality, stopped the batch, and restored the output track to its empty baseline.

But it also proved that the batch-level boundary was still too broad.

The final model: one clip, one completed transaction

In version 1.1.6, the loop became fully serialized:

  1. insert one MOGRT;
  2. reacquire the active sequence and output track;
  3. find the new item by its exact start frame;
  4. require two identical stable reads;
  5. create the duration Action inside project.lockedAccess;
  6. execute the transaction;
  7. reacquire the TrackItem again;
  8. verify the actual end frame;
  9. verify the entire inserted prefix;
  10. only then start the next MOGRT.

Premiere 26 never reuses the insertion wrapper for duration or Effect Controls mutation. If the API returns nullptr, that wrapper is discarded and the item is reacquired from the timeline. Attempts and deadlines are bounded, so the plugin cannot wait forever.

This approach is slower than optimistic bulk insertion. It is still faster than repairing a damaged editing project.

Rollback is not the same thing as Undo

Rollback in a plugin like this cannot mean “delete everything from V4.” The output track may already contain clips before the batch starts, and those clips belong to the user.

The plugin therefore captures a baseline inventory before Insert. During the operation, it keeps a registry of inserted descriptors, start frames, and freshly acquired TrackItems. If any stage fails, rollback:

  • finds the items created by this run;
  • avoids adding the same physical item twice;
  • removes only the current batch;
  • reads the track again;
  • compares it with the exact baseline.

For verification, we built a separate non-release QA package with a one-shot failure injection. It deliberately failed after the first physical insertion. In Windows Premiere 26.3.2, the plugin inserted one item, generated the expected error, removed exactly that item, and verified a 0 → 0 baseline. The injection configuration deleted itself after use.

That QA package cannot be mistaken for the public build. It has a different artifact role, releaseEligible: false, a separate build ID, and its own manifest. After the rollback test, the release CCX was reinstalled and verified through its runtime identity.

Why automation did not replace manual testing

We tried to automate the UI passes as far as practical. Coordinate control worked much better in Premiere 26 than in Premiere 25, where some accessibility clicks ended in AXError.notImplemented.

But being able to move a cursor automatically does not mean every check should be performed that way.

A machine-driven pass can fail more often because of focus, a picker, a repaint delay, or window state than because of the plugin itself. It can also spend many actions doing something a person completes and understands in seconds.

The final QA model therefore became hybrid:

  • scripts verify hashes, manifests, identities, package structure, and machine-readable reports;
  • automated tests verify parsing, wrapping, mapping, race recovery, rollback, and packaging contracts;
  • a human tester presses the critical buttons, watches the timeline, and confirms the real result in Premiere.

For this class of product, that was not a compromise. It was the most reliable design.

Clean projects, immutable bundles, and no “it was somewhere on the desktop”

Another part of the work that never appears in the interface is artifact discipline.

The original reviewer project eventually contained clips saved during earlier QA sessions. It could no longer serve as a clean baseline. From then on, every important pass received a new timestamped copy.

Release tooling began producing separate directories containing the version, commit, and UTC time, while manifests recorded SHA-256 values for the CCX, reviewer bundle, and runtime payload. Old candidates were never overwritten. A dirty fixture could no longer become an invisible fallback.

This produces a lot of folders. It also means that when two independent tests fail in different places, I can prove that they ran the same bytes, in the same host runtime, against the same MOGRT.

That was essential for diagnosing the race condition.

Mac, Windows, and the next Premiere

The final matrix was not limited to one laptop and one Premiere version.

The plugin was tested on macOS in Premiere Pro 25.6 and 26.3. A separate canary passed in Premiere 27 Beta. A canary does not replace stable-version testing, but it can reveal early whether a critical UXP contract has changed in the next generation of the host.

The Windows pass ran on Windows 10 x64 in VMware Fusion on a 2019 Intel MacBook Pro. Premiere 25 and 26 were installed there, and the CCX ran in the real Windows UXP runtime. We tested DOCX, VTT, offline SRT, TXT, persistence, Reset Saved Settings, collision protection, and rollback.

No, this is not a lab with ten physical Windows PCs. It is still a real Windows system, real Premiere, a real CCX installation, and real runtime reports. For an independent product at launch, that is much more valuable than assuming “it is pure JavaScript, so Windows will probably be fine.”

One documented limitation remains: in Premiere 25, after adding a track dynamically, the editor may need to click Refresh Tracks. In Premiere 26, the layout normally refreshes automatically.

What Text-to-MOGRT can do now

The current release can:

  • process TXT and DOCX through timeline timing tracks;
  • recognize host and quotation roles in structured DOCX files;
  • import SRT and WebVTT while preserving cue timecodes;
  • split long cues into adjacent, frame-aligned clips;
  • use a local, installed, or timeline-template MOGRT;
  • show a complete Preview without changing the timeline;
  • insert only on the selected output track;
  • block collisions before the first mutation;
  • refresh the video and audio track catalogue dynamically;
  • remember the chosen MOGRT, source mode, layout, and tracks;
  • never restore the previous source document automatically;
  • reset remembered settings with one button;
  • work locally and offline;
  • restore the exact baseline after an interrupted Insert.

The plugin supports Premiere Pro 25.6 or later on macOS and Windows x64. You can purchase and install it through Adobe Exchange — Text-to-MOGRT.

About the price

Text-to-MOGRT is sold as a $19.99 perpetual license.

I spent a long time wondering whether it should be cheaper “for launch.” But the price of a tool should not reflect the number of buttons. It should reflect the manual work it removes and the responsibility involved in modifying an editing project.

This is not a plugin for every Premiere user. It is for editors who regularly work with prepared scripts, branded MOGRTs, and many repetitive subtitle clips. If it saves one long session of duplicating and trimming graphics, its value is already clear.

I also deliberately kept the perpetual model: no subscription, no external activation, and no extra service sitting between the text and Premiere.

What Adobe review contributed

Adobe review is not a magical guarantee that the software will never have another bug. Premiere, UXP, and third-party MOGRTs are far too varied for that promise.

But review forces the basics into a product state:

  • the manifest and host compatibility must be correct;
  • the package must install through the standard channel;
  • the product page cannot promise features that do not exist;
  • privacy, terms, support, and the commercial model must agree;
  • a reviewer must understand how to test the product;
  • the version, screenshots, release notes, and submitted bytes must match.

When the approval message finally arrived, the most satisfying part was not the status itself. It was knowing that the release CCX was no longer “the latest file on my desktop.” It was an artifact tied to a known commit, SHA-256, runtime build ID, and a completed matrix.

What I learned from the work

A human in QA is not a sign of weak automation

At the beginning, it is easy to imagine the perfect setup: an agent opens Premiere, moves the cursor, clicks every button, compares screenshots, and declares the release ready without help. Some of that genuinely worked. In Premiere 26, automation could open the panel, use file pickers, and complete the main flow. In Premiere 25, the same coordinate clicks sometimes failed in the accessibility layer while the plugin itself remained healthy.

That distinction matters. A UI automation failure is not automatically a product failure. The machine can lose focus, act before a window repaints, click an element at an old position, or spend many steps doing nothing but moving the pointer. Treating every one of those events as a plugin defect creates more noise than evidence.

A human sees context differently. A person immediately notices that V4 still contains exactly 19 clips, that rollback really left the track empty, that Sample text disappeared from the Program Monitor while Welcome remained, or that a newly added V5 exists in Premiere but not in the panel selector. An automated test needs a separate measurement strategy for each observation. An editor needs one look at the screen.

Manual testing produced the second independent TrackItem failure. The machine-driven run stopped on clip nine; the manual run stopped on clip three. If I had trusted only one method, I could have blamed cursor movement, timing, or an unstable test harness. Two different runs with the same diagnostic proved that the race was in the runtime rather than the automation.

At the same time, a person should not verify SHA-256 values, CCX structure, commit IDs, build IDs, JSON record counts, or package-manifest consistency by hand. A script is incomparably better at that job. It does not get tired, confuse two similarly named files, or decide that this is “probably the right build.”

The best system was therefore not complete automation, but a clear division of responsibility. Scripts created immutable bundles, verified identities, counted timeline items, recorded duration transactions, and compared baselines. I performed short, explicit steps in a real Premiere session and confirmed what I could see. The Support Report connected the two worlds by giving each human observation exact technical context.

Even the one-step-at-a-time instructions became part of quality. They prevented an accidental Insert before Preview, stopped Premiere 25 and 26 from being mixed in one session, avoided running two hosts sharing one plugin ID, and made it much harder to reinstall a rollback-only CCX instead of the release package. A good QA scenario reduces the tester’s cognitive load instead of turning the tester into another unreliable automation script.

That is my main conclusion from the entire project: a human presence in QA does not excuse missing tests. It gives automated tests the correct role. The machine verifies everything that can be measured unambiguously. The human evaluates state, meaning, and the result inside the real working environment. Confidence appears when those two kinds of evidence agree.

What comes next

The work does not end with the release. Real projects will bring unfamiliar MOGRTs, different sequence structures, and scenarios that no test matrix can completely invent in advance.

The immediate plan is straightforward:

  • collect useful support reports without collecting user content;
  • broaden compatibility across different MOGRT structures;
  • watch UXP changes in future Premiere releases;
  • improve panel explanations wherever the API imposes limitations;
  • avoid turning a local tool into a cloud service without a real need;
  • preserve the main principle: Preview first, controlled mutation second.

Final thought

I like products that grow from one very specific irritation.

Text-to-MOGRT began with a question: “Why am I manually duplicating all these graphic clips when the text, style, and timing already exist?” The answer turned out to be much larger than one script. It passed through document parsing, language rules, the Premiere API, UXP lifecycle behavior, TrackItem race conditions, rollback, a Windows VM, a Beta canary, manifests, SHA-256, and Adobe review.

Now it is a tool that can be installed and used inside a normal Premiere workflow.

Text-to-MOGRT in Adobe Exchange

If your work includes prepared scripts, MOGRT templates, and timelines where subtitle graphics are still created by hand, I would be glad to hear how this approach behaves on a real project.

Українська версія: Від монтажної рутини до Adobe Marketplace: як я створював Text-to-MOGRT.