新增FLAC格式音乐标签信息写入与封面嵌入
This commit is contained in:
+79
-23
@@ -1,38 +1,94 @@
|
||||
const fs = require('fs')
|
||||
const { Processor: FlacProcessor, data: { MetaDataBlockVorbisComment: FlacComment } } = require('./flac-metadata')
|
||||
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'
|
||||
|
||||
module.exports = (filenPath, meta) => {
|
||||
const reader = fs.createReadStream(filenPath)
|
||||
const tempPath = filenPath + '.lxmtemp'
|
||||
const writer = fs.createWriteStream(tempPath)
|
||||
const flacProcessor = new FlacProcessor()
|
||||
if (meta.APIC) delete meta.APIC
|
||||
|
||||
const comments = []
|
||||
for (const key in meta) {
|
||||
comments.push(`${key.toUpperCase()}=${meta[key]}`)
|
||||
const writeMeta = (filePath, meta, picPath) => {
|
||||
const comments = Object.keys(meta).map(key => `${key.toUpperCase()}=${meta[key]}`)
|
||||
const data = {
|
||||
vorbis: {
|
||||
vendor,
|
||||
comments,
|
||||
},
|
||||
}
|
||||
if (picPath) {
|
||||
const apicData = Buffer.from(fs.readFileSync(picPath, 'binary'), 'binary')
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
let isInjected = false
|
||||
flacProcessor.on('preprocess', function(mdb) {
|
||||
// Remove existing VORBIS_COMMENT block, if any.
|
||||
if (mdb.type === flacProcessor.MDB_TYPE_VORBIS_COMMENT) mdb.remove()
|
||||
// Inject new VORBIS_COMMENT block.
|
||||
if ((mdb.removed || mdb.isLast) && !isInjected) {
|
||||
isInjected = true
|
||||
let mdbVorbis = FlacComment.create(mdb.isLast, vendor, comments)
|
||||
this.push(mdbVorbis.publish())
|
||||
}
|
||||
})
|
||||
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(filenPath, err => {
|
||||
fs.unlink(filePath, err => {
|
||||
if (err) return console.log(err.message)
|
||||
fs.rename(tempPath, filenPath, err => {
|
||||
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 picPath = filePath.replace(/\.flac$/, '') + path.extname(picUrl).replace(extReg, '$1')
|
||||
|
||||
request(picUrl)
|
||||
.on('response', respones => {
|
||||
if (respones.statusCode !== 200 && respones.statusCode != 206) return writeMeta(filePath, meta)
|
||||
respones
|
||||
.pipe(fs.createWriteStream(picPath))
|
||||
.on('finish', () => {
|
||||
if (respones.complete) {
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user