Beispiel #1
0
    def create_level(self):
        self.ass_lev = unreal.AssetToolsHelpers.get_asset_tools().create_asset(
            asset_name=self.ass_lev_name,
            package_path=self.ass_lev_path,
            asset_class=unreal.World,
            factory=unreal.WorldFactory())

        self.ass = unreal.AssetToolsHelpers.get_asset_tools().create_asset(
            asset_name=self.ass_name,
            package_path=self.ass_path,
            asset_class=unreal.LevelSequence,
            factory=unreal.LevelSequenceFactoryNew())
        self.ass.set_display_rate(unreal.FrameRate(self.fps, 1))

        # 设置关卡序列的开始帧
        self.ass.make_range(self.start, self.end)
        self.ass.set_playback_start(self.start)
        self.ass.set_playback_end(self.end)

        self.ass.set_work_range_start(self.start / self.fps)
        self.ass.set_work_range_end(self.end / self.fps)

        self.ass.set_view_range_start(self.start / self.fps)
        self.ass.set_view_range_end(self.end / self.fps)
        # 添加摄像机关卡
        unreal.EditorLevelLibrary().load_level("{path}{name}.{name}".format(
            path=self.ass_lev_path, name=self.ass_lev_name))  # 打开创建的关卡
    def read_config(self, text=True):
        self.ini_file = self.Config_LE.text()
        if not os.path.exists(self.ini_file):
            toast(u"配置路径不存在")
            self.Config_LE.setText("")
            return

        # print(self.ini_file)

        self.config = ConfigParser() if six.PY2 else ConfigParser(strict=False)
        self.config.read(self.ini_file)

        section = "MovieSceneCaptureUIInstance AutomatedLevelSequenceCapture"
        option = "Settings"
        try:
            capture_settings = self.config.get(section, option)
        except:
            return
        capture_settings_dict = self.json_config[section][option]
        capture_settings = capture_settings[1:-1]
        pattern = re.compile("\((.+?)\)")
        value_list = []
        for i, match in enumerate(pattern.findall(capture_settings)):
            capture_settings = capture_settings.replace(match, "$$%s$$" % i)
            value_list.append(match)

        # NOTE 设置
        for pair in capture_settings.split(","):
            k, v = pair.split("=")
            v = value_list[int(v[3])] if v.startswith("($$") else v
            k = capture_settings_dict.get(k)
            if not k:
                continue
            elif k == "output_directory":
                self.Output_LE.setText(v[6:-1].replace("\\\\", "\\")) if text else None
            elif text and k == "output_format":
                self.FileName_LE.setText(v[1:-1]) if text else None
            elif k == "game_mode_override":
                if v == "None":
                    continue
                v = v.split('"')[1]
                v = unreal.load_class(None, v)
                self.capture_settings.set_editor_property(k, v)
            elif k == "custom_frame_rate":
                numerator, denominator = v.split(",")
                numerator = numerator.split("=")[1]
                denominator = denominator.split("=")[1]
                v = unreal.FrameRate(int(numerator), int(denominator))
                self.capture_settings.set_editor_property(k, v)
            elif k == "resolution":
                x, y = v.split(",")
                x = x.split("=")[1]
                y = y.split("=")[1]
                v = unreal.CaptureResolution(int(x), int(y))
                self.capture_settings.set_editor_property(k, v)
            else:
                v = ast.literal_eval(v)
                self.capture_settings.set_editor_property(k, v)
def CreateSequencer():

    import unreal
    import os.path
    import sys
    import time
    import json
    '''
    if int(unreal.SystemLibrary.get_engine_version()[:4][2:]) >= 26:
        import configparser as ConfigParser
    else:
        import ConfigParser
    '''

    # Prepare process import
    json_data_file = 'ImportSequencerData.json'
    dir_path = os.path.dirname(os.path.realpath(__file__))

    with open(os.path.join(dir_path, json_data_file), "r") as json_file:
        sequence_data = json.load(json_file)

    spawnable_camera = sequence_data['spawnable_camera']
    startFrame = sequence_data['startFrame']
    endFrame = sequence_data['endFrame'] + 1
    render_resolution_x = sequence_data['render_resolution_x']
    render_resolution_y = sequence_data['render_resolution_y']
    frameRateDenominator = sequence_data['frameRateDenominator']
    frameRateNumerator = sequence_data['frameRateNumerator']
    secureCrop = sequence_data[
        'secureCrop']  # add end crop for avoid section overlay
    unreal_import_location = sequence_data['unreal_import_location']
    ImportedCamera = []  # (CameraName, CameraGuid)

    def AddSequencerSectionTransformKeysByIniFile(sequencer_section,
                                                  track_dict):
        for key in track_dict.keys():
            value = track_dict[key]  # (x,y,z x,y,z x,y,z)
            frame = unreal.FrameNumber(int(key))

            sequencer_section.get_channels()[0].add_key(
                frame, value["location_x"])
            sequencer_section.get_channels()[1].add_key(
                frame, value["location_y"])
            sequencer_section.get_channels()[2].add_key(
                frame, value["location_z"])
            sequencer_section.get_channels()[3].add_key(
                frame, value["rotation_x"])
            sequencer_section.get_channels()[4].add_key(
                frame, value["rotation_y"])
            sequencer_section.get_channels()[5].add_key(
                frame, value["rotation_z"])
            sequencer_section.get_channels()[6].add_key(
                frame, value["scale_x"])
            sequencer_section.get_channels()[7].add_key(
                frame, value["scale_y"])
            sequencer_section.get_channels()[8].add_key(
                frame, value["scale_z"])

    def AddSequencerSectionFloatKeysByIniFile(sequencer_section, track_dict):
        for key in track_dict.keys():
            frame = unreal.FrameNumber(int(key))
            value = track_dict[key]
            sequencer_section.get_channels()[0].add_key(frame, value)

    def AddSequencerSectionBoolKeysByIniFile(sequencer_section, track_dict):
        for key in track_dict.keys():
            frame = unreal.FrameNumber(int(key))
            value = track_dict[key]
            sequencer_section.get_channels()[0].add_key(frame, value)

    print("Warning this file already exists")  # ???
    factory = unreal.LevelSequenceFactoryNew()
    asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
    seq = asset_tools.create_asset_with_dialog('MySequence', '/Game', None,
                                               factory)
    if seq is None:
        return 'ERROR: level sequencer factory_create fail'

    print("Sequencer reference created")
    print(seq)

    # Process import
    print(
        "========================= Import started ! =========================")

    # Set frame rate
    myFFrameRate = unreal.FrameRate()
    myFFrameRate.denominator = frameRateDenominator
    myFFrameRate.numerator = frameRateNumerator
    seq.set_display_rate(myFFrameRate)

    # Set playback range
    seq.set_playback_end_seconds(
        (endFrame - secureCrop) / float(frameRateNumerator))
    seq.set_playback_start_seconds(
        startFrame / float(frameRateNumerator))  # set_playback_end_seconds
    camera_cut_track = seq.add_master_track(unreal.MovieSceneCameraCutTrack)
    camera_cut_track.set_editor_property('display_name',
                                         'Imported Camera Cuts')
    if int(unreal.SystemLibrary.get_engine_version()[:4][2:]) >= 26:
        camera_cut_track.set_color_tint(unreal.Color(b=200, g=0, r=0, a=0))
    else:
        pass

    for x, camera_data in enumerate(sequence_data["cameras"]):
        # import camera
        print("Start camera import " + str(x + 1) + "/" +
              str(len(sequence_data["cameras"])) + " :" + camera_data["name"])
        # Import camera tracks transform

        with open(camera_data["additional_tracks_path"], "r") as json_file:
            camera_tracks = json.load(json_file)

        # Create spawnable camera and add camera in sequencer
        cine_camera_actor = unreal.EditorLevelLibrary().spawn_actor_from_class(
            unreal.CineCameraActor, unreal.Vector(0, 0, 0),
            unreal.Rotator(0, 0, 0))

        # Import additional tracks (camera_component)
        camera_component_binding = seq.add_possessable(
            cine_camera_actor.get_cine_camera_component())
        # Get the last

        TrackFocalLength = camera_component_binding.add_track(
            unreal.MovieSceneFloatTrack)
        TrackFocalLength.set_property_name_and_path('CurrentFocalLength',
                                                    'CurrentFocalLength')
        TrackFocalLength.set_editor_property('display_name',
                                             'Current Focal Length')
        sectionFocalLength = TrackFocalLength.add_section()
        sectionFocalLength.set_end_frame_bounded(False)
        sectionFocalLength.set_start_frame_bounded(False)
        AddSequencerSectionFloatKeysByIniFile(
            sectionFocalLength, camera_tracks['Camera FocalLength'])

        TrackSensorWidth = camera_component_binding.add_track(
            unreal.MovieSceneFloatTrack)
        TrackSensorWidth.set_property_name_and_path('Filmback.SensorWidth',
                                                    'Filmback.SensorWidth')
        TrackSensorWidth.set_editor_property('display_name',
                                             'Sensor Width (Filmback)')
        sectionSensorWidth = TrackSensorWidth.add_section()
        sectionSensorWidth.set_end_frame_bounded(False)
        sectionSensorWidth.set_start_frame_bounded(False)
        AddSequencerSectionFloatKeysByIniFile(
            sectionSensorWidth, camera_tracks['Camera SensorWidth'])

        TrackSensorHeight = camera_component_binding.add_track(
            unreal.MovieSceneFloatTrack)
        TrackSensorHeight.set_property_name_and_path('Filmback.SensorHeight',
                                                     'Filmback.SensorHeight')
        TrackSensorHeight.set_editor_property('display_name',
                                              'Sensor Height (Filmback)')
        sectionSensorHeight = TrackSensorHeight.add_section()
        sectionSensorHeight.set_end_frame_bounded(False)
        sectionSensorHeight.set_start_frame_bounded(False)

        crop_camera_sensor_height = {}
        for key in camera_tracks['Camera SensorHeight'].keys():
            original_width = float(camera_tracks['Camera SensorWidth'][key])
            original_height = float(camera_tracks['Camera SensorHeight'][key])
            res_x = float(sequence_data['render_resolution_x'])
            res_y = float(sequence_data['render_resolution_y'])
            pixel_x = float(sequence_data['pixel_aspect_x'])
            pixel_y = float(sequence_data['pixel_aspect_y'])
            res_ratio = res_x / res_y
            pixel_ratio = pixel_x / pixel_y

            crop_camera_sensor_height[key] = (original_width /
                                              (res_ratio * pixel_ratio))

        AddSequencerSectionFloatKeysByIniFile(sectionSensorHeight,
                                              crop_camera_sensor_height)

        TrackFocusDistance = camera_component_binding.add_track(
            unreal.MovieSceneFloatTrack)

        # Wtf this var name change every version or I do someting wrong??? :v
        if int(unreal.SystemLibrary.get_engine_version()[:4][2:]) >= 26:
            TrackFocusDistance.set_property_name_and_path(
                'FocusSettings.ManualFocusDistance',
                'FocusSettings.ManualFocusDistance')
            TrackFocusDistance.set_editor_property(
                'display_name', 'Manual Focus Distance (Focus Settings)')
        elif int(unreal.SystemLibrary.get_engine_version()[:4][2:]) >= 25:
            TrackFocusDistance.set_property_name_and_path(
                'FocusSettings.ManualFocusDistance',
                'FocusSettings.ManualFocusDistance')
            TrackFocusDistance.set_editor_property(
                'display_name', 'Manual Focus Distance (Focus Settings)')
        elif int(unreal.SystemLibrary.get_engine_version()[:4][2:]) >= 24:
            TrackFocusDistance.set_property_name_and_path(
                'CurrentFocusDistance', 'CurrentFocusDistance')
            TrackFocusDistance.set_editor_property('display_name',
                                                   'Current Focus Distance')
        else:
            TrackFocusDistance.set_property_name_and_path(
                'ManualFocusDistance', 'ManualFocusDistance')
            TrackFocusDistance.set_editor_property('display_name',
                                                   'Current Focus Distance')
        sectionFocusDistance = TrackFocusDistance.add_section()
        sectionFocusDistance.set_end_frame_bounded(False)
        sectionFocusDistance.set_start_frame_bounded(False)
        AddSequencerSectionFloatKeysByIniFile(
            sectionFocusDistance, camera_tracks['Camera FocusDistance'])

        TracknAperture = camera_component_binding.add_track(
            unreal.MovieSceneFloatTrack)
        TracknAperture.set_property_name_and_path('CurrentAperture',
                                                  'CurrentAperture')
        TracknAperture.set_editor_property('display_name', 'Current Aperture')
        sectionAperture = TracknAperture.add_section()
        sectionAperture.set_end_frame_bounded(False)
        sectionAperture.set_start_frame_bounded(False)
        AddSequencerSectionFloatKeysByIniFile(sectionAperture,
                                              camera_tracks['Camera Aperture'])

        # add a binding for the camera
        camera_binding = seq.add_possessable(cine_camera_actor)

        if spawnable_camera:
            # Transfer to spawnable camera
            camera_spawnable = seq.add_spawnable_from_class(
                unreal.CineCameraActor)  # Add camera in sequencer
            camera_component_binding.set_parent(camera_spawnable)

        # Import transform tracks
        if spawnable_camera:
            transform_track = camera_spawnable.add_track(
                unreal.MovieScene3DTransformTrack)
        else:
            transform_track = camera_binding.add_track(
                unreal.MovieScene3DTransformTrack)
        transform_section = transform_track.add_section()
        transform_section.set_end_frame_bounded(False)
        transform_section.set_start_frame_bounded(False)
        AddSequencerSectionTransformKeysByIniFile(
            transform_section, camera_tracks['Camera transform'])

        # Set property binding
        if spawnable_camera:
            current_camera_binding = camera_spawnable
        else:
            current_camera_binding = camera_binding

        if int(unreal.SystemLibrary.get_engine_version()[:4][2:]) >= 26:
            current_camera_binding.set_display_name(camera_data["name"])
        else:
            pass
        tracksSpawned = current_camera_binding.find_tracks_by_exact_type(
            unreal.MovieSceneSpawnTrack)
        if len(tracksSpawned) > 0:
            sectionSpawned = tracksSpawned[0].get_sections()[0]
            AddSequencerSectionBoolKeysByIniFile(
                sectionSpawned, camera_tracks['Camera Spawned'])

        # Set property actor
        if spawnable_camera:
            current_cine_camera_actor = camera_spawnable.get_object_template()
        else:
            current_cine_camera_actor = cine_camera_actor

        current_cine_camera_actor.set_actor_label(camera_data["name"])
        camera_component = cine_camera_actor.camera_component
        camera_component.aspect_ratio = render_resolution_x / render_resolution_y
        camera_component.lens_settings.min_f_stop = 0
        camera_component.lens_settings.max_f_stop = 1000

        # Clean the created assets
        if spawnable_camera:
            cine_camera_actor.destroy_actor()
            camera_binding.remove()

        if spawnable_camera:
            ImportedCamera.append((camera_data["name"], camera_spawnable))
        else:
            ImportedCamera.append((camera_data["name"], camera_binding))

    # Import camera cut section
    for section in sequence_data['marker_sections']:
        camera_cut_section = camera_cut_track.add_section()
        if section["has_camera"] is not None:
            for camera in ImportedCamera:
                if camera[0] == section["camera_name"]:
                    camera_binding_id = unreal.MovieSceneObjectBindingID()
                    camera_binding_id = seq.make_binding_id(
                        camera[1], unreal.MovieSceneObjectBindingSpace.LOCAL)
                    camera_cut_section.set_camera_binding_id(camera_binding_id)

        camera_cut_section.set_end_frame_seconds(
            (section["end_time"] - secureCrop) / float(frameRateNumerator))
        camera_cut_section.set_start_frame_seconds(section["start_time"] /
                                                   float(frameRateNumerator))
    # Import result
    print(
        '========================= Imports completed ! ========================='
    )
    ImportedCameraStr = []
    for cam in ImportedCamera:
        ImportedCameraStr.append(cam[0])
        print(ImportedCameraStr)
        print('=========================')

    # Select and open seq in content browser
    if int(unreal.SystemLibrary.get_engine_version()[:4][2:]) >= 26:
        unreal.AssetEditorSubsystem.open_editor_for_assets(
            unreal.AssetEditorSubsystem(),
            [unreal.load_asset(seq.get_path_name())])
    else:
        unreal.AssetToolsHelpers.get_asset_tools().open_editor_for_assets(
            [unreal.load_asset(seq.get_path_name())])

    unreal.EditorAssetLibrary.sync_browser_to_objects([seq.get_path_name()])
    return 'Sequencer created with success !'
def render(sequence_list,
           i,
           output_directory="C:/render",
           output_format="{sequence}"):

    # NOTE 如果超出数组则退出执行
    if i >= len(sequence_list):
        # NOTE 输出完成 打开输出文件夹的路径
        os.startfile(output_directory)
        return

    # NOTE 获取当前渲染序号下的 LevelSequence
    sequence = sequence_list[i]

    # NOTE 配置渲染参数
    settings = unreal.MovieSceneCaptureSettings()
    path = unreal.DirectoryPath(output_directory)
    settings.set_editor_property("output_directory", path)
    settings.set_editor_property("output_format", output_format)
    settings.set_editor_property("overwrite_existing", True)
    settings.set_editor_property("game_mode_override", None)
    settings.set_editor_property("use_relative_frame_numbers", False)
    settings.set_editor_property("handle_frames", 0)
    settings.set_editor_property("zero_pad_frame_numbers", 4)
    settings.set_editor_property("use_custom_frame_rate", True)
    settings.set_editor_property("custom_frame_rate", unreal.FrameRate(24, 1))

    # NOTE 渲染大小
    w, h = 1280, 720
    settings.set_editor_property("resolution", unreal.CaptureResolution(w, h))

    settings.set_editor_property("enable_texture_streaming", False)
    settings.set_editor_property("cinematic_engine_scalability", True)
    settings.set_editor_property("cinematic_mode", True)
    settings.set_editor_property("allow_movement", False)
    settings.set_editor_property("allow_turning", False)
    settings.set_editor_property("show_player", False)
    settings.set_editor_property("show_hud", False)

    # NOTE 设置默认的自动渲染参数
    option = unreal.AutomatedLevelSequenceCapture()
    option.set_editor_property("use_separate_process", False)
    option.set_editor_property("close_editor_when_capture_starts", False)
    option.set_editor_property("additional_command_line_arguments",
                               "-NOSCREENMESSAGES")
    option.set_editor_property("inherited_command_line_arguments", "")
    option.set_editor_property("use_custom_start_frame", False)
    option.set_editor_property("use_custom_end_frame", False)
    option.set_editor_property("warm_up_frame_count", 0.0)
    option.set_editor_property("delay_before_warm_up", 0)
    option.set_editor_property("delay_before_shot_warm_up", 0.0)
    option.set_editor_property("write_edit_decision_list", True)
    # option.set_editor_property("custom_start_frame",unreal.FrameNumber(0))
    # option.set_editor_property("custom_end_frame",unreal.FrameNumber(0))

    option.set_editor_property("settings", settings)
    option.set_editor_property("level_sequence_asset",
                               unreal.SoftObjectPath(sequence.get_path_name()))

    # NOTE 设置自定义渲染参数
    option.set_image_capture_protocol_type(
        unreal.CompositionGraphCaptureProtocol)
    protocol = option.get_image_capture_protocol()
    # NOTE 这里设置 Base Color 渲染 Base Color 通道,可以根据输出的 UI 设置数组名称
    passes = unreal.CompositionGraphCapturePasses(["Base Color"])
    protocol.set_editor_property("include_render_passes", passes)
    # protocol.set_editor_property("compression_quality",100)

    # NOTE 设置全局变量才起作用!
    global on_finished_callback
    on_finished_callback = unreal.OnRenderMovieStopped(lambda s: render(
        sequence_list, i + 1, output_directory, output_format))
    unreal.SequencerTools.render_movie(option, on_finished_callback)
Beispiel #5
0
def render_sequence_to_movie(sequencer_asset_path,
                             level_name,
                             level_path,
                             output_file_name,
                             resolution=(1280, 720),
                             game_mode_override='None',
                             warm_up_frame_count=0,
                             delay_before_warm_up=0.0,
                             delay_before_shot_warm_up=0.0,
                             delay_every_frame=0.0,
                             use_burn_in=False,
                             encorder_format='422'):
    # 1) Create an instance of our UAutomatedLevelSequenceCapture and override all of the settings on it. This class is currently
    # set as a config class so settings will leak between the Unreal Sequencer Render-to-Movie UI and this object. To work around
    # this, we set every setting via the script so that no changes the user has made via the UI will affect the script version.
    # The users UI settings will be reset as an unfortunate side effect of this.
    capture_settings = unreal.AutomatedLevelSequenceCapture()

    # Set all POD settings on the UMovieSceneCapture
    output_dir = unreal.SystemLibrary.get_project_directory(
    ) + "Saved/VideoCaptures/"
    capture_settings.settings.output_directory = unreal.DirectoryPath(
        output_dir)
    if not os.path.exists(output_dir):
        os.mkdir(output_dir)

    #capture_settings.settings.movie_extension = '.avi'

    # If you game mode is implemented in Blueprint, load_asset(...) is going to return you the C++ type ('Blueprint') and not what the BP says it inherits from.
    # Instead, because game_mode_override is a TSubclassOf<AGameModeBase> we can use unreal.load_class to get the UClass which is implicitly convertable.
    # ie: capture_settings.settings.game_mode_override = unreal.load_class(None, "/Game/AI/TestingSupport/AITestingGameMode.AITestingGameMode_C")

    editor_world_settings = unreal.EditorLevelLibrary.get_editor_world(
    ).get_world_settings()
    ''' game_mode_override is not working
		so change game_mode in world setting temporatily '''
    print "# World Setting - Game Mode Input = " + game_mode_override
    print "# World Setting - Game Mode = " + str(
        editor_world_settings.default_game_mode) + " - type = " + str(
            type(editor_world_settings.default_game_mode))
    if game_mode_override == 'None':
        unreal.EditorLevelLibrary.get_editor_world().get_world_settings(
        ).set_editor_property('default_game_mode', None)
    elif game_mode_override == 'BP_CameraGameMode':
        unreal.EditorLevelLibrary.get_editor_world().get_world_settings(
        ).set_editor_property(
            'default_game_mode',
            unreal.load_class(
                None,
                '/VirtualCamera/Custom/BP_CameraGameMode.BP_CameraGameMode_C'))
    else:
        pass

    print "# World Setting - Game Mode Override = " + str(
        editor_world_settings.default_game_mode) + " - type = " + str(
            type(editor_world_settings.default_game_mode))

    capture_settings.settings.game_mode_override = None
    #if game_mode_override=='BP_CameraGameMode':
    #	capture_settings.settings.game_mode_override = None
    capture_settings.settings.output_format = output_file_name
    capture_settings.settings.overwrite_existing = False
    capture_settings.settings.use_relative_frame_numbers = False
    capture_settings.settings.handle_frames = 0
    capture_settings.settings.zero_pad_frame_numbers = 4
    # If you wish to override the output framerate you can use these two lines, otherwise the framerate will be derived from the sequence being rendered
    capture_settings.settings.use_custom_frame_rate = True
    capture_settings.settings.custom_frame_rate = unreal.FrameRate(24, 1)
    capture_settings.settings.resolution.res_x = resolution[0]
    capture_settings.settings.resolution.res_y = resolution[1]
    capture_settings.settings.enable_texture_streaming = False
    capture_settings.settings.cinematic_engine_scalability = True
    capture_settings.settings.cinematic_mode = True
    capture_settings.settings.allow_movement = False  # Requires cinematic_mode = True
    capture_settings.settings.allow_turning = False  # Requires cinematic_mode = True
    capture_settings.settings.show_player = False  # Requires cinematic_mode = True
    capture_settings.settings.show_hud = False  # Requires cinematic_mode = True
    capture_settings.use_separate_process = False
    capture_settings.close_editor_when_capture_starts = False  # Requires use_separate_process = True
    capture_settings.additional_command_line_arguments = "-NOSCREENMESSAGES"  # Requires use_separate_process = True
    capture_settings.inherited_command_line_arguments = ""  # Requires use_separate_process = True

    # Set all the POD settings on UAutomatedLevelSequenceCapture
    capture_settings.use_custom_start_frame = False  # If False, the system will automatically calculate the start based on sequence content
    capture_settings.use_custom_end_frame = False  # If False, the system will automatically calculate the end based on sequence content
    capture_settings.custom_start_frame = unreal.FrameNumber(
        0)  # Requires use_custom_start_frame = True
    capture_settings.custom_end_frame = unreal.FrameNumber(
        0)  # Requires use_custom_end_frame = True
    capture_settings.warm_up_frame_count = warm_up_frame_count
    capture_settings.delay_before_warm_up = delay_before_warm_up
    capture_settings.delay_before_shot_warm_up = delay_before_shot_warm_up
    capture_settings.delay_every_frame = delay_every_frame

    capture_settings.write_edit_decision_list = True

    # Tell the capture settings which level sequence to render with these settings. The asset does not need to be loaded,
    # as we're only capturing the path to it and when the PIE instance is created it will load the specified asset.
    # If you only had a reference to the level sequence, you could use "unreal.SoftObjectPath(mysequence.get_path_name())"
    capture_settings.level_sequence_asset = unreal.SoftObjectPath(
        sequencer_asset_path)

    # To configure the video output we need to tell the capture settings which capture protocol to use. The various supported
    # capture protocols can be found by setting the Unreal Content Browser to "Engine C++ Classes" and filtering for "Protocol"
    # ie: CompositionGraphCaptureProtocol, ImageSequenceProtocol_PNG, etc. Do note that some of the listed protocols are not intended
    # to be used directly.
    # Right click on a Protocol and use "Copy Reference" and then remove the extra formatting around it. ie:
    # Class'/Script/MovieSceneCapture.ImageSequenceProtocol_PNG' gets transformed into "/Script/MovieSceneCapture.ImageSequenceProtocol_PNG"

    #capture_settings.set_image_capture_protocol_type(unreal.load_class(None, "/Script/MovieSceneCapture.VideoCaptureProtocol"))
    capture_settings.set_image_capture_protocol_type(
        unreal.load_class(
            None, "/Script/AppleProResMedia.AppleProResEncoderProtocol"))
    # After we have set the capture protocol to a soft class path we can start editing the settings for the instance of the protocol that is internallyc reated.
    #capture_settings.get_image_capture_protocol().compression_quality = 100

    # The other complex settings is the burn-in. Create an instance of the LevelSequenceBurnInOptions which is used to
    # specify if we should use a burn in, and then which settings.
    burn_in_options = unreal.LevelSequenceBurnInOptions()
    #unreal.log('use_burn_in =' + str(use_burn_in))
    burn_in_options.use_burn_in = use_burn_in
    #unreal.log('burn_in_options.use_burn_in =' + str(burn_in_options.use_burn_in))

    # You have to specify a path to a class to use for the burn in (if use_burn_in = True), and this class specifies a UClass to define the
    # settings object type. We've created a convinence function which takes the class path, loads the class at that path and assigns it to
    # the Settings object.
    #burn_in_options.set_burn_in(unreal.SoftClassPath("/Engine/Sequencer/DefaultBurnIn.DefaultBurnIn_C"))
    burn_in_options.set_burn_in(
        unreal.SoftClassPath("/MofacRenderMovie/CustomBurnIn.CustomBurnIn_C"))

    # The default burn in is implemented entirely in Blueprint which means that the method we've been using to set properties will not
    # work for it. The python bindings that turn bSomeVariableName into "some_variable_name" only work for C++ classes with
    # UPROPERTY(BlueprintReadWrite) marked fields. Python doesn't know about the existence of Blueprint classes and their fields, so we
    # have to use an alternative method.
    burn_in_options.settings.set_editor_property(
        'TopLeftText', "{FocalLength}mm,{Aperture},{FocusDistance}")
    burn_in_options.settings.set_editor_property(
        'TopCenterText',
        "{MasterName} - {Date} - {EngineVersion} - " + proj_names)
    burn_in_options.settings.set_editor_property('TopRightText', artist_names)

    burn_in_options.settings.set_editor_property(
        'BottomLeftText',
        "Level: " + level_name + "\nPath: " + level_path + "\n{ShotName}")
    burn_in_options.settings.set_editor_property(
        'BottomCenterText', "{hh}:{mm}:{ss}:{ff} ({MasterFrame})")
    burn_in_options.settings.set_editor_property(
        'BottomRightText',
        "{shh}:{smm}:{sss}:{sff} {SourceTimecode} {ShotFrame}")

    # Load a Texture2D asset and assign it to the UTexture2D reference that Watermark is.
    # burn_in_settings.set_editor_property('Watermark', None)
    # Note that this example creates a really obvious watermark (a big blurry green smiley face) just so that you know it's working!
    #burn_in_options.settings.set_editor_property('Watermark', unreal.load_asset("/Engine/EngineResources/AICON-Green"))
    #burn_in_options.settings.set_editor_property('WatermarkTint', unreal.LinearColor(1.0, 0.5, 0.5, 0.5)) # Create a FLinearColor to tint our Watermark

    # Assign our created instances to our original capture_settings object.
    capture_settings.burn_in_options = burn_in_options

    # Finally invoke Sequencer's Render to Movie functionality. This will examine the specified settings object and either construct a new PIE instance to render in,
    # or create and launch a new process (optionally shutting down your editor).

    #unreal.log(capture_settings.get_image_capture_protocol().get_editor_property('EncodingFormat'))
    '''
	enum class EAppleProResEncoderFormats : uint8
	{
		F_422HQ UMETA(DisplayName = "422 HQ"),
		F_422 UMETA(DisplayName = "422"),
		F_422LT UMETA(DisplayName = "422 LT"),
		F_422Proxy UMETA(DisplayName = "422 Proxy"),
		F_4444 UMETA(DisplayName = "4444"),
		F_4444XQ UMETA(DisplayName = "4444 XQ"),
	};
	'''
    TargetEncoderFormat = unreal.AppleProResEncoderFormats.F_422
    #print type(TargetEncoderFormat)
    #print TargetEncoderFormat
    #print dir(type(TargetEncoderFormat))
    if encorder_format == '422 HQ':
        TargetEncoderFormat = unreal.AppleProResEncoderFormats.F_422HQ
    elif encorder_format == '422':
        pass
    elif encorder_format == '422 LT':
        TargetEncoderFormat = unreal.AppleProResEncoderFormats.F_422LT
    elif encorder_format == '422 Proxy':
        TargetEncoderFormat = unreal.AppleProResEncoderFormats.F_422_PROXY
    elif encorder_format == '4444':
        TargetEncoderFormat = unreal.AppleProResEncoderFormats.F_4444
    elif encorder_format == '4444 XQ':
        TargetEncoderFormat = unreal.AppleProResEncoderFormats.F_4444XQ

    capture_settings.get_image_capture_protocol().set_editor_property(
        'EncodingFormat', TargetEncoderFormat)

    if args.use_audio_capture:
        capture_settings.set_audio_capture_protocol_type(
            unreal.load_class(
                None,
                "/Script/MovieSceneCapture.MasterAudioSubmixCaptureProtocol"))
        capture_settings.get_audio_capture_protocol().set_editor_property(
            'FileName', output_file_name)
    #unreal.log(capture_settings.get_image_capture_protocol().get_editor_property('EncodingFormat'))
    #unreal.log(type(capture_settings.get_image_capture_protocol().get_editor_property('EncodingFormat')))

    unreal.SequencerTools.render_movie(capture_settings, on_finished_callback)
def CreateSequencer():
		import os.path
		import time
		import ConfigParser
		import unreal
	
	
		seqPath = r"/Game/ImportedFbx/Sequencer"
		seqName = r'MySequence'
		seqTempName = r'MySequence'+str(time.time())
		startFrame = 1
		endFrame = 251
		frameRateDenominator = 1.0
		frameRateNumerator = 25
		secureCrop = 0.0001 #add end crop for avoid section overlay
	
	
		def AddSequencerSectionTransformKeysByIniFile(SequencerSection, SectionFileName, FileLoc):
			Config = ConfigParser.ConfigParser()
			Config.read(FileLoc)
			for option in Config.options(SectionFileName):
				frame = float(option)/float(frameRateNumerator) #FrameRate
				list = Config.get(SectionFileName, option)
				for x in range(0, 9): #(x,y,z x,y,z x,y,z)
					value = float(list.split(',')[x])
					SequencerSection.get_channels()[x].add_key(unreal.FrameNumber(frame*float(frameRateNumerator)),value)
	
	
		def AddSequencerSectionFloatKeysByIniFile(SequencerSection, SectionFileName, FileLoc):
			Config = ConfigParser.ConfigParser()
			Config.read(FileLoc)
			for option in Config.options(SectionFileName):
				frame = float(option)/float(frameRateNumerator) #FrameRate
				value = float(Config.get(SectionFileName, option))
				SequencerSection.get_channels()[0].add_key(unreal.FrameNumber(frame*float(frameRateNumerator)),value)
	
	
		def AddSequencerSectionBoolKeysByIniFile(SequencerSection, SectionFileName, FileLoc):
			Config = ConfigParser.ConfigParser()
			Config.read(FileLoc)
			for option in Config.options(SectionFileName):
				frame = float(option)/float(frameRateNumerator) #FrameRate
				value = Config.getboolean(SectionFileName, option)
				SequencerSection.get_channels()[0].add_key(unreal.FrameNumber(frame*float(frameRateNumerator)),value)
	
	
		print("Warning this file already exists")
		factory = unreal.LevelSequenceFactoryNew()
		asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
		seq = asset_tools.create_asset_with_dialog(seqName.replace('.',''), seqPath, None, factory)
		if seq is None:
			return 'Error /!\ level sequencer factory_create fail' 
	
		print("Sequencer reference created")
		print(seq)
		ImportedCamera = [] #(CameraName, CameraGuid)
		print("========================= Import started ! =========================")
		
		#Set frame rate
		myFFrameRate = unreal.FrameRate()
		myFFrameRate.denominator = frameRateDenominator
		myFFrameRate.numerator = frameRateNumerator
		seq.set_display_rate(myFFrameRate)
		#Set playback range
		seq.set_playback_end_seconds((endFrame-secureCrop)/float(frameRateNumerator))
		seq.set_playback_start_seconds(startFrame/float(frameRateNumerator))
		camera_cut_track = seq.add_master_track(unreal.MovieSceneCameraCutTrack)
	
	
		#Import camera cut section
		camera_cut_section = camera_cut_track.add_section()
		#Not camera found for this section
		camera_cut_section.set_end_frame_seconds((251-secureCrop)/float(frameRateNumerator))
		camera_cut_section.set_start_frame_seconds(1/float(frameRateNumerator))
		print('========================= Imports completed ! =========================')
		
		for cam in ImportedCamera:
			print(cam[0])
		
		print('=========================')
	#Select and open seq in content browser
		unreal.AssetToolsHelpers.get_asset_tools().open_editor_for_assets([unreal.load_asset(seqPath+'/'+seqName.replace('.',''))])
		unreal.EditorAssetLibrary.sync_browser_to_objects([seqPath+'/'+seqName.replace('.','')])
		return 'Sequencer created with success !' 
Beispiel #7
0
def render_sequence_to_movie(sequencer_asset_path):
    # 1) Create an instance of our UAutomatedLevelSequenceCapture and override all of the settings on it. This class is currently
    # set as a config class so settings will leak between the Unreal Sequencer Render-to-Movie UI and this object. To work around
    # this, we set every setting via the script so that no changes the user has made via the UI will affect the script version.
    # The users UI settings will be reset as an unfortunate side effect of this.
    capture_settings = unreal.AutomatedLevelSequenceCapture()

    # Set all POD settings on the UMovieSceneCapture
    capture_settings.settings.output_directory = unreal.DirectoryPath(
        "../../../QAGame/Saved/VideoCaptures/")

    # If you game mode is implemented in Blueprint, load_asset(...) is going to return you the C++ type ('Blueprint') and not what the BP says it inherits from.
    # Instead, because game_mode_override is a TSubclassOf<AGameModeBase> we can use unreal.load_class to get the UClass which is implicitly convertable.
    # ie: capture_settings.settings.game_mode_override = unreal.load_class(None, "/Game/AI/TestingSupport/AITestingGameMode.AITestingGameMode_C")
    capture_settings.settings.game_mode_override = None
    capture_settings.settings.output_format = "{world}"
    capture_settings.settings.overwrite_existing = True
    capture_settings.settings.use_relative_frame_numbers = False
    capture_settings.settings.handle_frames = 0
    capture_settings.settings.zero_pad_frame_numbers = 4
    capture_settings.settings.frame_rate = unreal.FrameRate(24, 1)
    capture_settings.settings.resolution.res_x = 1280
    capture_settings.settings.resolution.res_y = 720
    capture_settings.settings.enable_texture_streaming = False
    capture_settings.settings.cinematic_engine_scalability = True
    capture_settings.settings.cinematic_mode = True
    capture_settings.settings.allow_movement = False  # Requires cinematic_mode = True
    capture_settings.settings.allow_turning = False  # Requires cinematic_mode = True
    capture_settings.settings.show_player = False  # Requires cinematic_mode = True
    capture_settings.settings.show_hud = False  # Requires cinematic_mode = True
    capture_settings.use_separate_process = False
    capture_settings.close_editor_when_capture_starts = False  # Requires use_separate_process = True
    capture_settings.additional_command_line_arguments = "-NOSCREENMESSAGES"  # Requires use_separate_process = True
    capture_settings.inherited_command_line_arguments = ""  # Requires use_separate_process = True

    # Set all the POD settings on UAutomatedLevelSequenceCapture
    capture_settings.use_custom_start_frame = False  # If False, the system will automatically calculate the start based on sequence content
    capture_settings.use_custom_end_frame = False  # If False, the system will automatically calculate the end based on sequence content
    capture_settings.custom_start_frame = unreal.FrameNumber(
        0)  # Requires use_custom_start_frame = True
    capture_settings.custom_end_frame = unreal.FrameNumber(
        0)  # Requires use_custom_end_frame = True
    capture_settings.warm_up_frame_count = 0.0
    capture_settings.delay_before_warm_up = 0  # ToDo: Test int -> float
    capture_settings.delay_before_shot_warm_up = 0.0
    capture_settings.write_edit_decision_list = True

    # Tell the capture settings which level sequence to render with these settings. The asset does not need to be loaded,
    # as we're only capturing the path to it and when the PIE instance is created it will load the specified asset.
    # If you only had a reference to the level sequence, you could use "unreal.SoftObjectPath(mysequence.get_path_name())"
    capture_settings.level_sequence_asset = unreal.SoftObjectPath(
        sequencer_asset_path)

    # Now let's work on setting some more complex settings. The image capture is composed of two fields that need to correspond to each other.
    # The first field is the CaptureType ("Output Format" on the UI). This is how you specify if you want to output custom render passes, a video sequence, etc.
    # Then, once you decide on a capture type you also need to create an instance of the settings object specific to that capture type and assign it.
    # In this example, we will be using a Custom Render Passes output as it is the most complicated one to set up.
    #
    # The settings classes for each capture protocol can be found in the /Engine/Source/Runtime/MovieSceneCapture/Public/Protocols folder.
    # The identifier comes from MovieSceneCaptureModule.cpp ("CustomRenderPasses", "Video", "PNG", "JPG", "BMP")
    capture_settings.capture_type.identifier = "CustomRenderPasses"
    protocol_settings = unreal.CompositionGraphCaptureSettings()
    # The passes comes from BufferVisualizationData.cpp
    protocol_settings.include_render_passes.value.append("BaseColor")
    protocol_settings.include_render_passes.value.append("SceneDepth")
    protocol_settings.include_render_passes.value.append("Roughness")
    protocol_settings.capture_frames_in_hdr = False
    protocol_settings.hdr_compression_quality = 1  # Requires capture_frames_in_hdr = True, 0 means no compression, 1 means standard.
    protocol_settings.capture_gamut = unreal.HDRCaptureGamut.HCGM_REC709  # Requires capture_frames_in_hdr = True
    # protocol_settings.post_processing_material = unreal.SoftObjectPath("/Game/Path/To/Material")
    protocol_settings.post_processing_material = unreal.SoftObjectPath(
        "")  # Soft Object Paths use an empty string for None.
    protocol_settings.disable_screen_percentage = True

    # The other complex settings is the burn-in. Create an instance of the LevelSequenceBurnInOptions which is used to
    # specify if we should use a burn in, and then which settings.
    burn_in_options = unreal.LevelSequenceBurnInOptions()
    burn_in_options.use_burn_in = True

    # You have to specify a path to a class to use for the burn in (if use_burn_in = True), and this class specifies a UClass to define the
    # settings object type. We've created a convinence function which takes the class path, loads the class at that path and assigns it to
    # the Settings object.
    burn_in_options.set_burn_in(
        unreal.SoftClassPath(
            "/Engine/Sequencer/DefaultBurnIn.DefaultBurnIn_C"))

    # The default burn in is implemented entirely in Blueprint which means that the method we've been using to set properties will not
    # work for it. The python bindings that turn bSomeVariableName into "some_variable_name" only work for C++ classes with
    # UPROPERTY(BlueprintReadWrite) marked fields. Python doesn't know about the existence of Blueprint classes and their fields, so we
    # have to use an alternative method.
    burn_in_options.settings.set_editor_property(
        'TopLeftText', "{FocalLength}mm,{Aperture},{FocusDistance}")
    burn_in_options.settings.set_editor_property(
        'TopCenterText', "{MasterName} - {Date} - {EngineVersion}")
    burn_in_options.settings.set_editor_property(
        'TopRightText',
        "{TranslationX} {TranslationY} {TranslationZ}, {RotationX} {RotationY} {RotationZ}"
    )

    burn_in_options.settings.set_editor_property('BottomLeftText',
                                                 "{ShotName}")
    burn_in_options.settings.set_editor_property(
        'BottomCenterText', "{hh}:{mm}:{ss}:{ff} ({MasterFrame})")
    burn_in_options.settings.set_editor_property('BottomRightText',
                                                 "{ShotFrame}")

    # Load a Texture2D asset and assign it to the UTexture2D reference that Watermark is.
    # burn_in_settings.set_editor_property('Watermark', None)
    burn_in_options.settings.set_editor_property(
        'Watermark', unreal.load_asset("/Engine/EngineResources/AICON-Green"))
    burn_in_options.settings.set_editor_property(
        'WatermarkTint',
        unreal.LinearColor(1.0, 0.5, 0.5,
                           0.5))  # Create a FLinearColor to tint our Watermark

    # Assign our created instances to our original capture_settings object.
    capture_settings.burn_in_options = burn_in_options
    capture_settings.protocol_settings = protocol_settings

    # Finally invoke Sequencer's Render to Movie functionality. This will examine the specified settings object and either construct a new PIE instance to render in,
    # or create and launch a new process (optionally shutting down your editor).
    unreal.SequencerTools.render_movie(capture_settings)
Beispiel #8
0
    def render_sequence_to_movie(sequence_path, sequence_name):
        def on_render_movie_finished(success):
            print(
                "Movie has finished rendering. Python can now invoke another movie render if needed. Sucess: "
                + str(success))

        on_finished_callback = unreal.OnRenderMovieStopped()
        on_finished_callback.bind_callable(on_render_movie_finished)

        file_path = sequence_path + "/" + sequence_name

        capture_settings = unreal.AutomatedLevelSequenceCapture()

        # out put path
        capture_settings.settings.output_directory = unreal.DirectoryPath(
            "../../../Game/Saved/VideoCaptures/")

        capture_settings.settings.game_mode_override = None

        # out put name
        capture_settings.settings.output_format = sequence_name

        capture_settings.settings.overwrite_existing = False
        capture_settings.settings.use_relative_frame_numbers = False
        capture_settings.settings.handle_frames = 0
        capture_settings.settings.zero_pad_frame_numbers = 4

        capture_settings.settings.use_custom_frame_rate = True

        capture_settings.settings.custom_frame_rate = unreal.FrameRate(24, 1)
        capture_settings.settings.resolution.res_x = 1280
        capture_settings.settings.resolution.res_y = 720

        capture_settings.settings.enable_texture_streaming = False
        capture_settings.settings.cinematic_engine_scalability = True
        capture_settings.settings.cinematic_mode = True
        capture_settings.settings.allow_movement = False
        capture_settings.settings.allow_turning = False
        capture_settings.settings.show_player = False
        capture_settings.settings.show_hud = False
        capture_settings.use_separate_process = False
        capture_settings.close_editor_when_capture_starts = False
        capture_settings.additional_command_line_arguments = "-NOSCREENMESSAGES"
        capture_settings.inherited_command_line_arguments = ""

        capture_settings.use_custom_start_frame = False
        capture_settings.use_custom_end_frame = False
        capture_settings.custom_start_frame = unreal.FrameNumber(0)
        capture_settings.custom_end_frame = unreal.FrameNumber(0)
        capture_settings.warm_up_frame_count = 0.0
        capture_settings.delay_before_warm_up = 0
        capture_settings.delay_before_shot_warm_up = 0.0
        capture_settings.write_edit_decision_list = True

        # Change format
        capture_settings.set_image_capture_protocol_type(
            unreal.load_class(
                None, "/Script/MovieSceneCapture.ImageSequenceProtocol_JPG"))
        capture_settings.get_image_capture_protocol().compression_quality = 100

        capture_settings.level_sequence_asset = unreal.SoftObjectPath(
            file_path)
        unreal.SequencerTools.render_movie(capture_settings,
                                           on_finished_callback)
Beispiel #9
0
def render_sequence_to_movie(sequencer_asset_path):
    # 1) Create an instance of our UAutomatedLevelSequenceCapture and override all of the settings on it. This class is currently
    # set as a config class so settings will leak between the Unreal Sequencer Render-to-Movie UI and this object. To work around
    # this, we set every setting via the script so that no changes the user has made via the UI will affect the script version.
    # The users UI settings will be reset as an unfortunate side effect of this.
    capture_settings = unreal.AutomatedLevelSequenceCapture()

    # Set all POD settings on the UMovieSceneCapture
    capture_settings.settings.output_directory = unreal.DirectoryPath(
        "../../../QAGame/Saved/VideoCaptures/")

    # If you game mode is implemented in Blueprint, load_asset(...) is going to return you the C++ type ('Blueprint') and not what the BP says it inherits from.
    # Instead, because game_mode_override is a TSubclassOf<AGameModeBase> we can use unreal.load_class to get the UClass which is implicitly convertable.
    # ie: capture_settings.settings.game_mode_override = unreal.load_class(None, "/Game/AI/TestingSupport/AITestingGameMode.AITestingGameMode_C")
    capture_settings.settings.game_mode_override = None
    capture_settings.settings.output_format = "{world}"
    capture_settings.settings.overwrite_existing = True
    capture_settings.settings.use_relative_frame_numbers = False
    capture_settings.settings.handle_frames = 0
    capture_settings.settings.zero_pad_frame_numbers = 4
    # If you wish to override the output framerate you can use these two lines, otherwise the framerate will be derived from the sequence being rendered
    capture_settings.settings.use_custom_frame_rate = True
    capture_settings.settings.custom_frame_rate = unreal.FrameRate(24, 1)
    capture_settings.settings.resolution.res_x = 1280
    capture_settings.settings.resolution.res_y = 720
    capture_settings.settings.enable_texture_streaming = False
    capture_settings.settings.cinematic_engine_scalability = True
    capture_settings.settings.cinematic_mode = True
    capture_settings.settings.allow_movement = False  # Requires cinematic_mode = True
    capture_settings.settings.allow_turning = False  # Requires cinematic_mode = True
    capture_settings.settings.show_player = False  # Requires cinematic_mode = True
    capture_settings.settings.show_hud = False  # Requires cinematic_mode = True
    capture_settings.use_separate_process = False
    capture_settings.close_editor_when_capture_starts = False  # Requires use_separate_process = True
    capture_settings.additional_command_line_arguments = "-NOSCREENMESSAGES"  # Requires use_separate_process = True
    capture_settings.inherited_command_line_arguments = ""  # Requires use_separate_process = True

    # Set all the POD settings on UAutomatedLevelSequenceCapture
    capture_settings.use_custom_start_frame = False  # If False, the system will automatically calculate the start based on sequence content
    capture_settings.use_custom_end_frame = False  # If False, the system will automatically calculate the end based on sequence content
    capture_settings.custom_start_frame = unreal.FrameNumber(
        0)  # Requires use_custom_start_frame = True
    capture_settings.custom_end_frame = unreal.FrameNumber(
        0)  # Requires use_custom_end_frame = True
    capture_settings.warm_up_frame_count = 0.0
    capture_settings.delay_before_warm_up = 0
    capture_settings.delay_before_shot_warm_up = 0.0
    capture_settings.write_edit_decision_list = True

    # Tell the capture settings which level sequence to render with these settings. The asset does not need to be loaded,
    # as we're only capturing the path to it and when the PIE instance is created it will load the specified asset.
    # If you only had a reference to the level sequence, you could use "unreal.SoftObjectPath(mysequence.get_path_name())"
    capture_settings.level_sequence_asset = unreal.SoftObjectPath(
        sequencer_asset_path)

    # To configure the video output we need to tell the capture settings which capture protocol to use. The various supported
    # capture protocols can be found by setting the Unreal Content Browser to "Engine C++ Classes" and filtering for "Protocol"
    # ie: CompositionGraphCaptureProtocol, ImageSequenceProtocol_PNG, etc. Do note that some of the listed protocols are not intended
    # to be used directly.
    # Right click on a Protocol and use "Copy Reference" and then remove the extra formatting around it. ie:
    # Class'/Script/MovieSceneCapture.ImageSequenceProtocol_PNG' gets transformed into "/Script/MovieSceneCapture.ImageSequenceProtocol_PNG"
    capture_settings.set_image_capture_protocol_type(
        unreal.load_class(
            None, "/Script/MovieSceneCapture.ImageSequenceProtocol_PNG"))

    # After we have set the capture protocol to a soft class path we can start editing the settings for the instance of the protocol that is internallyc reated.
    capture_settings.get_image_capture_protocol().compression_quality = 100

    # The other complex settings is the burn-in. Create an instance of the LevelSequenceBurnInOptions which is used to
    # specify if we should use a burn in, and then which settings.
    burn_in_options = unreal.LevelSequenceBurnInOptions()
    burn_in_options.use_burn_in = True

    # You have to specify a path to a class to use for the burn in (if use_burn_in = True), and this class specifies a UClass to define the
    # settings object type. We've created a convinence function which takes the class path, loads the class at that path and assigns it to
    # the Settings object.
    burn_in_options.set_burn_in(
        unreal.SoftClassPath(
            "/Engine/Sequencer/DefaultBurnIn.DefaultBurnIn_C"))

    # The default burn in is implemented entirely in Blueprint which means that the method we've been using to set properties will not
    # work for it. The python bindings that turn bSomeVariableName into "some_variable_name" only work for C++ classes with
    # UPROPERTY(BlueprintReadWrite) marked fields. Python doesn't know about the existence of Blueprint classes and their fields, so we
    # have to use an alternative method.
    burn_in_options.settings.set_editor_property(
        'TopLeftText', "{FocalLength}mm,{Aperture},{FocusDistance}")
    burn_in_options.settings.set_editor_property(
        'TopCenterText', "{MasterName} - {Date} - {EngineVersion}")
    burn_in_options.settings.set_editor_property(
        'TopRightText',
        "{TranslationX} {TranslationY} {TranslationZ}, {RotationX} {RotationY} {RotationZ}"
    )

    burn_in_options.settings.set_editor_property('BottomLeftText',
                                                 "{ShotName}")
    burn_in_options.settings.set_editor_property(
        'BottomCenterText', "{hh}:{mm}:{ss}:{ff} ({MasterFrame})")
    burn_in_options.settings.set_editor_property('BottomRightText',
                                                 "{ShotFrame}")

    # Load a Texture2D asset and assign it to the UTexture2D reference that Watermark is.
    # burn_in_settings.set_editor_property('Watermark', None)
    # Note that this example creates a really obvious watermark (a big blurry green smiley face) just so that you know it's working!
    burn_in_options.settings.set_editor_property(
        'Watermark', unreal.load_asset("/Engine/EngineResources/AICON-Green"))
    burn_in_options.settings.set_editor_property(
        'WatermarkTint',
        unreal.LinearColor(1.0, 0.5, 0.5,
                           0.5))  # Create a FLinearColor to tint our Watermark

    # Assign our created instances to our original capture_settings object.
    capture_settings.burn_in_options = burn_in_options

    # Finally invoke Sequencer's Render to Movie functionality. This will examine the specified settings object and either construct a new PIE instance to render in,
    # or create and launch a new process (optionally shutting down your editor).
    unreal.SequencerTools.render_movie(capture_settings, on_finished_callback)