Mercurial > codedump
changeset 136:da4f7200665f default tip
buncha shit
| author | Paper <paper@tflc.us> |
|---|---|
| date | Sat, 07 Mar 2026 18:04:10 -0500 |
| parents | 0c3cd90e91f7 |
| children | |
| files | animeregex.py copy-aac-fixup.py create.py decode-mixed-mode.c split-aac.py |
| diffstat | 5 files changed, 201 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/animeregex.py Sat Mar 07 18:04:10 2026 -0500 @@ -0,0 +1,12 @@ +import os +import re + +for i in os.listdir("."): + if i.endswith(".mkv"): + regex = re.search("\[(?P<group>.*?)\] (?P<anime>.+?) - (?P<nc>[A-z]+|\d+)? ?(?P<episode>\d+)?", i) + if regex is None: + continue + if regex.group("episode") is None: + os.rename(i, regex.group("anime") + " - " + regex.group("episode").lstrip("0") + ".mkv") + else: + os.rename(i, regex.group("anime") + " - " + regex.group("nc") + " " + regex.group("episode").lstrip("0") + ".mkv")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/copy-aac-fixup.py Sat Mar 07 18:04:10 2026 -0500 @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +import glob +import subprocess +import termios + +oldtty = termios.tcgetattr(0) + +# list of Popen classes to wait on +# this allows us to run metaflac independently on +# a huge list of files concurrently +processes = list() + +i = 1 + +# glob the files in order +files = glob.glob("*.aac") +files.sort() +for g in files: + processes.append(subprocess.Popen(["ffmpeg", "-i", g, "-c", "copy", "-metadata", "track=%d" % i, g + ".m4a"])) + i += 1 + +for p in processes: + p.wait() + +# ffmpeg fucks the terminal, restore it back +termios.tcsetattr(0, termios.TCSANOW, oldtty)
--- a/create.py Sat Jan 24 15:10:05 2026 -0500 +++ b/create.py Sat Mar 07 18:04:10 2026 -0500 @@ -6,6 +6,9 @@ import argparse import json import subprocess +import os +import math #ceil +import typing def build_vf(blur) -> list[str]: if blur: @@ -14,82 +17,84 @@ return ["-vf", "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2"] # Build filter string -def build_filter_string(length: int, cover: bool) -> str: - f = "" - i = 1 if cover else 0 - for x in range(length): - f += ("[%d:0]" % (x + i)) - f += ("concat=n=%d:v=0:a=1[out]" % length) - return f +def build_filter_string(length: int, offset: int) -> str: + f = "" + i = offset + for x in range(length): + f += ("[%d:0]" % (x + i)) + f += ("concat=n=%d:v=0:a=1[out]" % length) + return f -def build_arguments_list(audio_files: list[str], cover, output, blur) -> list: - args = ["ffmpeg", "-y"] - if not cover is None: - args.extend(["-r", "1", "-loop", "1", "-i", cover]) - # I want you to play that song again - for f in audio_files: - args.extend(["-i", f]) - args.extend(["-filter_complex", build_filter_string(len(audio_files), False if cover is None else True), "-map", "[out]"]) - if not cover is None: - # Letterbox to 1920x1080 - args.extend(["-map", "0:v", "-tune", "stillimage", "-c:v", "libx264"]) - args.extend(build_vf(blur)) - args.extend(["-shortest"]) - args.append(output + ".mkv") - return args +def build_arguments_list(audio_files: list[str], cover: typing.Optional[str], output: str, blur: bool, duration: float) -> list: + args = ["ffmpeg", "-y"] + # I want you to play that song again + if not cover is None: + args.extend(["-r", "1", "-loop", "1", "-i", cover]) + for f in audio_files: + args.extend(["-i", f]) + args.extend(["-filter_complex", build_filter_string(len(audio_files), 1 if cover else 0), "-map", "[out]"]) + if not cover is None: + # Letterbox to 1920x1080 + args.extend(["-map", "0:v", + "-tune", "stillimage", + "-c:v", "libx264", + # Add a second to account for inconsistencies in durations + "-t", "%f" % (duration + 1.0)]) + args.extend(build_vf(blur)) + args.append(output + ".mkv") + return args # Returns a Popen object that should be waited on -def run_ffmpeg(audio_files: list[str], cover, output, blur) -> subprocess.Popen: - args = build_arguments_list(audio_files, cover, output, blur) - print(args) - return subprocess.Popen(args) +def run_ffmpeg(audio_files: list[str], cover: typing.Optional[str], output: str, blur: bool, duration: float) -> subprocess.Popen: + args = build_arguments_list(audio_files, cover, output, blur, duration) + print(args) + return subprocess.Popen(args) # Returns a Popen object that should be waited on. # stdout is also piped... def run_ffprobe(audio_file: str) -> subprocess.Popen: - return subprocess.Popen(["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", audio_file], stdout=subprocess.PIPE, text=True) + return subprocess.Popen(["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", audio_file], stdout=subprocess.PIPE, text=True) -def get_title_from_tags(j, default: str) -> str: - # Is there an easier way to do this...? - for tag in j: - if tag.lower() == "title": - return j[tag] +def get_title_from_tags(j: list, default: str) -> str: + # Is there an easier way to do this...? + for tag in j: + if tag.lower() == "title": + return j[tag] - # Ugh - return default + # Ugh + return default def doit(audio_files: list[str], cover, output, blur) -> int: - ffprobes = [run_ffprobe(x) for x in audio_files] - ffmpeg = run_ffmpeg(audio_files, cover, output, blur) + dur = 0.0 - # Wait for all ffprobe processes to finish their jobs - for f in ffprobes: - f.wait() + ffprobes = [run_ffprobe(x) for x in audio_files] - # Iterate the list again, and add up all the times. - # This also accounts for milliseconds etc. to be - # more accurate - with open(output + ".txt", "w", encoding="utf-8") as fw: - dur = 0.0 - for f in ffprobes: - j = json.load(f.stdout) - fw.write("%d:%02d:%02d %s\n" % (int(dur) // 3600, int(dur) % 3600 // 60, int(dur) % 60, get_title_from_tags(j["format"]["tags"], "OOPS...."))) - dur += float(j["format"]["duration"]) + # Create output txt file with timestamps; we also use this duration + # to force ffmpeg to do the right thing instead of elongating our + # video + with open(output + ".txt", "w", encoding="utf-8") as fw: + for f in ffprobes: + f.wait() + j = json.load(f.stdout) + fw.write("%d:%02d:%02d %s\n" % (int(dur) // 3600, int(dur) % 3600 // 60, int(dur) % 60, get_title_from_tags(j["format"]["tags"], "OOPS...."))) + dur += float(j["format"]["duration"]) - # Finally, wait on the big ffmpeg process - ffmpeg.wait() + ffmpeg = run_ffmpeg(audio_files, cover, output, blur, dur) + + # Finally, wait on the big ffmpeg process + ffmpeg.wait() def main() -> int: - parser = argparse.ArgumentParser(prog='create', description='Creates album videos', epilog='(c) paper 2025 all rights reversed') - parser.add_argument('-c', '--cover', required=True) - parser.add_argument('-o', '--output', required=True) - parser.add_argument('-b', '--blur', action='store_true') - parser.add_argument('audio', action='extend', nargs='+', type=str) - args = parser.parse_args() - doit(args.audio, args.cover, args.output, args.blur) + parser = argparse.ArgumentParser(prog='create', description='Creates album videos', epilog='(c) paper 2025 all rights reversed') + parser.add_argument('-c', '--cover', required=True) + parser.add_argument('-o', '--output', required=True) + parser.add_argument('-b', '--blur', action='store_true') + parser.add_argument('audio', action='extend', nargs='+', type=str) + args = parser.parse_args() + doit(args.audio, args.cover, args.output, args.blur) if __name__ == "__main__": - exit(main()) + exit(main())
--- a/decode-mixed-mode.c Sat Jan 24 15:10:05 2026 -0500 +++ b/decode-mixed-mode.c Sat Mar 07 18:04:10 2026 -0500 @@ -2,6 +2,7 @@ #include <stdio.h> #include <stdlib.h> #include <inttypes.h> +#include <string.h> static void decode_size(unsigned long x) { @@ -10,16 +11,31 @@ printf("k%sByteCode", lut[x & 3]); } -int main(int argc, char *argv[]) +static void func_header(unsigned long x, unsigned long off) { - unsigned long x; + unsigned long i; + int ret; + + static const char *lut[] = {"void", "OMS_uint8", "OMS_uint16", "OMS_uint32"}; + + /* dont care */ + x >>= 4; - if (argc < 2) { - fprintf(stderr, "usage: decrypt-mixed-call <param>\n"); - return 1; - } + printf("%s OMS_Unknown0x%02lX(", lut[x & 3], off); + ret = !!(x & 3); + x >>= 2; + + for (i = 1; x; i++, x >>= 2) + printf("%s%s p%ld", (i == 1) ? "" : ", ", lut[x & 3], i); - x = strtoul(argv[1], NULL, 0); + printf(")\n{\n\t"); + if (ret) printf("return "); + printf("CallUniversalProc(OMS_InternalFuncTable[0x%02lX],\n\t\t", off); +} + +static void gen(unsigned long x) +{ + unsigned long i; switch (x & 15) { case 0: @@ -30,7 +46,7 @@ break; case 2: printf("I'm too lazy for this!"); - return 1; + break; case 5: printf("kThinkCStackBased"); break; @@ -47,8 +63,7 @@ printf("kStackDispatchedPascalStackBased"); break; default: - /* Invalid */ - return 1; + return; } x >>= 4; @@ -61,11 +76,56 @@ x >>= 2; /* hopefully we're using stack, since that's the ONLY thing i'm handling */ - for (uint32_t i = 1; i < 13 && x; i++, x >>= 2) { - printf(" | STACK_ROUTINE_PARAMETER(%" PRIu32 ", ", i); + for (i = 1; x; i++, x >>= 2) { + printf(" | STACK_ROUTINE_PARAMETER(%lu, ", i); decode_size(x); printf(")"); } +} + +void func_footer(unsigned long x) +{ + unsigned long i; + + x >>= 6; + + printf("\n\t"); + + for (i = 1; x; i++, x >>= 2) + printf(", p%lu", i); + + printf(");\n}"); +} + +int main(int argc, char *argv[]) +{ + unsigned long x; + int stubs; + int inarg; + unsigned long off; + + if (argc < 2) { + fprintf(stderr, "usage: decrypt-mixed-call <param>\n"); + return 1; + } + + stubs = (argc > 2 && !strcmp(argv[1], "-gen-stub")); + + if (stubs) { + inarg = 3; + off = strtoul(argv[2], NULL, 0); + } else + inarg = 1; + + x = strtoul(argv[inarg], NULL, 0); + + if (stubs) { + func_header(x, off); + } + gen(x); + if (stubs) { + func_footer(x); + } puts("");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/split-aac.py Sat Mar 07 18:04:10 2026 -0500 @@ -0,0 +1,28 @@ +# We want to split the files, preserving their original compression with as few possible clicks. +# This means we have to align all of our track offsets as frames. + +import sys + + +def get_closest_aligned_time(target_time: float, sample_rate: float) -> int: + # Convert target time into an exact amount of samples first. + # We obviously can't have a fraction of a sample. + samples = int(round(target_time * sample_rate)) + + # Round to the nearest frame multiple. Note that AAC frames are + # *usually* (but not always) 1024 samples in size. + frames = samples - samples % 1024 + + return frames / sample_rate + + +# sample rate is first argument +sample_rate = float(sys.argv[1]) + +# rest of the arguments are the times to align. +# Hopefully giving these values as microseconds will help +# ffmpeg realize it should cut along frame boundaries. +for i in sys.argv[2:]: + x = get_closest_aligned_time(float(i), sample_rate) + print("%f\n" % x, end="") + print("%f," % x, end="")
