96 lines
2.6 KiB
JavaScript
96 lines
2.6 KiB
JavaScript
const fs = require('fs')
|
|
const fsPromises = fs.promises
|
|
const path = require('path')
|
|
const getImgSize = require('image-size')
|
|
const request = require('request')
|
|
|
|
const FlacProcessor = require('./flac-metadata')
|
|
|
|
const extReg = /^(\.(?:jpe?g|png)).*$/
|
|
const vendor = 'reference libFLAC 1.2.1 20070917'
|
|
|
|
const writeMeta = async(filePath, meta, picPath) => {
|
|
const comments = Object.keys(meta).map(key => `${key.toUpperCase()}=${meta[key] || ''}`)
|
|
const data = {
|
|
vorbis: {
|
|
vendor,
|
|
comments,
|
|
},
|
|
}
|
|
if (picPath) {
|
|
const apicData = await fsPromises.readFile(picPath)
|
|
let imgSize = getImgSize(apicData)
|
|
let mime_type
|
|
let bitsPerPixel
|
|
if (apicData[0] == 0xff && apicData[1] == 0xd8 && apicData[2] == 0xff) {
|
|
mime_type = 'image/jpeg'
|
|
bitsPerPixel = 24
|
|
} else {
|
|
mime_type = 'image/png'
|
|
bitsPerPixel = 32
|
|
}
|
|
data.picture = {
|
|
pictureType: 3,
|
|
mimeType: mime_type,
|
|
description: '',
|
|
width: imgSize.width,
|
|
height: imgSize.height,
|
|
bitsPerPixel,
|
|
colors: 0,
|
|
pictureData: apicData,
|
|
}
|
|
}
|
|
|
|
const reader = fs.createReadStream(filePath)
|
|
const tempPath = filePath + '.lxmtemp'
|
|
const writer = fs.createWriteStream(tempPath)
|
|
const flacProcessor = new FlacProcessor()
|
|
flacProcessor.writeMeta(data)
|
|
|
|
reader.pipe(flacProcessor).pipe(writer).on('finish', () => {
|
|
fs.unlink(filePath, err => {
|
|
if (err) return console.log(err.message)
|
|
fs.rename(tempPath, filePath, err => {
|
|
if (err) console.log(err.message)
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
module.exports = (filePath, meta) => {
|
|
if (!meta.APIC) return writeMeta(filePath, meta)
|
|
const picUrl = meta.APIC
|
|
delete meta.APIC
|
|
if (!/^http/.test(picUrl)) {
|
|
return writeMeta(filePath, meta)
|
|
}
|
|
let ext = path.extname(picUrl)
|
|
let picPath = filePath.replace(/\.flac$/, '') + (ext ? ext.replace(extReg, '$1') : '.jpg')
|
|
|
|
request(picUrl)
|
|
.on('response', respones => {
|
|
if (respones.statusCode !== 200 && respones.statusCode != 206) return writeMeta(filePath, meta)
|
|
respones
|
|
.pipe(fs.createWriteStream(picPath))
|
|
.on('finish', async() => {
|
|
if (respones.complete) {
|
|
await writeMeta(filePath, meta, picPath)
|
|
} else {
|
|
writeMeta(filePath, meta)
|
|
}
|
|
fs.unlink(picPath, err => {
|
|
if (err) console.log(err.message)
|
|
})
|
|
})
|
|
.on('error', err => {
|
|
if (err) console.log(err.message)
|
|
writeMeta(filePath, meta)
|
|
})
|
|
})
|
|
.on('error', err => {
|
|
if (err) console.log(err.message)
|
|
writeMeta(filePath, meta)
|
|
})
|
|
}
|
|
|