Merged in feature/PYPE-320_fps_frames_sapublisher (pull request #136)

Feature/PYPE-320 fps frames sapublisher

Approved-by: Milan Kolar <milan@orbi.tools>
This commit is contained in:
Jakub Trllo 2019-05-15 16:04:49 +00:00 committed by Milan Kolar
commit d8265ec2f2
4 changed files with 95 additions and 67 deletions

View file

@ -55,10 +55,10 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin):
instance = context.create_instance(subset)
instance.data.update({
"subset": family + subset,
"subset": subset,
"asset": asset_name,
"label": family + subset,
"name": family + subset,
"label": subset,
"name": subset,
"family": family,
"families": [family, 'ftrack'],
})
@ -74,10 +74,9 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin):
collections, remainder = clique.assemble(component['files'])
if collections:
self.log.debug(collections)
range = collections[0].format('{range}')
instance.data['startFrame'] = range.split('-')[0]
instance.data['endFrame'] = range.split('-')[1]
instance.data['startFrame'] = component['startFrame']
instance.data['endFrame'] = component['endFrame']
instance.data['frameRate'] = component['frameRate']
instance.data["files"].append(component)
instance.data["representations"].append(component)

View file

@ -57,19 +57,19 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin):
"name": "thumbnail" # Default component name is "main".
}
elif comp['preview']:
if not instance.data.get('startFrameReview'):
instance.data['startFrameReview'] = instance.data['startFrame']
if not instance.data.get('endFrameReview'):
instance.data['endFrameReview'] = instance.data['endFrame']
if not comp.get('startFrameReview'):
comp['startFrameReview'] = comp['startFrame']
if not comp.get('endFrameReview'):
comp['endFrameReview'] = instance.data['endFrame']
location = ft_session.query(
'Location where name is "ftrack.server"').one()
component_data = {
# Default component name is "main".
"name": "ftrackreview-mp4",
"metadata": {'ftr_meta': json.dumps({
'frameIn': int(instance.data['startFrameReview']),
'frameOut': int(instance.data['endFrameReview']),
'frameRate': 25.0})}
'frameIn': int(comp['startFrameReview']),
'frameOut': int(comp['endFrameReview']),
'frameRate': float(comp['frameRate')]})}
}
else:
component_data = {

View file

@ -10,6 +10,7 @@ class ComponentItem(QtWidgets.QFrame):
C_HOVER = '#ffffff'
C_ACTIVE = '#4BB543'
C_ACTIVE_HOVER = '#4BF543'
signal_remove = QtCore.Signal(object)
signal_thumbnail = QtCore.Signal(object)
signal_preview = QtCore.Signal(object)
@ -291,4 +292,12 @@ class ComponentItem(QtWidgets.QFrame):
'thumbnail': self.is_thumbnail(),
'preview': self.is_preview()
}
if ('startFrame' in self.in_data and 'endFrame' in self.in_data):
data['startFrame'] = self.in_data['startFrame']
data['endFrame'] = self.in_data['endFrame']
if 'frameRate' in self.in_data:
data['frameRate'] = self.in_data['frameRate']
return data

View file

@ -1,5 +1,6 @@
import os
import re
import json
import clique
import subprocess
from pypeapp import config
@ -49,7 +50,7 @@ class DropDataFrame(QtWidgets.QFrame):
else:
# If path is in clipboard as string
try:
path = ent.text()
path = os.path.normpath(ent.text())
if os.path.exists(path):
paths.append(path)
else:
@ -170,6 +171,13 @@ class DropDataFrame(QtWidgets.QFrame):
repr_name = file_ext.replace('.', '')
range = collection.format('{ranges}')
# TODO: ranges must not be with missing frames!!!
# - this is goal implementation:
# startFrame, endFrame = range.split('-')
rngs = range.split(',')
startFrame = rngs[0].split('-')[0]
endFrame = rngs[-1].split('-')[-1]
actions = []
data = {
@ -177,39 +185,15 @@ class DropDataFrame(QtWidgets.QFrame):
'name': file_base,
'ext': file_ext,
'file_info': range,
'startFrame': startFrame,
'endFrame': endFrame,
'representation': repr_name,
'folder_path': folder_path,
'is_sequence': True,
'actions': actions
}
self._process_data(data)
def _get_ranges(self, indexes):
if len(indexes) == 1:
return str(indexes[0])
ranges = []
first = None
last = None
for index in indexes:
if first is None:
first = index
last = index
elif (last+1) == index:
last = index
else:
if first == last:
range = str(first)
else:
range = '{}-{}'.format(first, last)
ranges.append(range)
first = index
last = index
if first == last:
range = str(first)
else:
range = '{}-{}'.format(first, last)
ranges.append(range)
return ', '.join(ranges)
self._process_data(data)
def _process_remainder(self, remainder):
filename = os.path.basename(remainder)
@ -232,39 +216,75 @@ class DropDataFrame(QtWidgets.QFrame):
'is_sequence': False,
'actions': actions
}
data['file_info'] = self.get_file_info(data)
self._process_data(data)
def get_file_info(self, data):
output = None
if data['ext'] == '.mov':
try:
# ffProbe must be in PATH
filepath = data['files'][0]
args = ['ffprobe', '-show_streams', filepath]
p = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True
)
datalines=[]
for line in iter(p.stdout.readline, b''):
line = line.decode("utf-8").replace('\r\n', '')
datalines.append(line)
def load_data_with_probe(self, filepath):
args = [
'ffprobe',
'-v', 'quiet',
'-print_format', 'json',
'-show_format',
'-show_streams', filepath
]
ffprobe_p = subprocess.Popen(
args,
stdout=subprocess.PIPE,
shell=True
)
ffprobe_output = ffprobe_p.communicate()[0]
if ffprobe_p.returncode != 0:
raise RuntimeError(
'Failed on ffprobe: check if ffprobe path is set in PATH env'
)
return json.loads(ffprobe_output)['streams'][0]
def get_file_data(self, data):
filepath = data['files'][0]
ext = data['ext']
output = {}
probe_data = self.load_data_with_probe(filepath)
if (
ext in self.presets['extensions']['image_file'] or
ext in self.presets['extensions']['video_file']
):
if 'frameRate' not in data:
# default value
frameRate = 25
frameRate_string = probe_data.get('r_frame_rate')
if frameRate_string:
frameRate = int(frameRate_string.split('/')[0])
output['frameRate'] = frameRate
if 'startFrame' not in data or 'endFrame' not in data:
startFrame = endFrame = 1
endFrame_string = probe_data.get('nb_frames')
if endFrame_string:
endFrame = int(endFrame_string)
output['startFrame'] = startFrame
output['endFrame'] = endFrame
file_info = None
if 'file_info' in data:
file_info = data['file_info']
elif ext in ['.mov']:
file_info = probe_data.get('codec_name')
output['file_info'] = file_info
find_value = 'codec_name'
for line in datalines:
if line.startswith(find_value):
output = line.replace(find_value + '=', '')
break
except Exception as e:
pass
return output
def _process_data(self, data):
ext = data['ext']
# load file data info
file_data = self.get_file_data(data)
for key, value in file_data.items():
data[key] = value
icon = 'default'
for ico, exts in self.presets['extensions'].items():
if ext in exts: