mirror of
https://git.stupid.fish/teidesu/scripts.git
synced 2025-07-27 18:22:10 +10:00
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
import { readFile, rm } from 'node:fs/promises'
|
|
import { join } from 'node:path'
|
|
import { $ } from 'zx'
|
|
import { downloadStream } from '../../utils/fetch.ts'
|
|
import { getEnv } from '../../utils/misc.ts'
|
|
import { fetchSongs } from '../../utils/navidrome.ts'
|
|
import { WebdavClient } from '../../utils/webdav.ts'
|
|
|
|
const webdav = new WebdavClient({
|
|
baseUrl: getEnv('NAVIDROME_WEBDAV_ENDPOINT'),
|
|
username: getEnv('NAVIDROME_WEBDAV_USERNAME'),
|
|
password: getEnv('NAVIDROME_WEBDAV_PASSWORD'),
|
|
})
|
|
|
|
const CHUNK_SIZE = 1000
|
|
for (let offset = 0; ; offset += CHUNK_SIZE) {
|
|
const songs = await fetchSongs(offset, CHUNK_SIZE)
|
|
if (songs.length === 0) break
|
|
|
|
for (const song of songs) {
|
|
const ext = song.path.split('.').pop()!
|
|
if (ext !== 'm4a') continue
|
|
|
|
console.log('❌ song %s is m4a, remuxing...', song.path)
|
|
const webdavPath = song.path.replace('/music/s3/', '/')
|
|
const res = await webdav.get(webdavPath).catch(() => null)
|
|
|
|
if (!res) {
|
|
console.log(' ❌ failed to get %s', webdavPath)
|
|
continue
|
|
}
|
|
|
|
const tmpfile = join('assets', `${song.id}.m4a`)
|
|
await downloadStream(res.body!, tmpfile)
|
|
console.log(' - downloaded to %s', tmpfile)
|
|
|
|
const probe = await $`ffprobe -v error -show_entries stream=codec_type,codec_name,index:stream_tags=title,language -of json ${tmpfile}`.json()
|
|
const audioStream = probe.streams.find(stream => stream.codec_type === 'audio')
|
|
if (!audioStream) {
|
|
console.log(' ❌ no audio stream found')
|
|
await rm(tmpfile)
|
|
continue
|
|
}
|
|
const codec = audioStream.codec_name
|
|
|
|
if (codec !== 'flac') {
|
|
console.log(` ❌ audio stream is ${codec}, not flac, skipping`)
|
|
await rm(tmpfile)
|
|
continue
|
|
}
|
|
|
|
console.log(' - audio stream is flac, remuxing')
|
|
|
|
// remux
|
|
const remuxed = join('assets', `${song.id}.flac`)
|
|
await rm(remuxed, { force: true })
|
|
await $`ffmpeg -i ${tmpfile} -c:a copy ${remuxed}`.quiet(true)
|
|
console.log(' - remuxed to %s', remuxed)
|
|
await rm(tmpfile)
|
|
|
|
await webdav.put(webdavPath.replace('.m4a', '.flac'), await readFile(remuxed))
|
|
await webdav.delete(webdavPath)
|
|
console.log(' - uploaded to %s', webdavPath.replace('.m4a', '.flac'))
|
|
await rm(remuxed)
|
|
}
|
|
}
|