De facto way to get ProjectItem of newly imported media in Premiere Pro UXP?

Hi,

In Premiere Pro UXP, what is the de facto / recommended way to get the ProjectItem(s) created by a call to project.importFiles()?

I’m trying to reliably obtain the ProjectItem for newly imported media, but I can’t find an official or documented pattern for this.

So far, the best approach I can come up with (untested) is:

  1. Take a snapshot of rootItem.getItems() before calling project.importFiles()

  2. Call project.importFiles(...)

  3. Take another snapshot of rootItem.getItems() after

  4. Compute the diff → these are the newly added items

  5. To find a specific item, do something like:
    newItems.find(item => item.name === <itemName>)

  6. Where itemName matches the filename of the imported media

However, this feels:

  • Potentially fragile (async timing, batch imports, name collisions)

  • Inefficient for large projects

  • Not obviously “the intended way”

Questions:

  • Is this snapshot + diff approach the correct way today?

  • Is there a more reliable or officially recommended pattern?

  • Is there any way to directly obtain the ProjectItem(s) created by importFiles, especially when importing multiple files?

Any guidance or confirmation from the team or others using UXP in production would be greatly appreciated.

Thanks!

This is so funny. I was dealing with this exact same conundrum yesterday! The snapshot diff solution as you described it is the exact same one that I’m using in my plugin and it works reliably.

You can also use ClipProjectItem.findItemsMatchingMediaPath() which will return an array of ProjectItems.

I wish that project.importFiles()returned the getId() value of the newly imported media instead of just a bool, that would make this simpler. Oh well.

Technically, if the API would be returning an list of (newly imported) clips ( ClipProjectItem[]) - that would be ideal.

@pinoy Also you may want to check against the value returned by “getMediPathFile()” - since I think its “name” is not guaranteed to be unique.

@bbb_999 : BTW, why is findItemsMatchingMediaPath returning an array of projectItem ?
It seems like if you specify the MediaPath, the only object i can be is a CliProjectItem.
(I suppose the answer might be “best practice → code to interface”, and ProjectItem act as interface / abstract class - but in that case an explicit cast is required :frowning: )

ClipProjectItem.findItemsMatchingMediaPath(matchString, ignoreSubclips) looks like exactly what I need — just wanted to check I’m using it correctly.

Since it’s an instance method, I need an existing ClipProjectItem to call it on, even though the method appears to search the whole project. My current approach is to walk the project tree first to find any media clip, then use it as the receiver:

async function findAnyMediaClip(folderItem) {
  const items = await folderItem.getItems();
  for (const item of items) {
    const clip = ppro.ClipProjectItem.cast(ppro.ProjectItem.cast(item));
    if (clip && (await clip.getContentType()) === ppro.Constants.ContentType.MEDIA) {
      return clip;
    }
    const folder = ppro.FolderItem.cast(ppro.ProjectItem.cast(item));
    if (folder) {
      const found = await findAnyMediaClip(folder);
      if (found) return found;
    }
  }
  return null;
}

const anyClip = await findAnyMediaClip(rootItem);
const matches = await anyClip.findItemsMatchingMediaPath(uncPath, true);

This works, but it feels a bit roundabout — walking the tree just to get a receiver for a method that searches the whole project anyway. I wanted to check:

  1. Is this the intended way to use findItemsMatchingMediaPath?

  2. Is there a cleaner alternative, like a static or project-level method for path lookup?

Happy to be corrected if I’m missing something obvious. Thanks!

Because a given piece of media can be imported to a Project as N different projectItems, and we wanted to use the same return type regardless of the value of N. :slight_smile:

@bbb_999 Ah, I was not clear. My question was not about the array but the type within the array.

So should be read “Why an array of ProjectItem and not an array of ClipProjectItem ?” (since only Clips can be imported, it does not make sense to import a Folder)

Hrrmmn…Neither Sequences nor Bins will have a path to match, which should exclude them from being in the resultant array…

Worthwhile suggestion; I’ll ask the team.

Normally I’d agree that returning the ClipProjectItem[ ] itself would be ideal, I’ve just standardized around always storing the ID of objects and then fetching fresh objects right before I need them. I’ve been burned too many times by either those object references becoming stale if I run concurrent operations in between the retrieval and use, or that I lose the object methods when they become serialized and passed between module boundaries.