From 621dbd7ffacd8b8065d49413b7cc6fed47c063a3 Mon Sep 17 00:00:00 2001 From: UnitedAirforce Date: Tue, 17 Jun 2025 19:47:08 +0800 Subject: [PATCH] update --- .../audio_shifted/111_genzp.py | 35 +++++++++++++++++ .../ios m4a offset correction/process.py | 27 +++++++++++++ .../ios m4a offset correction/readme.txt | 16 ++++++++ .../ios m4a offset correction/unpack.py | 39 +++++++++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 various-tools/ios m4a offset correction/audio_shifted/111_genzp.py create mode 100644 various-tools/ios m4a offset correction/process.py create mode 100644 various-tools/ios m4a offset correction/readme.txt create mode 100644 various-tools/ios m4a offset correction/unpack.py diff --git a/various-tools/ios m4a offset correction/audio_shifted/111_genzp.py b/various-tools/ios m4a offset correction/audio_shifted/111_genzp.py new file mode 100644 index 0000000..cd5436f --- /dev/null +++ b/various-tools/ios m4a offset correction/audio_shifted/111_genzp.py @@ -0,0 +1,35 @@ +import os + +SEVEN_ZIP_PATH = r"C:\Program Files\7-Zip\7z.exe" + +PASSWORD = "eiprblFFv69R83J5" + +OUTPUT_FOLDER = "output" + +def generate_zipcrypto_commands(): + cwd = os.getcwd() + output_path = os.path.join(cwd, OUTPUT_FOLDER) + + os.makedirs(output_path, exist_ok=True) + + commands = [] + + for root, _, files in os.walk(cwd): + if root == output_path: + continue + + for file in files: + file_path = os.path.join(root, file) + zip_filename = file + ".zip" + zip_path = os.path.join(output_path, zip_filename) + + cmd = f'"{SEVEN_ZIP_PATH}" a -p{PASSWORD} -mem=ZipCrypto "{zip_path}" "{file_path}"' + commands.append(cmd) + + return commands + +if __name__ == "__main__": + zip_commands = generate_zipcrypto_commands() + + for cmd in zip_commands: + print(cmd) \ No newline at end of file diff --git a/various-tools/ios m4a offset correction/process.py b/various-tools/ios m4a offset correction/process.py new file mode 100644 index 0000000..e95019d --- /dev/null +++ b/various-tools/ios m4a offset correction/process.py @@ -0,0 +1,27 @@ +import os +import subprocess +from pathlib import Path + +INPUT_DIR = Path("audio") +OUTPUT_DIR = Path("audio_shifted") +OUTPUT_DIR.mkdir(exist_ok=True) + +def shift_audio(file_path: Path): + output_file = OUTPUT_DIR / file_path.name + cmd = [ + "ffmpeg", + "-y", + "-ss", "0.02321", + "-i", str(file_path), + "-c", "copy", + str(output_file) + ] + print(f"Processing {file_path.name}...") + subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + +def main(): + for file in INPUT_DIR.glob("*.m4a"): + shift_audio(file) + +if __name__ == "__main__": + main() diff --git a/various-tools/ios m4a offset correction/readme.txt b/various-tools/ios m4a offset correction/readme.txt new file mode 100644 index 0000000..cd0375e --- /dev/null +++ b/various-tools/ios m4a offset correction/readme.txt @@ -0,0 +1,16 @@ +These are to correct an obscure issue where the ios M4A audio are offseted by 23ms. This is a universal issue (across all ios audio files) and should not pose much issue for the majority of users. + +For preservation sake, I do not want to alter the original game file. Thus, those who wish to correct this issue should process the audio on their local environment. + +Process. + +Copy/cut all the `.m4a.zip` to the working directory. + +Run `unpack.py`. All files will be extracted to `audio` folder. + +Run `process.py`, all the audios within `audio` folder will be shifted and saved to `audio_shifted` folder. + +Go into `audio_shifted` folder. Run `111_genzp.py`, it will provide the 7-zip compression commands for all the files, with output to `../audio_shifted/output`. Make sure to edit the python script's 7zip install location. + +Simply copy the `zips` located in `output` folder and replace existing ones. + diff --git a/various-tools/ios m4a offset correction/unpack.py b/various-tools/ios m4a offset correction/unpack.py new file mode 100644 index 0000000..42d6481 --- /dev/null +++ b/various-tools/ios m4a offset correction/unpack.py @@ -0,0 +1,39 @@ +import os +import zipfile +import threading +import traceback + +ZIP_PASSWORD = b"eiprblFFv69R83J5" +OUTPUT_DIR = "audio" +MAX_THREADS = 4 +semaphore = threading.Semaphore(MAX_THREADS) + +def unpack_zip(zip_path): + with semaphore: + try: + with zipfile.ZipFile(zip_path) as zf: + print(f"Extracting {zip_path}...") + zf.extractall(OUTPUT_DIR, pwd=ZIP_PASSWORD) + print(f"Unpacked: {zip_path}") + except Exception as e: + print(f"Failed to unpack {zip_path}: {e}") + traceback.print_exc() + +def main(): + if not os.path.exists(OUTPUT_DIR): + os.makedirs(OUTPUT_DIR) + + zip_files = [f for f in os.listdir('.') if f.lower().endswith('.zip')] + print(f"Found ZIP files: {zip_files}") + threads = [] + + for zip_file in zip_files: + t = threading.Thread(target=unpack_zip, args=(zip_file,)) + t.start() + threads.append(t) + + for t in threads: + t.join() + +if __name__ == "__main__": + main() \ No newline at end of file