Files
legacy-tools/iidx/2dxrender-master/render_songs.py

148 lines
5.2 KiB
Python
Executable File

import argparse
import queue
import threading
import shutil
import glob
import os
import sys
import subprocess
import musicdata_tool
def get_sanitized_filename(filename, invalid_chars='<>:;\"\\/|?*'):
for c in invalid_chars:
filename = filename.replace(c, "_")
return filename
def read_charts(mid, input_chart, input_sounds, metadata, output_folder="", chart_ids=[0, 1, 2, 7, 8, 9], output_format="mp3"):
chart_labels = {
0: "SP NORMAL",
1: "SP HYPER",
2: "SP ANOTHER",
3: "SP BEGINNER",
6: "DP NORMAL",
7: "DP HYPER",
8: "DP ANOTHER",
}
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for i in range(0, 12):
if i not in chart_ids or i not in chart_labels:
continue
id3_str = ""
if metadata:
id3_parts = []
if 'artist' in metadata and metadata['artist']:
id3_parts.append('--id3-artist "{}"'.format(metadata['artist']))
if 'title' in metadata and metadata['title']:
id3_parts.append('--id3-title "{}"'.format(metadata['title']))
if 'genre' in metadata and metadata['genre']:
id3_parts.append('--id3-genre "{}"'.format(metadata['genre']))
if 'album' in metadata and metadata['album']:
id3_parts.append('--id3-album "{}"'.format(metadata['album']))
if 'album_artist' in metadata and metadata['album_artist']:
id3_parts.append('--id3-album-artist "{}"'.format(metadata['album_artist']))
if 'year' in metadata and metadata['year']:
id3_parts.append('--id3-year "{}"'.format(metadata['year']))
if 'mid' in metadata and metadata['mid']:
id3_parts.append('--id3-track "{}"'.format(metadata['mid']))
id3_str = " ".join(id3_parts)
if output_format.lower() == "mp3":
output_filename = os.path.join(output_folder, get_sanitized_filename("[%04d] %s - %s (%s).mp3" % (metadata.get('mid', ''), metadata.get('artist', ''), metadata.get('title', ''), chart_labels[i])))
else:
output_filename = os.path.join(output_folder, get_sanitized_filename("[%04d] %s - %s (%s).wav" % (metadata.get('mid', ''), metadata.get('artist', ''), metadata.get('title', ''), chart_labels[i])))
else:
if output_format.lower() == "mp3":
output_filename = "%d.mp3" % mid
else:
output_filename = "%d.wav" % mid
print("Rendering", input_chart)
subprocess.call("2dxrender.exe -i \"%s\" -s \"%s\" -o \"%s\" -c %d %s" % (input_chart, input_sounds, output_filename, i, id3_str), shell=True)
print("Saved", output_filename)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--songs-folder', help='Input songs folder', required=True)
parser.add_argument('--output-folder', default="renders", help='Output folder')
parser.add_argument('--music-database-file', default='music_data.bin', help='Input music database file')
parser.add_argument('--charts', nargs='+', default=[2], help='Charts to render for each song', type=int)
parser.add_argument('--id3-album', help='ID3 album', default="", type=str)
parser.add_argument('--id3-album-artist', help='ID3 album artist', default="", type=str)
parser.add_argument('--id3-year', help='ID3 year', default="", type=str)
parser.add_argument('--output-format', help='Output format: WAV or MP3', default="mp3", type=str)
parser.add_argument('--threads', help='Max number of threads to use for rendering songs', default=4, type=int)
args = parser.parse_args()
song_info = {}
if os.path.exists(args.music_database_file):
iidx_songs = musicdata_tool.extract_file(args.music_database_file, None, True)
for song in iidx_songs.get('data', []):
mid = song['song_id']
song_info[mid] = {
'artist': song['artist'],
'title': song['title'],
'genre': song['genre'],
'album': args.id3_album,
'album_artist': args.id3_album_artist,
'year': args.id3_year,
'mid': mid,
}
def worker():
while True:
mid = q.get()
if mid is None:
break
try:
read_charts(mid, os.path.join("songs", "{}".format(mid), "{}.1".format(mid)), os.path.join("songs", "{}".format(mid), "{}.s3p".format(mid)), song_info.get(mid, None), args.output_folder, args.charts, args.output_format)
except:
pass
q.task_done()
q = queue.Queue()
threads = []
for i in range(args.threads):
t = threading.Thread(target=worker)
t.start()
threads.append(t)
for root, dirnames, filenames in os.walk('songs'):
for foldername in dirnames:
try:
mid = int(os.path.basename(foldername))
q.put(mid)
except:
pass
# block until all tasks are done
q.join()
# stop workers
for i in range(args.threads):
q.put(None)
for t in threads:
t.join()