Skip to content

Instantly share code, notes, and snippets.

@dmarx
Created June 15, 2023 01:00
Show Gist options
  • Select an option

  • Save dmarx/4d682332a584e6a22fbad2a03fc86e3c to your computer and use it in GitHub Desktop.

Select an option

Save dmarx/4d682332a584e6a22fbad2a03fc86e3c to your computer and use it in GitHub Desktop.

Revisions

  1. dmarx created this gist Jun 15, 2023.
    86 changes: 86 additions & 0 deletions storybaord2deforum.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    #!pip install omegaconf keyframed

    from omegaconf import OmegaConf
    from collections import defaultdict

    from keyframed import Curve
    from keyframed.dsl import curve_from_cn_string
    from keyframed.utils import simplify

    def update_storyboard_inferred_values(storyboard):
    """
    populates scene_id and starting_frame index (i.e. cumulative frames)
    """
    scenes = storyboard.prompt_starts
    prompt_lag = storyboard.params.get('prompt_lag', True)
    cf = 0
    for idx, rec in enumerate(scenes):
    rec['scene_id'] = idx
    rec['starting_frame'] = cf
    cf += rec['frames']

    # resolve prompt
    if not rec.get('_prompt'):
    theme = rec.get('_theme')
    prompt = rec.get('prompt')
    if not prompt:
    prompt = f"{rec['text']}, {theme}"

    if prompt_lag and (idx > 0):
    rec_prev = scenes[idx -1]
    prev_text = rec_prev.get('text','')
    if not prev_text:
    prev_text = rec_prev.get('prompt','').split(',')[0]
    this_text = rec.get('text','')
    if this_text:
    prompt = f"{prev_text} {this_text}, {theme}"
    else:
    prompt = rec_prev['_prompt']
    rec['_prompt'] = prompt
    return storyboard

    def adjust_curve(curve_str, start_offset):
    curve0 = curve_from_cn_string(curve_str)
    return Curve({ (k+start_offset): curve0[k] for k in curve0.keyframes})

    def is_curved_param(param):
    if not isinstance(param, str):
    return False
    if ':(' in param:
    return True
    return False


    def storyboard_to_deforum(storyboard):
    storyboard = update_storyboard_inferred_values(storyboard)

    # collect arguments and handle curved parameters
    d_ = {}
    d_curved = defaultdict(list)
    d_prompts = {}
    for idx, rec in enumerate(storyboard.prompt_starts):
    d_prompts[str(rec['starting_frame')]] = rec['_prompt']
    for param_name, param_value in rec.animation_args.items():
    if is_curved_param(param_value):
    curve = adjust_curve(param_value, rec['starting_frame'] )#, rec['frames'])
    curve_str = ','.join([f"{k}:({curve[k]})" for k in curve.keyframes if k>= rec['starting_frame']])
    #print(curve_str)
    d_curved[param_name].append(curve_str)
    else:
    if param_name not in d_:
    d_[param_name] = param_value
    if d_.get(param_name) != param_value:
    raise Exception(f"conflicting parameter values for {param_name} at scene {idx}")

    # cleanup curved parameters and combine with uncovered
    for param, v in d_curved.items():
    if param in d_:
    raise Exception(f"conflicting parameterizations for parameter {param}, appears in both curved and uncurved")
    curve = curve_from_cn_string(','.join(v))
    curve = simplify(curve)
    d_[param] = ','.join([f"{k}:({curve[k]})" for k in curve.keyframes] )

    d_['cond_prompts'] = d_prompts
    return d_

    storyboard_to_deforum(storyboard)