Premiere+Python审片工具开发

zhangly 2024-01-01 19:00:50
Categories: Tags:

前言

这篇文章主要是给使用Premiere作为审片工具的公司,以及他们的TD提供一些工作量
通过开发一些工具来提升审片工作的效率,让导演和制片少加班,早回家!

开发借用pymiere 项目,支持的pr版本2017-2023。
阅读能力强的同学可以直接点开github看他的说明(就不用看这篇流水账啦)。

文章大致内容如下

环境配置

需要给Premiere安装pymiere扩展,使用正版的同学可以直接通过扩展管理器安装。
用学习版的同学,需要使用一个第三方软件来安装扩展包,下面是安装步骤。

1.首先下载安装 ZXP/UXP Installer
只勾选下面这个,然后安装。

image.png

2.打开ZXP Installer软件,安装扩展
下载之前提到的pymiere扩展,然后File菜单打开zxp文件进行安装(或者直接将zxp文件拖拽进窗口就行)。

image.png

3.看到successfully就是安装完成了

image.png

4.打开pr在菜单栏,能看到Pymiere Link代表成功安装

image.png

5.最后在你的python环境中安装第三方库

pip install pymiere

概念与文档

这是pymiere库文档: https://ppro-scripting.docsforadobe.dev/
比较重要的是ProjectItemTrackItem两个对象。

ProjectItem是项目素材库中音视频媒体对象。
通常创建bin文件夹,导入/替换视频,或者获取视频信息等方法在这个对象里。

image.png

TrackItem是剪辑线中的剪辑片段(clip)对象。
比如获取剪辑入点/出点,时间长度,timecode等操作在这个对象里。

image.png

常用代码块

重要: 运行代码时,必须打开pr软件,并进入一个工程。

获取当前激活的项目对象

这是一切的基础,获取project对象才能对pr进行操控。

import pymiere

project = pymiere.objects.app.project

创建bin文件夹

bin_folder = project.rootItem.createBin('abc')

导入视频

project.importFiles(filePaths=mov_list,          # 导入的mov路径,列表类型
                    suppressUI=True,             # 是否应禁止显示警告对话框。
                    targetBin=bin_folder,        # 目标文件夹的路径,ProjectItem对象  
                    importAsNumberedStills=False # 是否为序列帧导入
                    )

将视频放在时间线

import pymiere  

mov_path = r'D:\test\sc001_shot001_lay_v001.mov'
# 获取pr软件中,当前激活的项目对象  
project = pymiere.objects.app.project  

# 获取激活的序列  
sequence = project.activeSequence

# 通过视频路径,获取其ProjectItem对象
item = project.rootItem.findItemsMatchingMediaPath(mov_path, ignoreSubclips=True)[0]

# 选择第一个视频轨道
track = sequence.videoTracks[0]

# 在时间轨道0秒处插入视频
track.insertClip(item, 0)

获取剪辑线选择的视频clip

# 获取激活的序列对象
active_sequence = project.activeSequence

# 获取选择的clip,会返回一个数组对象pymiere.core.Array
selected = active_sequence.getSelection()

# 过滤出所有的视频类型
for i in range(selected.length):  
    track_item = selected[i]  # 这里是TrackItem对象
    if track_item.mediaType == 'Video':  
        print(track_item)

替换视频

# 先通过上面的方法获取TrackItem对象

# 然后从TrackItem获取素材箱中媒体对象
project_item = track_item.projectItem

# 指定新的mov路径
new_mov_path = r'D:\test\sc001_shot001_lay_v001.mov'
name = os.path.basename(new_mov_path)

# 执行替换
project_item.changeMediaPath(new_mov_path, overrideChecks=True)

# 修改素材箱中媒体名称
project_item.name = name

# 修改剪辑线上clip名称
track_item.name = name

需求与实例

批量导入视频,创建层级

这里的例子是导入sc001sc002两个场次,所有lay环节的最新版review。
并在pr的素材箱中创建层级结构。

image.png

import pymiere  
  
# 获取pr软件中,当前激活的项目对象  
project = pymiere.objects.app.project  
  
# 创建文件夹层级  
sequence_name = 'sc001'  
seq_bin_folder = project.rootItem.createBin(sequence_name)  
step_bin_folder = seq_bin_folder.createBin('lay')  
  
# 导入mov文件  
mov_list = [rf'D:\lay\{sequence_name}_shot001_lay_v003.mov',  
            rf'D:\lay\{sequence_name}_shot002_lay_v003.mov',  
            rf'D:\lay\{sequence_name}_shot003_lay_v003.mov',  
            rf'D:\lay\{sequence_name}_shot004_lay_v003.mov']

# 导入操作  
project.importFiles(mov_list,
					suppressUI=True,
					targetBin=step_bin_folder,  
                    importAsNumberedStills=False  
                    )

切换环节

将现在的lay环节替换为ani环节的mov

image.png

import os  
import pymiere  

# 获取pr软件中,当前激活的项目对象  
project = pymiere.objects.app.project  

# 获取文件夹层级下所有的mov(projectItem对象)
sequence_name = 'sc001'
step_name = 'lay'
target_step_name = 'ani'

project_items = []
# 遍历素材箱
for root_bin_folder in project.rootItem.children:
	# 如果根目录名称为sc001,则遍历其子项
    if root_bin_folder.name == sequence_name and not root_bin_folder.isSequence():  
        for num in range(root_bin_folder.children.numItems):  
            step_bin_item = root_bin_folder.children[num]
            # 如果bin目录为step名称,则遍历其子项
            if step_name == step_bin_item.name and not step_bin_item.isSequence():
	            # 修改bin目录名称为ani
                step_bin_item.name = target_step_name  
                for video_num in range(step_bin_item.children.numItems):
	                # 最后将所有sc001/ani目录下的媒体对象加入列表
                    project_items.append(step_bin_item.children[video_num])  
  
for project_item in project_items:  
    # 获取媒体文件的路径
    old_file_path = project_item.getMediaPath()
    # 粗暴的获取目标环节的mov路径,实际使用中需构建自己的逻辑
    new_file_path = old_file_path.replace(step_name, target_step_name)
    # 执行替换
    project_item.changeMediaPath(new_file_path, overrideChecks=True)
    # 修改素材箱中的名称
    project_item.name = os.path.basename(new_file_path)

素材箱中的媒体文件替换后,时间线上的clip也会随之替换。

检查/更新review版本

思路和上面一样,遍历素材箱找到对应媒体对象,然后进行替换。

或者只替换时间线上使用的mov:

import pymiere  

clips_list = []

# 获取pr软件中,当前激活的项目对象  
project = pymiere.objects.app.project  
  
# 获取激活的序列对象
active_sequence = project.activeSequence  

# 获取序列对象所有的视频轨对象
video_tracks = active_sequence.videoTracks

for track_num in range(video_tracks.numTracks):  
    # 单个视频轨道的所有剪辑块 clips
    clips = video_tracks[track_num].clips  
    for clip_num in range(clips.numItems):  
        clips_list.append(clips[clip_num])  

for track_item in clips_list:  
    project_item = track_item.projectItem  
    # 执行替换  
    project_item.changeMediaPath(new_file_path, overrideChecks=True)

提交反馈

这个也是获取时间线上选择的视频,写一些界面交互让审核者提交文字反馈或截图。

pymiere提供了一个时间线跳转的方法,可以帮助快速定位到指定的镜头:

import pymiere

project = pymiere.objects.app.project

# 跳转时间线到指定的时间
project.activeSequence.setPlayerPosition(clip.start.ticks)

印象中clip.start.ticks会出现一个类型错误,需要改源码进行修正。

颜色标记镜头任务状态

这里使用marker对剪辑线进行标记,修改颜色和反馈/制作内容。
可以根据不同的颜色定义不同的任务状态。

image.png

import pymiere  

project = pymiere.objects.app.project  
active_sequence = project.activeSequence    
clips = active_sequence.getSelection()

notes = ['修改桌子的边缘高光', '角色A走路飘移', '屋顶换成玻璃材质']
n = 0
for clip in clips:
    # 创建Marker
    marker = active_sequence.markers.createMarker(time=clip.start.seconds)
    # 设置Marker时间范围等于clip的范围
    marker.start = clip.start.seconds  
    marker.end = clip.end.seconds
    # 设置文字描述
    marker.comments = notes[n]
    # 设置Marker颜色
    marker.setColorByIndex(4)  
    n += 1

如果想要用标签色来标记任务状态,需要修改pymiere\objects\premiere_objects.py文件中的TrackItem类。pymiere没有提供对应方法来修改标签颜色。

image.png

总结

Pymiere库并不是官方提供的Python API,它的作用主要是将 Python 命令(获取属性、执行函数等)转换为 ExtendScript 代码,然后通过HTTP请求将代码发送给Pymiere Link扩展来执行它。

所以提供的接口有限,能实现的自动化也因此受到限制。不过可以查询ExtendScript命令去修改pymiere源码来实现想要的效果。

开发体验来说不如ShotGrid RVNuke Studio,两者都提供了官方Python API,文档详细且接口丰富。

文章就到这里,如果有所帮助可以关注一下这个公众号,感谢!