Skip to content

Editorial_pkg: publishing sequence into OTIO timeline with rendered media #132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
72c2f1e
wip for creator, collector and extractor for editorial product type
moonyuet Oct 10, 2024
ef4e87d
remove collect editorial as it is not gonna use for this workflow
moonyuet Oct 10, 2024
9f24405
remove otio-related workflow as it is not related to this PR
moonyuet Oct 10, 2024
f96b691
wip the creator and render for clip function
moonyuet Oct 11, 2024
bbfafef
wip the creator
moonyuet Oct 11, 2024
58e46bf
wip on the creator and collector
moonyuet Oct 14, 2024
b6082c4
wip on the creator
moonyuet Oct 14, 2024
427828e
use editorial pkg product type
moonyuet Oct 15, 2024
f4a6956
remove to return unnecessary function
moonyuet Oct 15, 2024
4962722
wip on implementation
moonyuet Oct 15, 2024
ea40c2d
draft the otio_unreal_export script
moonyuet Oct 31, 2024
9377c8d
draft the otio_unreal_export script
moonyuet Oct 31, 2024
47dd36a
resolve conflict
moonyuet Nov 1, 2024
3001478
wip creator
moonyuet Nov 1, 2024
521d94b
wip creator
moonyuet Nov 1, 2024
1e60e01
add intermediate renders and supports rendering for editorial package
moonyuet Nov 4, 2024
4864345
add the check on the publish error in the collector if the users do n…
moonyuet Nov 4, 2024
306cd6e
make sure the frame range is correct
moonyuet Nov 4, 2024
6f93a9c
edit rendering py for rendering out the image in different directory
moonyuet Nov 4, 2024
c6afe1e
fix the enumerate value
moonyuet Nov 4, 2024
be237a5
update the intermediate render product type as editorial publish and …
moonyuet Nov 5, 2024
2cbab6e
edit the unreal_export.py
moonyuet Nov 5, 2024
b146626
coverting otio logic to accompany wioth unreal in unreal_export.py
moonyuet Nov 5, 2024
9291eaa
coverting otio logic to accompany wioth unreal in unreal_export.py
moonyuet Nov 5, 2024
78d794e
implement unreal logic into unreal_export.py
moonyuet Nov 6, 2024
beb46a3
impelement the extractor for intermediate render
moonyuet Nov 7, 2024
fd08023
implement pre-launch hook for otio installation
moonyuet Nov 8, 2024
adf1d84
implement extract edidtorial package.py
moonyuet Nov 8, 2024
454c941
make sure the opentimelineio is using 0.16.0
moonyuet Nov 8, 2024
aa662db
edit the unreal export.py for getting correct track name
moonyuet Nov 8, 2024
726e169
update the extract data for the representation
moonyuet Nov 8, 2024
8e5a726
add remove tags
moonyuet Nov 8, 2024
90a08c9
add remove tags
moonyuet Nov 8, 2024
b08b410
ruff cosmetic fix
moonyuet Nov 8, 2024
f5a6ce1
uses get_name instead of get_sequence().get_name()
moonyuet Nov 11, 2024
ac16030
uses get_name instead of get_sequence().get_name()
moonyuet Nov 11, 2024
403cf56
resolve conflict
moonyuet Nov 13, 2024
aa61db2
make sure the image sequences not being rendered per sub sequence dur…
moonyuet Nov 13, 2024
afebb9c
rename the collector and name of the hook for otio according to Jeza'…
moonyuet Feb 18, 2025
ba81eff
Merge branch 'develop' into feature/AY-6916_Editorial-publish-from-Un…
jakubjezek001 Jun 17, 2025
88f3e04
make sure editorial package published successfully
moonyuet Jun 23, 2025
8fd04af
Add MovieSceneSubTrack as TRACK_TYPES
moonyuet Jun 27, 2025
d7a9519
Merge branch 'develop' into feature/AY-6916_Editorial-publish-from-Un…
moonyuet Jun 27, 2025
0c86f21
Add condition check on getting sequence shot name as track name
moonyuet Jun 30, 2025
e0eb3d5
use sequence name instead
moonyuet Jun 30, 2025
de5418d
check if the section is MovieSceneCInematicShotTrack ifnot it will us…
moonyuet Jun 30, 2025
53ee6a8
implement the condition check on the section in create_otio_clip
moonyuet Jul 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion client/ayon_unreal/api/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
)
from ayon_unreal.api.pipeline import (
get_camera_tracks,
ls
ls,
UNREAL_VERSION
)
from ayon_core.pipeline.context_tools import get_current_folder_entity
import ayon_api
Expand Down Expand Up @@ -306,3 +307,42 @@ def import_animation(
sequence.get_playback_end())
sec_params = section.get_editor_property('params')
sec_params.set_editor_property('animation', animation)


def get_shot_track_names(sel_objects=None, get_name=True):
selection = [
a for a in sel_objects
if a.get_class().get_name() == "LevelSequence"
]
if (
UNREAL_VERSION.major == 5
and UNREAL_VERSION.minor > 4
):
sub_sequence_tracks = [
track for sel in selection for track in
sel.find_tracks_by_type(unreal.MovieSceneSubTrack)
]
else:
sub_sequence_tracks = [
track for sel in selection for track in
sel.find_master_tracks_by_type(unreal.MovieSceneSubTrack)
]

if get_name:
return [shot_tracks.get_display_name() for shot_tracks in
sub_sequence_tracks]
else:
return [shot_tracks for shot_tracks in sub_sequence_tracks]


def get_shot_tracks(members):
ar = unreal.AssetRegistryHelpers.get_asset_registry()
selected_sequences = [
ar.get_asset_by_object_path(member).get_asset() for member in members
]
return get_shot_track_names(selected_sequences, get_name=False)


def get_screen_resolution():
game_user_settings = unreal.GameUserSettings.get_game_user_settings()
return game_user_settings.get_screen_resolution()
56 changes: 56 additions & 0 deletions client/ayon_unreal/api/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,30 @@ def get_subsequences(sequence: unreal.LevelSequence):
return []


def get_movie_shot_tracks(sequence: unreal.LevelSequence):
"""Get list of movie shot tracks from sequence.

Args:
sequence (unreal.LevelSequence): Sequence

Returns:
list(unreal.LevelSequence): List of movie shot tracks

"""
tracks = sequence.find_master_tracks_by_type(unreal.MovieSceneSubTrack)
subscene_track = next(
(
t
for t in tracks
if t.get_class() == unreal.MovieSceneCinematicShotTrack.static_class()
),
None,
)
if subscene_track is not None and subscene_track.get_sections():
return subscene_track.get_sections()
return []


def set_sequence_hierarchy(
seq_i, seq_j, max_frame_i, min_frame_j, max_frame_j, map_paths
):
Expand Down Expand Up @@ -951,6 +975,38 @@ def get_sequence(files):
return [os.path.basename(filename) for filename in collections[0]]


def get_sequence_for_otio(files):
"""Get sequence from filename.

This will only return files if they exist on disk as it tries
to collect the sequence using the filename pattern and searching
for them on disk.

Supports negative frame ranges like -001, 0000, 0001 and -0001,
0000, 0001.

Arguments:
files (str): List of files

Returns:
Optional[list[str]]: file sequence.
Optional[str]: file head.

"""
base_filenames = [os.path.basename(filename) for filename in files]
collections, _remainder = clique.assemble(
base_filenames,
patterns=[clique.PATTERNS["frames"]],
minimum_items=1)

if len(collections) > 1:
raise ValueError(
f"Multiple collections found for {collections}. "
"This is a bug.")
filename_padding = collections[0].padding
return filename_padding


def find_camera_actors_in_camera_tracks(sequence) -> list[Any]:
"""Find the camera actors in the tracks from the Level Sequence

Expand Down
15 changes: 9 additions & 6 deletions client/ayon_unreal/api/rendering.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os

import unreal

from ayon_core.settings import get_project_settings
Expand Down Expand Up @@ -131,7 +130,7 @@ def start_rendering():

for i in instances:
data = pipeline.parse_container(i.get_path_name())
if data["productType"] == "render":
if data["productType"] == "render" or "editorial_pkg":
inst_data.append(data)

try:
Expand Down Expand Up @@ -161,6 +160,8 @@ def start_rendering():
current_level_name = current_level.get_outer().get_path_name()

for i in inst_data:
if i["productType"] == "editorial_pkg":
render_dir = f"{root}/{project_name}/editorial_pkg"
sequence = ar.get_asset_by_object_path(i["sequence"]).get_asset()

sequences = [{
Expand All @@ -178,12 +179,15 @@ def start_rendering():
for seq in sequences:
subscenes = pipeline.get_subsequences(seq.get('sequence'))

if subscenes:
if subscenes and i["productType"] != "editorial_pkg":
for sub_seq in subscenes:
sub_seq_obj = sub_seq.get_sequence()
if sub_seq_obj is None:
continue
sequences.append({
"sequence": sub_seq.get_sequence(),
"sequence": sub_seq_obj,
"output": (f"{seq.get('output')}/"
f"{sub_seq.get_sequence().get_name()}"),
f"{sub_seq_obj.get_name()}"),
"frame_range": (
sub_seq.get_start_frame(), sub_seq.get_end_frame())
})
Expand Down Expand Up @@ -215,7 +219,6 @@ def start_rendering():
# read in the job's OnJobFinished callback. We could,
# for instance, pass the AyonPublishInstance's path to the job.
# job.user_data = ""

output_dir = render_setting.get('output')
shot_name = render_setting.get('sequence').get_name()

Expand Down
Loading