Evenly distribute tracks per BPM range across CDs with BPM subfolders, splitting total size into ~700MB chunks

This commit is contained in:
2025-05-25 19:12:18 +02:00
parent 8957bde412
commit 32cc07962b

View File

@@ -2,12 +2,10 @@ import os
import shutil
from pathlib import Path
from mutagen.id3 import ID3
from mutagen.mp3 import MP3
CD_SIZE = 700 * 1024 * 1024 # 700 MB in bytes
GROUP_SIZE = 5 # BPM bin size
CD_SIZE = 700 * 1024 * 1024 # 700 MB
GROUP_SIZE = 5
# Directories
dir_a = Path(r"C:\Users\Edgar\Desktop\Peak Time BOF (ed1337x)\Already where in MP3")
dir_b = Path(r"C:\Users\Edgar\Desktop\Peak Time BOF (ed1337x)\CD")
dir_b.mkdir(parents=True, exist_ok=True)
@@ -22,7 +20,7 @@ def get_bpm(file_path):
print(f"Skipping {file_path.name} (no BPM): {e}")
return None
# Collect tracks
# Collect all tracks
all_tracks = []
for file in dir_a.glob("*.mp3"):
bpm = get_bpm(file)
@@ -32,35 +30,49 @@ for file in dir_a.glob("*.mp3"):
bpm_range = f"{(bpm // GROUP_SIZE) * GROUP_SIZE}-to-{((bpm // GROUP_SIZE) * GROUP_SIZE) + GROUP_SIZE - 1}"
all_tracks.append({"file": file, "size": size, "bpm_range": bpm_range})
# Sort by size descending
all_tracks.sort(key=lambda x: x["size"], reverse=True)
# Calculate total size and number of CDs needed
total_size = sum(t["size"] for t in all_tracks)
num_cds = max(1, (total_size + CD_SIZE - 1) // CD_SIZE) # ceiling division
# Distribute into CD folders with BPM subfolders
cd_index = 1
current_cd = []
current_size = 0
print(f"Total size: {total_size / 1024**2:.2f} MB, splitting into {num_cds} CDs")
def write_cd(cd_index, tracks):
cd_folder = dir_b / f"CD-{cd_index:02}"
# Group tracks by BPM range
from collections import defaultdict
bpm_groups = defaultdict(list)
for track in all_tracks:
bpm_groups[track["bpm_range"]].append(track)
# Sort each bpm group by filename (or size if you want)
for bpm_range in bpm_groups:
bpm_groups[bpm_range].sort(key=lambda x: x["file"].name)
# Split each BPM group evenly into num_cds parts
def split_evenly(lst, n):
"""Split list lst into n chunks as evenly as possible by count."""
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)]
bpm_chunks = {}
for bpm_range, tracks in bpm_groups.items():
bpm_chunks[bpm_range] = split_evenly(tracks, num_cds)
# Prepare CDs
cd_contents = [[] for _ in range(num_cds)]
# Fill CDs with chunks from each BPM range
for bpm_range in bpm_chunks:
for i, chunk in enumerate(bpm_chunks[bpm_range]):
cd_contents[i].extend(chunk)
# Write CDs with BPM subfolders
for i, tracks in enumerate(cd_contents, start=1):
cd_folder = dir_b / f"CD-{i:02}"
cd_folder.mkdir(parents=True, exist_ok=True)
size_accum = 0
for track in tracks:
bpm_subfolder = cd_folder / track["bpm_range"]
bpm_subfolder.mkdir(parents=True, exist_ok=True)
dest_file = bpm_subfolder / track["file"].name
shutil.copy(track["file"], dest_file)
total_size = sum(t['size'] for t in tracks)
print(f"[WRITE] CD-{cd_index:02} - {len(tracks)} tracks, {total_size / 1024**2:.2f} MB")
for track in all_tracks:
if current_size + track["size"] > CD_SIZE and current_cd:
write_cd(cd_index, current_cd)
cd_index += 1
current_cd = []
current_size = 0
current_cd.append(track)
current_size += track["size"]
# Final CD
if current_cd:
write_cd(cd_index, current_cd)
shutil.copy(track["file"], bpm_subfolder / track["file"].name)
size_accum += track["size"]
print(f"[WRITE] CD-{i:02}: {len(tracks)} tracks, approx {size_accum/1024**2:.2f} MB")