diff --git a/bin/sonic.js b/bin/sonic.js index a1d06ff..899fa75 100755 --- a/bin/sonic.js +++ b/bin/sonic.js @@ -137,6 +137,21 @@ function cleanup(exitCode = 0) { ]).then(() => process.exit(exitCode)); } +// A crash must still stop the music and give the terminal back. +function crash(err) { + try { ui.cleanup(); } catch {} + if (player.proc) { + try { player.proc.kill('SIGKILL'); } catch {} + } + if (process.stdin.isTTY && process.stdin.isRaw) process.stdin.setRawMode(false); + console.error(`\nsonic hit a bug and stopped: ${err?.message || err}`); + console.error('please report it: https://github.com/sethmills21/sonic/issues'); + if (process.env.SONIC_DEBUG) console.error(err?.stack); + process.exit(1); +} + +process.on('uncaughtException', crash); +process.on('unhandledRejection', crash); process.on('SIGINT', () => cleanup(0)); process.on('SIGTERM', () => cleanup(0)); process.on('exit', () => { diff --git a/lib/ui.js b/lib/ui.js index 073bdaa..2407c89 100644 --- a/lib/ui.js +++ b/lib/ui.js @@ -604,7 +604,8 @@ export class UI { const parts = []; if (typeof options.volume === 'number') { const steps = 10; - const filled = Math.round((options.volume / 100) * steps); + // mpv goes to 150; past 100 the meter stays full and the number keeps counting. + const filled = Math.max(0, Math.min(steps, Math.round((options.volume / 100) * steps))); const meter = chalk.hex(theme.accent)('━'.repeat(filled)) + chalk.hex(theme.muted)('─'.repeat(steps - filled)); parts.push(`${chalk.hex(theme.muted)('vol')} ${meter} ${chalk.hex(theme.muted)(String(options.volume))}`); }