diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..61e296f
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
new file mode 100644
index 0000000..fcf3635
--- /dev/null
+++ b/.idea/jsLibraryMappings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/scripts/asset-extract.py b/scripts/asset-extract.py
index 13acf60..a9421fb 100644
--- a/scripts/asset-extract.py
+++ b/scripts/asset-extract.py
@@ -18,9 +18,14 @@ def run(event, func, args):
if __name__ == '__main__':
parser = argparse.ArgumentParser()
- parser.add_argument('--config', help='asset config', default='assets.yaml')
- parser.add_argument('--processes', type=int, default=cpu_count(), help='number of processes to use')
- parser.add_argument('--out-dir', '--output', help='output directory', default='../public/assets')
+ parser.add_argument('--config', help='asset config (default=assets.yaml)', default='assets.yaml')
+ parser.add_argument('--processes', type=int, default=cpu_count(), help=f'number of processes to use (default={cpu_count()})')
+ parser.add_argument('--out-dir', '--output-dir', '--output', '-o', help='output directory (default=../public/assets)', default='../public/assets')
+ parser.add_argument('--no-overwrite', '-n', help='don\'t overwrite exising files', action='store_true')
+ parser.add_argument('--no-music', help='don\'t process music files', action='store_true')
+ parser.add_argument('--no-audio', help='don\'t process other audio files', action='store_true')
+ parser.add_argument('--no-jackets', help='don\'t process jacket images', action='store_true')
+ parser.add_argument('--no-images', help='don\'t process other images', action='store_true')
subparsers = parser.add_subparsers(dest='game', help='game extracter to use', required=True)
extracters = get_extracters()
for name, extracter in extracters.items():
diff --git a/scripts/assets.fast.yaml b/scripts/assets.fast.yaml
new file mode 100644
index 0000000..43da980
--- /dev/null
+++ b/scripts/assets.fast.yaml
@@ -0,0 +1,32 @@
+# produces decent quality files faster, at the expense of larger file sizes
+
+# path to ffmpeg if it is not on the path
+ffmpeg_path: 'ffmpeg'
+# path to vgmstream if it is not on the path
+# required for some audio conversions
+# https://github.com/vgmstream/vgmstream
+vgmstream_path: 'vgmstream-cli'
+
+# options for music
+music:
+ enable: true
+ extension: .opus
+ ffmpeg_args: ['-b:a', '64k']
+
+# options for music jacket images
+jackets:
+ enable: true
+ extension: .webp
+ ffmpeg_args: []
+
+# options for other images
+images:
+ enable: true
+ extension: .webp
+ ffmpeg_args: ['-preset', 'drawing']
+
+# options for other audio
+audio:
+ enable: true
+ extension: .opus
+ ffmpeg_args: [ '-b:a', '64k' ]
diff --git a/scripts/assets.faster.yaml b/scripts/assets.faster.yaml
new file mode 100644
index 0000000..bf45079
--- /dev/null
+++ b/scripts/assets.faster.yaml
@@ -0,0 +1,32 @@
+# produces decent quality files much faster, at the expense of greatly increased file sizes
+
+# path to ffmpeg if it is not on the path
+ffmpeg_path: 'ffmpeg'
+# path to vgmstream if it is not on the path
+# required for some audio conversions
+# https://github.com/vgmstream/vgmstream
+vgmstream_path: 'vgmstream-cli'
+
+# options for music
+music:
+ enable: true
+ extension: .opus
+ ffmpeg_args: ['-b:a', '64k']
+
+# options for music jacket images
+jackets:
+ enable: true
+ extension: .png
+ ffmpeg_args: []
+
+# options for other images
+images:
+ enable: true
+ extension: .png
+ ffmpeg_args: []
+
+# options for other audio
+audio:
+ enable: true
+ extension: .opus
+ ffmpeg_args: [ '-b:a', '64k' ]
diff --git a/scripts/assets.lossless.yaml b/scripts/assets.lossless.yaml
new file mode 100644
index 0000000..9b20f7f
--- /dev/null
+++ b/scripts/assets.lossless.yaml
@@ -0,0 +1,32 @@
+# produces lossless files
+
+# path to ffmpeg if it is not on the path
+ffmpeg_path: 'ffmpeg'
+# path to vgmstream if it is not on the path
+# required for some audio conversions
+# https://github.com/vgmstream/vgmstream
+vgmstream_path: 'vgmstream-cli'
+
+# options for music
+music:
+ enable: true
+ extension: .flac
+ ffmpeg_args: []
+
+# options for music jacket images
+jackets:
+ enable: true
+ extension: .webp
+ ffmpeg_args: ['-lossless', '1']
+
+# options for other images
+images:
+ enable: true
+ extension: .webp
+ ffmpeg_args: ['-lossless', '1']
+
+# options for other audio
+audio:
+ enable: true
+ extension: .flac
+ ffmpeg_args: []
diff --git a/scripts/assets.yaml b/scripts/assets.yaml
index 65d3360..9ddb743 100644
--- a/scripts/assets.yaml
+++ b/scripts/assets.yaml
@@ -1,3 +1,5 @@
+# produces small-sized, decent quality files at the expense of long encoding times
+
# path to ffmpeg if it is not on the path
ffmpeg_path: 'ffmpeg'
# path to vgmstream if it is not on the path
@@ -14,13 +16,14 @@ music:
# options for music jacket images
jackets:
enable: true
- extension: .webp
+ extension: .avif
+ ffmpeg_args: ['-c:v', 'libaom-av1', '-still-picture', '1', '-cpu-used', '2', '-pix_fmt:0', 'yuv420p']
# options for other images
images:
enable: true
- extension: .webp
- ffmpeg_args: ['-preset', 'drawing']
+ extension: .avif
+ ffmpeg_args: ['-map', '0', '-map', '0', '-filter:v:1', 'alphaextract', '-c:v', 'libaom-av1', '-still-picture', '1', '-cpu-used', '2', '-pix_fmt:0', 'yuv420p']
# options for other audio
audio:
diff --git a/scripts/extracters/extracter.py b/scripts/extracters/extracter.py
index 31f3e32..7dac616 100644
--- a/scripts/extracters/extracter.py
+++ b/scripts/extracters/extracter.py
@@ -13,7 +13,7 @@ from collections import defaultdict
class Extracter:
- def __init__(self, *, config, out_dir, **kwargs):
+ def __init__(self, *, config, out_dir, no_overwrite, no_music, no_audio, no_jackets, no_images, **kwargs):
with open(config, 'r') as f:
self.config = yaml.safe_load(f)
self.music_enabled = self.config['music']['enable']
@@ -22,6 +22,11 @@ class Extracter:
self.audio_enabled = self.config['audio']['enable']
self.out_dir = Path(out_dir)
self.tmp_dir = self.out_dir / 'tmp'
+ self.no_overwrite = no_overwrite
+ self.no_music = no_music
+ self.no_audio = no_audio
+ self.no_jackets = no_jackets
+ self.no_images = no_images
def get_tmp(self, ext='.dat'):
self.tmp_dir.mkdir(parents=True, exist_ok=True)
@@ -76,7 +81,7 @@ class Extracter:
args = [
self.config['ffmpeg_path'],
- '-y',
+ ('-n' if self.no_overwrite else '-y'),
'-hide_banner',
'-loglevel',
'error',
@@ -141,13 +146,13 @@ class Extracter:
raise NotImplementedError
def extract(self):
- if self.jackets_enabled:
+ if self.jackets_enabled and not self.no_jackets:
yield from self.extract_jacket()
- if self.images_enabled:
+ if self.images_enabled and not self.no_images:
yield from self.extract_images()
- if self.music_enabled:
+ if self.music_enabled and not self.no_music:
yield from self.extract_music()
- if self.audio_enabled:
+ if self.audio_enabled and not self.no_audio:
yield from self.extract_audio()
@staticmethod