From f7ee691b4dcdb6f5ce383ec4cc1e342184b10a55 Mon Sep 17 00:00:00 2001 From: "Roncero Blanco, Edgar" Date: Mon, 26 May 2025 20:17:05 +0200 Subject: [PATCH] Better split algorithm --- Program/app.py | 52 +++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/Program/app.py b/Program/app.py index 1a822ec..dc8f103 100644 --- a/Program/app.py +++ b/Program/app.py @@ -3,10 +3,10 @@ import shutil from pathlib import Path from mutagen.id3 import ID3, TBPM, ID3NoHeaderError from datetime import datetime -from collections import defaultdict import configparser import sys import librosa +import warnings GROUP_SIZE = 5 @@ -20,6 +20,7 @@ def load_config(): print("config.ini created from def_config.ini with default settings.") else: print("Error: def_config.ini not found! Please create it and rerun.") + input("Press Enter to exit...") sys.exit(1) default_config = configparser.ConfigParser() @@ -36,7 +37,9 @@ def load_config(): def analyze_bpm_librosa(file_path): try: - y, sr = librosa.load(file_path, mono=True) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + y, sr = librosa.load(file_path, mono=True) tempo, _ = librosa.beat.beat_track(y=y, sr=sr) return int(round(float(tempo))) except Exception as e: @@ -49,7 +52,6 @@ def write_bpm_tag(file_path, bpm): tags = ID3(file_path) except ID3NoHeaderError: tags = ID3() - tags.delall("TBPM") tags.add(TBPM(encoding=3, text=str(bpm))) tags.save(file_path) @@ -67,14 +69,11 @@ def get_bpm(file_path): pass return None -def split_evenly(lst, n): - k, m = divmod(len(lst), n) - return [lst[i*k + min(i, m):(i+1)*k + min(i+1, m)] for i in range(n)] - def main(): config = load_config() - CD_SIZE = config.getint("Settings", "SplitFolderMB") * 1024 * 1024 + SAFETY_MARGIN = 1024 * 1024 * 2 # 2 MB buffer + CD_SIZE = config.getint("Settings", "SplitFolderMB") * 1024 * 1024 - SAFETY_MARGIN bWriteNonPresentBPM = config.getboolean("Settings", "bWriteNonPresentBPM") bCheckAllTracksBPM = config.getboolean("Settings", "bCheckAllTracksBPM") @@ -85,6 +84,7 @@ def main(): if not source_media_path.exists() or not source_media_path.is_dir(): print(f"Error: {source_media_path} is not a valid directory.") + input("Press Enter to exit...") sys.exit(1) all_tracks = [] @@ -103,14 +103,12 @@ def main(): write_bpm_tag(file, bpm) size = file.stat().st_size - if bpm is None: - bpm_range = "[Unknown BPM]" - else: - bpm_range = f"{(bpm // GROUP_SIZE) * GROUP_SIZE}-to-{((bpm // GROUP_SIZE) * GROUP_SIZE) + GROUP_SIZE - 1}" + bpm_range = f"{(bpm // GROUP_SIZE) * GROUP_SIZE}-to-{((bpm // GROUP_SIZE) * GROUP_SIZE) + GROUP_SIZE - 1}" if bpm else "[Unknown BPM]" all_tracks.append({"file": file, "size": size, "bpm_range": bpm_range}) if not all_tracks: print("No MP3 files found.") + input("Press Enter to exit...") sys.exit(0) parent = source_media_path.parent @@ -118,27 +116,24 @@ def main(): dest_media_path = parent / f"[CDs-{run_date}]{folder_name}" dest_media_path.mkdir(parents=True, exist_ok=True) - total_size = sum(t["size"] for t in all_tracks) - num_cds = max(1, (total_size + CD_SIZE - 1) // CD_SIZE) + all_tracks.sort(key=lambda x: -x["size"]) # Sort by size descending for better packing - print(f"Total size: {total_size / 1024**2:.2f} MB, splitting into {num_cds} CDs") + cd_contents = [] + current_cd = [] + current_size = 0 - bpm_groups = defaultdict(list) for track in all_tracks: - bpm_groups[track["bpm_range"]].append(track) + if current_size + track["size"] > CD_SIZE: + cd_contents.append(current_cd) + current_cd = [] + current_size = 0 + current_cd.append(track) + current_size += track["size"] - for bpm_range in bpm_groups: - bpm_groups[bpm_range].sort(key=lambda x: x["file"].name) + if current_cd: + cd_contents.append(current_cd) - bpm_chunks = {} - for bpm_range, tracks in bpm_groups.items(): - bpm_chunks[bpm_range] = split_evenly(tracks, num_cds) - - cd_contents = [[] for _ in range(num_cds)] - - for bpm_range in bpm_chunks: - for i, chunk in enumerate(bpm_chunks[bpm_range]): - cd_contents[i].extend(chunk) + print(f"Total size: {sum(t['size'] for t in all_tracks) / 1024**2:.2f} MB, splitting into {len(cd_contents)} CDs") for i, tracks in enumerate(cd_contents, start=1): cd_folder = dest_media_path / f"CD-{i:02}" @@ -152,6 +147,7 @@ def main(): print(f"[WRITE] CD-{i:02}: {len(tracks)} tracks, approx {size_accum / 1024**2:.2f} MB") print("\n✓ Done!") + input("Press Enter to exit...") if __name__ == "__main__": main()