diff --git a/readme.md b/readme.md index 714b4af6..67752ffb 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# Welcome to Dough v. 0.7 (beta) +# Welcome to Dough v. 0.8.3 (beta) **⬇️ Scroll down for Setup Instructions - Currently available on Linux & Windows, hosted version coming soon.** @@ -100,6 +100,13 @@ This commands sets up the app. Run this only the first time, after that you can curl -sSL https://raw.githubusercontent.com/banodoco/Dough/green-head/scripts/linux_setup.sh | bash ``` +### Enter the folder + +In terminal, run: +```bash +cd Dough +``` + ### Run the app you can run the app using @@ -110,10 +117,20 @@ source ./dough-env/bin/activate && ./scripts/entrypoint.sh ## Instructions for Windows: +### Open Powershell in Administrator mode + +Open the Start menu, type Windows PowerShell, right-click on Windows PowerShell, and then select Run as administrator. + ### Install the app - Install MS C++ Redistributable (if not already present) - https://aka.ms/vs/16/release/vc_redist.x64.exe +### Enter the folder +In Powershell, run: +```bash +cd Dough +``` + Run the setup script ```bash diff --git a/scripts/app_version.txt b/scripts/app_version.txt index a3df0a69..ee94dd83 100644 --- a/scripts/app_version.txt +++ b/scripts/app_version.txt @@ -1 +1 @@ -0.8.0 +0.8.3 diff --git a/ui_components/components/animate_shot_page.py b/ui_components/components/animate_shot_page.py index 1274067c..d24471e5 100644 --- a/ui_components/components/animate_shot_page.py +++ b/ui_components/components/animate_shot_page.py @@ -72,12 +72,14 @@ def video_rendering_page(shot_uuid, selected_variant): with headline1: st.markdown("### 🎥 Generate animations") st.write("##### _\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_") + ''' with headline3: with st.expander("Type of animation", expanded=False): type_of_animation = st_memory.radio("What type of animation would you like to generate?", \ options=AnimateShotMethod.value_list(), horizontal=True, \ help="**Batch Creative Interpolaton** lets you input multple images and control the motion and style of each frame - resulting in a fluid, surreal and highly-controllable motion. \n\n **2-Image Realistic Interpolation** is a simpler way to generate animations - it generates a video by interpolating between two images, and is best for realistic motion.",key=f"type_of_animation_{shot.uuid}") - + ''' + type_of_animation = AnimateShotMethod.BATCH_CREATIVE_INTERPOLATION.value if type_of_animation == AnimateShotMethod.BATCH_CREATIVE_INTERPOLATION.value: sm_video_rendering_page(shot_uuid, img_list) else: diff --git a/ui_components/components/app_settings_page.py b/ui_components/components/app_settings_page.py index 12a14317..dea2543d 100644 --- a/ui_components/components/app_settings_page.py +++ b/ui_components/components/app_settings_page.py @@ -1,6 +1,5 @@ import time import streamlit as st -import webbrowser from shared.constants import SERVER, ServerType from utils.common_utils import get_current_user from ui_components.components.query_logger_page import query_logger_page @@ -41,10 +40,10 @@ def app_settings_page(): # TODO: rn storing 'update_state' in replicate_username inside app_setting to bypass db changes, will change this later app_setting = data_repo.get_app_setting_from_uuid() - update_enabled = True if app_setting.replicate_username and app_setting.replicate_username == 'update' else False + update_enabled = True if app_setting.replicate_username and app_setting.replicate_username in ['update', 'bn'] else False with st.expander("App Update", expanded=True): - st.info("We recommend auto-updating the app to get the latest features and bug fixes. However, if you'd like to update manually, you can turn this off and use './scripts/entrypoint.sh --update' when you're starting the app to update.") + # st.info("We recommend auto-updating the app to get the latest features and bug fixes. However, if you'd like to update manually, you can turn this off and use './scripts/entrypoint.sh --update' when you're starting the app to update.") st.toggle("Auto-update app upon restart", key='enable_app_update', value=update_enabled, on_change=update_toggle, help="This will update the app automatically when a new version is available.") with st.expander("Inference Logs", expanded=False): diff --git a/ui_components/components/video_rendering_page.py b/ui_components/components/video_rendering_page.py index a2413bf5..378c25ee 100644 --- a/ui_components/components/video_rendering_page.py +++ b/ui_components/components/video_rendering_page.py @@ -133,8 +133,6 @@ def sm_video_rendering_page(shot_uuid, img_list: List[InternalFileObject]): index=st.session_state[f"type_of_generation_index_{shot.uuid}"], help="Normal generations take around twice as long but provide more detailed results." ) - if type_of_generation == "Normal": - type_of_generation = "Detailed" animate_col_1, _, _ = st.columns([3, 1, 1]) with animate_col_1: variant_count = 1 @@ -199,7 +197,8 @@ def sm_video_rendering_page(shot_uuid, img_list: List[InternalFileObject]): vid_quality, settings, variant_count, - st.session_state[f'{shot_uuid}_backlog_enabled'] + st.session_state[f'{shot_uuid}_backlog_enabled'], + img_list ) backlog_update = {f'{shot_uuid}_backlog_enabled': False} @@ -299,7 +298,8 @@ def two_img_realistic_interpolation_page(shot_uuid, img_list: List[InternalFileO vid_quality, settings, variant_count, - st.session_state[f'{shot_uuid}_backlog_enabled'] + st.session_state[f'{shot_uuid}_backlog_enabled'], + img_list ) backlog_update = {f'{shot_uuid}_backlog_enabled': False} diff --git a/ui_components/components/welcome_page.py b/ui_components/components/welcome_page.py index 4dfd70db..22aa6349 100644 --- a/ui_components/components/welcome_page.py +++ b/ui_components/components/welcome_page.py @@ -67,12 +67,11 @@ def welcome_page(): st.markdown(''' 1. The first shot you animate will probably look crap. Using Dough is a skill - you'll need to experiment, iterate and learn - but you'll learn quickly. - 2. Dough won't work well for all styles - for example, realism tends to bring out the flaws in SD1.5-based models. It also won't work very well for realistic motion. - 3. The app will be slow the first time you use each function. It needs to download models and install stuff. Please be patient - but check your Terminal for error messages if it's taking more than 15 minutes. - 4. This is a beta - **please** share any feedback you have - especially negative stuff. We're relentlessly focused on making this better and we can't do that without your help. We won't be offended by anything you say! - 5. Our ultimate goal is to create a tool-builder that makes it easy for anyone to build artistic tools. While you're using this, think of what tool you would create if it were ridiculously easy to do so. - 6. The 'r' key on your keyboard is your friend - this will refresh the app, updating the generated frames and inference log! - 7. To make something great, you will need to use a video editor like DaVinci Resolve, Adobe Premiere or even iMovie. Dough is just the first step in the process. + 2. Dough won't work well for all styles or all types of motion - like all artistic mediums, it has its strengths and weaknesses. You'll need to figure out how to make it work for you. + 3. The app will be slow the first time you use each function. It needs to download models and install stuff. Please be patient (but check your Terminal for error messages if it's taking more than 15 minutes). + 4. This is a beta - **please** share any feedback you have - especially negative stuff. We're focused on making this better and we can't do that without your help. We won't be offended by anything you say! + 5. You need to press 'r' for new generations and updates to appear - they won't appear automatically. + 6. To make something great, you will need to use a video editor like DaVinci Resolve, Premiere Pro or even iMovie. Dough is the first step in the process but editing is what makes it magical. ''') diff --git a/ui_components/methods/animation_style_methods.py b/ui_components/methods/animation_style_methods.py index c627baae..e67e48a4 100644 --- a/ui_components/methods/animation_style_methods.py +++ b/ui_components/methods/animation_style_methods.py @@ -67,7 +67,7 @@ def load_shot_settings(shot_uuid, log_uuid=None): elif key == f"type_of_generation_index_{shot.uuid}": if not isinstance(st.session_state[key], int): st.session_state[key] = 0 - st.session_state["creative_interpolation_type"] = ["Detailed", "Fast"][st.session_state[key]] + st.session_state["creative_interpolation_type"] = ["Normal", "Fast"][st.session_state[key]] st.rerun() elif data_type == ShotMetaData.DYNAMICRAFTER_DATA.value: diff --git a/ui_components/methods/video_methods.py b/ui_components/methods/video_methods.py index 1215a4c7..9e4bd433 100644 --- a/ui_components/methods/video_methods.py +++ b/ui_components/methods/video_methods.py @@ -23,7 +23,7 @@ from utils.ml_processor.ml_interface import get_ml_client -def create_single_interpolated_clip(shot_uuid, quality, settings={}, variant_count=1, backlog=False): +def create_single_interpolated_clip(shot_uuid, quality, settings={}, variant_count=1, backlog=False, img_list=[]): ''' - this includes all the animation styles [direct morphing, interpolation, image to video] - this stores the newly created video in the interpolated_clip_list and promotes them to @@ -35,7 +35,6 @@ def create_single_interpolated_clip(shot_uuid, quality, settings={}, variant_cou data_repo = DataRepo() shot = data_repo.get_shot_from_uuid(shot_uuid) - timing_list = data_repo.get_timing_list_from_shot(shot_uuid) if quality == 'full': interpolation_steps = VideoInterpolator.calculate_dynamic_interpolations_steps(shot.duration) @@ -43,7 +42,10 @@ def create_single_interpolated_clip(shot_uuid, quality, settings={}, variant_cou interpolation_steps = 3 settings.update(interpolation_steps=interpolation_steps) - settings.update(file_uuid_list=[t.primary_image.uuid for t in timing_list]) + if not (img_list and len(img_list)): + timing_list = data_repo.get_timing_list_from_shot(shot_uuid) + img_list = [t.primary_image for t in timing_list] + settings.update(file_uuid_list=[t.uuid for t in img_list]) # res is an array of tuples (video_bytes, log) res = VideoInterpolator.create_interpolated_clip( diff --git a/ui_components/widgets/sidebar_logger.py b/ui_components/widgets/sidebar_logger.py index b1292e8a..9cd15033 100644 --- a/ui_components/widgets/sidebar_logger.py +++ b/ui_components/widgets/sidebar_logger.py @@ -54,11 +54,11 @@ def sidebar_logger(shot_uuid): [l.uuid for l in backlog_log_list], status=InferenceStatus.QUEUED.value ) if status: - st.success("success") + st.success("Running backlog") time.sleep(0.7) st.rerun() else: - st.info("No backlogs") + st.error("No backlogs") time.sleep(0.7) st.rerun() y1, y2 = st.columns([1, 1]) @@ -138,9 +138,10 @@ def sidebar_logger(shot_uuid): if log.uuid in log_file_dict: output_url = log_file_dict[log.uuid].location - c0, c1, c2, c3, c4 = st.columns( - [0.5, 0.5, 0.7 if output_url else 0.01, 1, 0.01 if output_url else 1] - ) + if output_url: + c0, c1, c2, c3, c4 = st.columns([0.5, 0.5, 0.7, 1, 0.01]) + else: + c0, c1, c2, c3 = st.columns([0.5, 0.5, 0.01, 1]) with c0: input_params = json.loads(log.input_params) prompt = input_params.get("prompt", "No prompt found") diff --git a/ui_components/widgets/variant_comparison_grid.py b/ui_components/widgets/variant_comparison_grid.py index db6dff66..36c2fdfc 100644 --- a/ui_components/widgets/variant_comparison_grid.py +++ b/ui_components/widgets/variant_comparison_grid.py @@ -63,10 +63,10 @@ def variant_comparison_grid(ele_uuid, stage=CreativeProcessType.MOTION.value): timing_list = data_repo.get_timing_list_from_shot(shot.uuid) if not (f"{shot_uuid}_selected_variant_log_uuid" in st.session_state and st.session_state[f"{shot_uuid}_selected_variant_log_uuid"]): - if variants and len(variants): - st.session_state[f"{shot_uuid}_selected_variant_log_uuid"] = variants[-1].inference_log.uuid - else: - st.session_state[f"{shot_uuid}_selected_variant_log_uuid"] = None + # if variants and len(variants): + # st.session_state[f"{shot_uuid}_selected_variant_log_uuid"] = variants[-1].inference_log.uuid + # else: + st.session_state[f"{shot_uuid}_selected_variant_log_uuid"] = None else: timing_uuid = ele_uuid timing = data_repo.get_timing_from_uuid(timing_uuid) @@ -81,6 +81,10 @@ def variant_comparison_grid(ele_uuid, stage=CreativeProcessType.MOTION.value): with col1: st.markdown(f"### 🎞️ '{shot.name}' options") st.write("##### _\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_") + if st.button("Refresh Shot"): + st.session_state[f"{shot_uuid}_selected_variant_log_uuid"] = None + st.rerun() + else: items_to_show = 5 num_columns = 3 @@ -191,8 +195,8 @@ def variant_comparison_grid(ele_uuid, stage=CreativeProcessType.MOTION.value): def is_upscaled_video(variant: InternalFileObject): log = variant.inference_log - if log.output_details and json.loads(log.output_details).get("model_name", "") == ComfyWorkflow.UPSCALER.value: - return True + if log and log.output_details and json.loads(log.output_details).get("model_name", "") == ComfyWorkflow.UPSCALER.value: + return True return False diff --git a/utils/app_update_utils.py b/utils/app_update_utils.py index 57daaf5a..932d45ba 100644 --- a/utils/app_update_utils.py +++ b/utils/app_update_utils.py @@ -20,7 +20,7 @@ def check_for_updates(): global update_event data_repo = DataRepo() app_setting = data_repo.get_app_setting_from_uuid() - update_enabled = True if app_setting.replicate_username and app_setting.replicate_username == 'update' else False + update_enabled = True if app_setting.replicate_username and app_setting.replicate_username in ['bn', 'update'] else False current_version = get_local_version() remote_version = get_remote_version() if current_version and remote_version and compare_versions(remote_version, current_version) == 1 and update_enabled\