mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
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:
commit
d8265ec2f2
4 changed files with 95 additions and 67 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue