|
import json |
|
import os |
|
import subprocess |
|
import shutil |
|
|
|
def remove_all_subfolders(directory): |
|
for item in os.listdir(directory): |
|
item_path = os.path.join(directory, item) |
|
if os.path.isdir(item_path): |
|
shutil.rmtree(item_path) |
|
|
|
def combine_gifs_to_mp4(gif_files, output_file): |
|
|
|
input_str = ' '.join(['-i ' + gif for gif in gif_files]) |
|
filter_str = """ |
|
[0:v][1:v][2:v]hstack=inputs=3[top]; |
|
[3:v][4:v][5:v]hstack=inputs=3[middle]; |
|
[6:v][7:v][8:v]hstack=inputs=3[bottom]; |
|
[top][middle][bottom]vstack=inputs=3[v] |
|
""" |
|
ffmpeg_cmd = f'ffmpeg {input_str} -filter_complex "{filter_str}" -map "[v]" combined.gif' |
|
|
|
|
|
subprocess.run(ffmpeg_cmd, shell=True, check=True) |
|
|
|
|
|
ffmpeg_convert_cmd = 'ffmpeg -i combined.gif -c:v libx264 -pix_fmt yuv420p -crf 23 ' + output_file |
|
subprocess.run(ffmpeg_convert_cmd, shell=True, check=True) |
|
|
|
def move_and_rename(src_folder, dest_folder): |
|
count = 1 |
|
|
|
|
|
if not os.path.exists(dest_folder): |
|
os.makedirs(dest_folder) |
|
|
|
|
|
for dirpath, dirnames, filenames in os.walk(src_folder): |
|
dirnames.sort() |
|
for file in sorted(filenames): |
|
if file.endswith('.gif'): |
|
src_path = os.path.join(dirpath, file) |
|
dest_path = os.path.join(dest_folder, f'{count}.gif') |
|
shutil.copy(src_path, dest_path) |
|
print(f"Moved {file} to {dest_path}") |
|
count += 1 |
|
|
|
|
|
dir_path = "data/share/sd_models/" |
|
|
|
|
|
json_file_path = "config/prompts/prompt_travel_multi_controlnet.json" |
|
|
|
def update_json_path(filename): |
|
|
|
with open(json_file_path, 'r') as json_file: |
|
data = json.load(json_file) |
|
|
|
|
|
data['path'] = f"share/sd_models/{filename}" |
|
|
|
|
|
with open(json_file_path, 'w') as json_file: |
|
json.dump(data, json_file, indent=4) |
|
|
|
def run_animatediff_command(): |
|
cmd = ["animatediff", "generate", "-c", "config/prompts/prompt_travel_multi_controlnet.json", "-W", "256", "-H", "384", "-L", "48", "-C", "16"] |
|
|
|
|
|
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) |
|
|
|
|
|
while True: |
|
output = process.stdout.readline() |
|
if output == '' and process.poll() is not None: |
|
break |
|
if output: |
|
print(output.strip()) |
|
rc = process.poll() |
|
|
|
|
|
errors = process.stderr.readlines() |
|
for error in errors: |
|
print(error.strip()) |
|
|
|
def main(): |
|
|
|
file_names = sorted([f for f in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, f))]) |
|
|
|
for filename in file_names: |
|
|
|
update_json_path(filename) |
|
|
|
|
|
run_animatediff_command() |
|
|
|
prompt_templates = [ |
|
|
|
{'prompt_fixed_ratio': 1.0, |
|
'head_prompt': 'little girl, pink hair, tall, confident, grace, poise, wide open eyes, surprise, curiosity, joyful smile, happiness', |
|
'prompt_map': {'0': '', |
|
'8': '((astonishment, wide eyes))', |
|
'16': '((joyful smile, happiness))', |
|
'24': '((excitement, sparkling eyes))', |
|
'32': '((delight, blushing cheeks))', |
|
'40': '((laughter, joyful atmosphere))'}, |
|
'tail_prompt': ''}, |
|
|
|
{'prompt_fixed_ratio': 1.0, |
|
'head_prompt': 'little girl, pink hair, tall, confident posture, wide open eyes, wonder, surprise, animated face, range of emotions', |
|
'prompt_map': {'0': '', |
|
'8': '((astonishment, wide eyes))', |
|
'16': '((tears welling up, emotional))', |
|
'24': '((flowing tears, sadness))', |
|
'32': '((contorted face, sadness))', |
|
'40': '((streaming tears, sadness))'}, |
|
'tail_prompt': ''}, |
|
|
|
{'prompt_fixed_ratio': 1.0, |
|
'head_prompt': 'little girl, pink hair, confidence, determination, wide eyes, curiosity, rosy cheeks, button nose, cute pink dress, frills, bows', |
|
'prompt_map': {'0': '', |
|
'8': '((confusion, squinting eyes))', |
|
'16': '((fear, widening eyes))', |
|
'24': '((terror, crying))', |
|
'32': '((tears streaming down face))', |
|
'40': '((intense sobs))'}, |
|
'tail_prompt': ''}, |
|
|
|
{'prompt_fixed_ratio': 1.0, |
|
'head_prompt': 'little girl, pink hair, tall, confident posture, closed eyes, deep thought, intense anger, powerful roar, red face', |
|
'prompt_map': {'0': '', |
|
'8': '((contemplation))', |
|
'16': '((furrowed brows))', |
|
'24': '((anger))', |
|
'32': '((wide open mouth))', |
|
'40': '((powerful roar))'}, |
|
'tail_prompt': ''}, |
|
] |
|
|
|
if __name__ == "__main__": |
|
|
|
for idx, prompt_template in enumerate(prompt_templates): |
|
|
|
|
|
with open(json_file_path, 'r') as json_file: |
|
data = json.load(json_file) |
|
|
|
|
|
data['head_prompt'] = prompt_template['head_prompt'] |
|
data['prompt_map'] = prompt_template['prompt_map'] |
|
data['tail_prompt'] = prompt_template['tail_prompt'] |
|
|
|
|
|
with open(json_file_path, 'w') as json_file: |
|
json.dump(data, json_file, indent=4) |
|
|
|
main() |
|
|
|
subfolder_path = "output" |
|
current_folder = f"{os.getcwd()}/output_{idx+1}" |
|
|
|
move_and_rename(subfolder_path, current_folder) |
|
|
|
path = f"{current_folder}" |
|
|
|
|
|
gif_files = [f"{path}/{i}.gif" for i in range(1, 10)] |
|
output_file = f"{path}/combined.mp4" |
|
|
|
os.remove(f"{os.getcwd()}/combined.gif") |
|
|
|
combine_gifs_to_mp4(gif_files, output_file) |
|
|
|
remove_all_subfolders(f"{os.getcwd()}/{subfolder_path}") |
|
|