Skip to content

Python library

from prpr import Premiere

p = Premiere()          # hosts the bridge; launches Premiere if needed

The object model mirrors dvr's: namespaces hang off the root handle, state is always read live, and operations are idempotent where possible (ensure everywhere).

Projects

p.project.list()                  # projects open in Premiere
proj = p.project.ensure("MyShow") # open-or-create by name (or full path)
proj.inspect()                    # name, path, sequences, bin/item counts
proj.save(); proj.save_as("/path/copy.prproj"); proj.close()

Timelines (sequences)

tl = p.timeline.ensure("Edit_v1")
tl.inspect()                      # fps, frame size, tracks, items, markers, settings
tl.append("clip_a.mp4")           # by project-item name (or item_path=...)
tl.insert("clip_b.mp4", seconds=10.0, video_track=1)
tl.delete_clips(name_contains="temp", ripple=True)
tl.set_in_out(1.0, 5.0)
tl.insert_mogrt("/path/lower-third.mogrt", seconds=2.0)
tl.scene_edit_detection(operation="cut", clip_name="long_take.mp4")

tl.add_marker(1.0, name="start", note="first pass", color_index=1)
tl.markers(); tl.remove_marker(name="start")

short = tl.clips.where(lambda c: (c.duration or 0) < 0.5)   # query language
for clip in short:
    clip.disable()

Media

p.media.import_(["/footage/a.mp4"], bin="Footage/Day1")   # bins auto-created
p.media.find_or_import("/footage/a.mp4")                   # idempotent
p.media.inspect()                                          # full bin/clip tree
p.media.move("Selects", source_bin="Footage", name_contains="_ok")
p.media.attach_proxy("/proxies/a_proxy.mov", name="a.mp4")
p.media.create_subclip("a_sub", 1.0, 4.0, name="a.mp4")    # 26.3+
p.media.transcript_export(name="interview.mp4")            # 26.3+
prpr.scan_media_files("/footage")                           # no Premiere needed

Effects, transitions, transforms

p.effects.list("video")           # 111 effects with matchNames
p.effects.apply("PR.ADBE Gamma Correction", clip_name="a.mp4")
p.effects.add_transition("ADBE Film Dissolve", clip_name="a.mp4", duration_seconds=1.0)

# Transforms are Motion-component params:
p.effects.set_param("Motion", "Scale", 50, clip_name="a.mp4")
p.effects.set_param("Motion", "Position", [0.25, 0.5], clip_name="a.mp4")

# Keyframes: pass at_seconds
p.effects.set_param("Opacity", "Opacity", 100, clip_name="a.mp4", at_seconds=0)
p.effects.set_param("Opacity", "Opacity", 0, clip_name="a.mp4", at_seconds=2.0)

p.effects.components(clip_name="a.mp4", with_values=True)  # inspect the chain

Render / export

p.render.presets()                              # .epr discovery
job = p.render.submit(target_dir="/exports",
                      preset="ProRes 422",      # name or path to .epr
                      queue_to=None,            # None | "app" | "ame"
                      wait=True)
job.output_path

p.render.export_frame(2.0, "/stills/f.png", width=1920, height=1080)

from prpr import interchange
interchange.export_timeline(p, "/out/edit.xml")     # fcpxml by extension
interchange.export_timeline(p, "/out/edit.otio")
interchange.export_timeline(p, "/out/edit.aaf")

Declarative workflows

from prpr import spec, diff, snapshot, lint

s = spec.load_spec("show.yaml")
spec.plan(s, p)                    # what would change
spec.apply(s, p, verify=True)      # reconcile + read-back verification

d = diff.compare_timelines(p, "Edit_v1", "Edit_v2")
snap = snapshot.capture(p); snapshot.save(snap)
report = lint.lint(p)              # offline media, temp paths, empty sequences

Escape hatch: raw JavaScript

The full premierepro UXP module is one call away — this is the same mechanism every wrapper uses:

p.eval_js("""
    const project = await ppro.Project.getActiveProject();
    return project.name;
""")

Errors

Everything raises a prpr.errors.PrprError subclass with message, cause, fix, and a state snapshot. Operations Premiere's API can't perform raise NotSupportedError — see parity.