37 lines
2 KiB
TypeScript
37 lines
2 KiB
TypeScript
// JPEG copies of the Play renders (play, tab7, tab10, feature): about 4x smaller, so `play images` uploads much faster.
|
|
// The App Store screenshots stay PNG.
|
|
// storebound shots jpeg [--q 92] [--lang en,tr] [--variant b | --variants]
|
|
import { existsSync, readdirSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { spawnSync } from 'node:child_process';
|
|
import type { Ctx } from '../lib/ctx';
|
|
import { done, log } from '../lib/log';
|
|
import { variantRoot } from './lib';
|
|
|
|
/** ffmpeg's mjpeg -q:v (2 best .. 31 worst) for a 0-100 quality. */
|
|
export const ffmpegQ = (q: number): number => Math.max(2, Math.min(31, Math.round(2 + (100 - q) * 0.29)));
|
|
|
|
export async function run(ctx: Ctx): Promise<void> {
|
|
const { config, resolve } = ctx.loaded;
|
|
const base = resolve(ctx.args.get('src') ?? config.renders ?? config.shots?.out ?? 'store/renders');
|
|
const roots = ctx.args.has('variants') ? [base, ...Object.keys(config.shots?.variants ?? {}).map(v => variantRoot(base, v, config.shots?.variants))]
|
|
: [variantRoot(base, ctx.args.get('variant'), config.shots?.variants)];
|
|
const q = ctx.args.num('q', 92);
|
|
const langs = ctx.args.list('lang').length ? ctx.args.list('lang') : config.languages.map(l => l.id);
|
|
const sips = spawnSync('sh', ['-c', 'command -v sips']).status === 0;
|
|
let n = 0;
|
|
for (const src of roots) for (const lang of langs) for (const sub of ['play', 'tab7', 'tab10', 'feature']) {
|
|
const dir = join(src, lang, sub);
|
|
if (!existsSync(dir)) continue;
|
|
for (const f of readdirSync(dir).filter(f => f.endsWith('.png'))) {
|
|
const inp = join(dir, f), out = inp.replace(/\.png$/, '.jpg');
|
|
const r = sips
|
|
? spawnSync('sips', ['-s', 'format', 'jpeg', '-s', 'formatOptions', String(q), inp, '--out', out])
|
|
: spawnSync('ffmpeg', ['-v', 'error', '-y', '-i', inp, '-q:v', String(ffmpegQ(q)), out]);
|
|
if (r.status !== 0) throw new Error(`jpeg failed for ${inp}`);
|
|
n++;
|
|
}
|
|
log('shots', `${src === base ? '' : src.slice(base.length + 1) + '/'}${lang}/${sub}: jpeg q${q}`);
|
|
}
|
|
done('shots', `${n} JPEG copies`);
|
|
}
|