diff --git a/DanceDashLaunchHelper/DanceDashLaunchHelper.csproj b/DanceDashLaunchHelper/DanceDashLaunchHelper.csproj index 3f5ca3c0..3209a1ed 100644 --- a/DanceDashLaunchHelper/DanceDashLaunchHelper.csproj +++ b/DanceDashLaunchHelper/DanceDashLaunchHelper.csproj @@ -14,11 +14,11 @@ - + - + ..\Dance Dash_Data\Managed\DDVR.dll diff --git a/DanceDashLaunchHelper/Folder.DotSettings.user b/DanceDashLaunchHelper/Folder.DotSettings.user index ac94d140..943a3a20 100644 --- a/DanceDashLaunchHelper/Folder.DotSettings.user +++ b/DanceDashLaunchHelper/Folder.DotSettings.user @@ -1,4 +1,4 @@  True True - <AssemblyExplorer /> \ No newline at end of file + <AssemblyExplorer /> diff --git a/DanceDashLaunchHelper/NuGet.Config b/DanceDashLaunchHelper/NuGet.Config index 1864ded5..fffd9183 100644 --- a/DanceDashLaunchHelper/NuGet.Config +++ b/DanceDashLaunchHelper/NuGet.Config @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/DanceDashLaunchHelper/Plugin.cs b/DanceDashLaunchHelper/Plugin.cs index cdbdbe93..04895adb 100644 --- a/DanceDashLaunchHelper/Plugin.cs +++ b/DanceDashLaunchHelper/Plugin.cs @@ -22,7 +22,7 @@ namespace DanceDashLaunchHelper } } - + // when we first start the game, we set the ready button to be interactable & click it programmatically [HarmonyPatch(typeof(ControllerSwitchUI), "Start")] class ControllerSwitchUI_Start_Patch @@ -49,7 +49,7 @@ namespace DanceDashLaunchHelper Traverse.Create(__instance).Method("OnToggleHpChange", true).GetValue(); } } - + // this patch is bad, it hijacks init and toggles the albums and invokes them as true, happens to // toggle on the last album (custom songs) purely based on the order of execution, but again, this sucks [HarmonyPatch(typeof(VolListItem), "Init")] @@ -63,7 +63,7 @@ namespace DanceDashLaunchHelper __instance.Invoke(true); } } - + // hijacks the ost selection happening as a side effect of VolListItem_Init_Patch, and clicks the play button [HarmonyPatch(typeof(PanelSelect), "OnSelectOst")] class PanelSelect_OnSelectOst_Patch @@ -135,5 +135,5 @@ namespace DanceDashLaunchHelper return false; } } - -} \ No newline at end of file + +} diff --git a/DanceDashLaunchHelper/README.md b/DanceDashLaunchHelper/README.md index 0648b366..8e70a8f3 100644 --- a/DanceDashLaunchHelper/README.md +++ b/DanceDashLaunchHelper/README.md @@ -1,4 +1,4 @@ # DanceDashLaunchHelper - Read comments in [Plugin.cs](Plugin.cs) -- First time writing one of these so todo on the README \ No newline at end of file +- First time writing one of these so todo on the README diff --git a/README.md b/README.md index 0b743ccd..2fd13f8c 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ python -m pip install -r requirements.txt pre-commit install ``` ---- +--- Usage: @@ -45,4 +45,4 @@ yt-dlp -f bv[ext=webm] https://youtu.be/o7I0scmptmo -o "drs_video.webm" # grab song-id from "resources\data.json" or https://arcade-songs.zetaraku.dev/drs/ .venv/Scripts/python drs2dd.py "drs_video.webm" --song-id "BOOMBAYAH-JP Ver.-" -``` \ No newline at end of file +``` diff --git a/drs2dd.py b/drs2dd.py index 23b710d6..5064bd3f 100644 --- a/drs2dd.py +++ b/drs2dd.py @@ -6,14 +6,13 @@ import os from dataclasses import asdict import cv2 +from alive_progress import alive_bar from loguru import logger -from tqdm import tqdm from model.dancedash import create_note_sphere from model.dancedash import DDBeatMap from model.dancedash import LEFT_NOTE from model.dancedash import RIGHT_NOTE -from util import ORDER_COUNT_PER_BEAT from util import crop_frame from util import find_l from util import find_r @@ -21,6 +20,7 @@ from util import find_stage from util import get_song_metadata_remote from util import map_position_to_dd_x from util import NOTE_SEARCH_AREA +from util import ORDER_COUNT_PER_BEAT from util import SIGN_SEARCH_AREA from util import WORKING_RESOLUTION @@ -36,75 +36,80 @@ def extract_spheres_from_drs_video(video_path: str, bpm: int): # noqa duration_seconds = total_frames / video_fps bps = bpm / 60 - pbar = tqdm(total=total_frames, desc='Finding stage') - logger.info(f'Starting to process video: {video_path}') - logger.info(f'Total frames: {total_frames}') + with alive_bar( + total=total_frames, + title='Finding stage', + bar='notes', + spinner='notes', + ) as bar: + logger.info(f'Starting to process video: {video_path}') + logger.info(f'Total frames: {total_frames}') - stage_found = False - while not stage_found: - pbar.update(1) - ret, frame = cap.read() - if not ret: - raise ValueError('Unable to find stage.') + stage_found = False + while not stage_found: + bar() + ret, frame = cap.read() + if not ret: + raise ValueError('Unable to find stage.') - frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) - if int(frame_number % 5) != 0: - continue + frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) + if int(frame_number % 5) != 0: + continue - frame = cv2.resize(frame, WORKING_RESOLUTION) - search_area = crop_frame(frame, *SIGN_SEARCH_AREA) - stage_found = find_stage(search_area) + frame = cv2.resize(frame, WORKING_RESOLUTION) + search_area = crop_frame(frame, *SIGN_SEARCH_AREA) + stage_found = find_stage(search_area) - pbar.set_description('Finding notes') + bar.title = 'Finding notes' - frames_since_l = 0 - frames_since_r = 0 + frames_since_l = 0 + frames_since_r = 0 - spheres = [] - while True: - pbar.update(1) + spheres = [] + while True: + bar() - ret, frame = cap.read() - if not ret: - break + ret, frame = cap.read() + if not ret: + break - frame = cv2.resize(frame, WORKING_RESOLUTION) - # frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) - current_position_seconds = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0 + frame = cv2.resize(frame, WORKING_RESOLUTION) + current_position_seconds = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0 - # float between 0 and 1 representing the time in the song - progress_percentage = current_position_seconds / duration_seconds + # float between 0 and 1 representing the time in the song + progress_percentage = current_position_seconds / duration_seconds - frames_since_l -= 1 - frames_since_r -= 1 + frames_since_l -= 1 + frames_since_r -= 1 - note_order = int(bps * current_position_seconds * ORDER_COUNT_PER_BEAT) - search_area = crop_frame(frame, *NOTE_SEARCH_AREA) - if frames_since_l < 1: - if left := find_l(search_area): - frames_since_l = 5 - note = create_note_sphere( # noqa - progress_percentage, - map_position_to_dd_x(left[0]), - note_order, - LEFT_NOTE, - ) - spheres.append(note) + note_order = int( + bps * current_position_seconds * + ORDER_COUNT_PER_BEAT, + ) + search_area = crop_frame(frame, *NOTE_SEARCH_AREA) + if frames_since_l < 1: + if left := find_l(search_area): + frames_since_l = 5 + note = create_note_sphere( # noqa + progress_percentage, + map_position_to_dd_x(left[0]), + note_order, + LEFT_NOTE, + ) + spheres.append(note) - if frames_since_r < 1: - if right := find_r(search_area): - frames_since_r = 5 - note = create_note_sphere( # noqa - progress_percentage, - map_position_to_dd_x(right[0]), - note_order, - RIGHT_NOTE, - ) - spheres.append(note) + if frames_since_r < 1: + if right := find_r(search_area): + frames_since_r = 5 + note = create_note_sphere( # noqa + progress_percentage, + map_position_to_dd_x(right[0]), + note_order, + RIGHT_NOTE, + ) + spheres.append(note) - pbar.close() cap.release() - return spheres diff --git a/model/dancedash.py b/model/dancedash.py index 2e637cc6..de06b4de 100644 --- a/model/dancedash.py +++ b/model/dancedash.py @@ -117,7 +117,8 @@ class DDBeatMap: ), beatSubs=beat_subs, BPM=bpm, - songStartOffset=-0.4, # -0.4 is arbitrary, figure out a better value. (because we detect notes early) + # -0.4 is arbitrary, figure out a better value. (because we detect notes early) + songStartOffset=-0.4, NPS='0.0', developerMode=False, noteSpeed=1.0, diff --git a/requirements.txt b/requirements.txt index 66052a27..43e0db12 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,5 +6,5 @@ opencv-python~=4.8.0.74 numpy~=1.25.2 Pillow~=10.0.0 loguru -tqdm +alive-progress requests