import { $, ProcessOutput } from 'zx' import { fetchSongsIter } from '../../../utils/navidrome.ts' import { asyncPool } from '@fuman/utils' import { join } from 'path/posix' // async function checkIfBroken(path: string) { // const r = await $`ffprobe -v error -show_entries stream=codec_type,codec_name,index:stream_tags=title,language -of json ${path}`.json() // } // for await (const song of fetchSongsIter()) { // } const broken: string[] = [] await asyncPool(fetchSongsIter({ onChunkProcessed: (page, items) => { console.log(`Processed page ${page} with ${items} items`) }, }), async (song) => { const fullPath = join(song.libraryPath, song.path) const path = fullPath.replace('/music/s3/', '/mnt/tank/enc/media/music/') try { const r = await $`ffmpeg -v error -i ${path} -f null -`.quiet() if (r.exitCode !== 0 || r.stderr.trim() !== '') throw r } catch (e) { if (!(e instanceof ProcessOutput)) throw e console.log('%s - %s (%s) seems broken:', song.artist, song.title, path) console.log(e.stderr) broken.push(path) } }, { limit: 8 }) if (broken.length > 0) { console.log('Found %d broken files:', broken.length) for (const path of broken.sort()) { console.log(' %s', path) } process.exit(1) }