需要帮助使用 id3-parser 在 node.js 中异步解析 id3 标签
Need help parsing id3 tags asyncrhonously in node.js using id3-parser
我有一个充满 mp3 的文件夹,我想使用 id3-parser npm 模块对其进行解析,以便我可以 return 一个 rss 提要。 id3-parser 文档说要使用这个结构:
id3.parse(filebuffer).then(function(tag){
console.log(tag.title);
});
id3-parser 模块使用了 promise-a-plus 模块。我的代码的问题是标签是在堆栈的最后读取的。这是我的测试代码:
var id3 = require('id3-parser');
var fs = require('fs');
fs.readdir("podcasts", function (err, files) {
files.forEach( function (file) {
var stats = fs.statSync("podcasts/" + file);
if (stats.isFile()) {
var fbuff = fs.readFileSync("podcasts/" + file);
id3.parse(fbuff).then( function (tag) {
console.log("***"+tag.title);
});
console.log("Parsed id3 tag " + file);
}
console.log("Done file");
});
console.log("Done readdir");
});
输出为:
Parsed id3 tag test.mp3
Done file
Done readdir
***Title tag
我一辈子都想不出如何正确地等待标签被解析。解析应该在我将它放入 rss 提要之前进行(使用 rss 模块创建 xml 提要没有问题——代码未显示)。我一直在阅读有关承诺的信息,但我遗漏了一些东西。我确定我只需要完全重构我的代码,但不确定如何读取每个文件(目前使用 readdir 和 forEach)并将每个文件添加到提要中。
试试这个:
var id3 = require('id3-parser')
var fs = require('fs')
var path = require('path')
function promiseFromCallback (fn) {
return new Promise(function (resolve, reject) {
return fn(function (err, result) {
return err ? reject(err) : resolve(result)
})
})
}
function dirID3 (directory) {
return promiseFromCallback(function (gotDir) {
return fs.readdir(directory, gotDir)
}).then(function (files) {
return Promise.all(files.map(function (file) {
var filePath = path.join(directory, file)
return promiseFromCallback(function (gotStat) {
return fs.stat(filePath, gotStat)
}).then(function (stat) {
return stat.isFile() ? promiseFromCallback(function (gotBuffer) {
return fs.readFile(filePath, gotBuffer)
}).then(function (fbuff) {
return id3.parse(fbuff)
}).then(function (tag) {
return { path: filePath, tag: tag }
}) : null
})
}))
}).then(function (id3Items) {
var result = {}
id3Items.forEach(function (id3Item) {
if (id3Item) result[id3Item.path] = id3Item.tag
})
return result
})
}
然后像这样使用它:
dirID3('podcasts').then(function (dirInfo) {
console.log('ID3 info for directory', dirInfo)
})
我有一个充满 mp3 的文件夹,我想使用 id3-parser npm 模块对其进行解析,以便我可以 return 一个 rss 提要。 id3-parser 文档说要使用这个结构:
id3.parse(filebuffer).then(function(tag){
console.log(tag.title);
});
id3-parser 模块使用了 promise-a-plus 模块。我的代码的问题是标签是在堆栈的最后读取的。这是我的测试代码:
var id3 = require('id3-parser');
var fs = require('fs');
fs.readdir("podcasts", function (err, files) {
files.forEach( function (file) {
var stats = fs.statSync("podcasts/" + file);
if (stats.isFile()) {
var fbuff = fs.readFileSync("podcasts/" + file);
id3.parse(fbuff).then( function (tag) {
console.log("***"+tag.title);
});
console.log("Parsed id3 tag " + file);
}
console.log("Done file");
});
console.log("Done readdir");
});
输出为:
Parsed id3 tag test.mp3
Done file
Done readdir
***Title tag
我一辈子都想不出如何正确地等待标签被解析。解析应该在我将它放入 rss 提要之前进行(使用 rss 模块创建 xml 提要没有问题——代码未显示)。我一直在阅读有关承诺的信息,但我遗漏了一些东西。我确定我只需要完全重构我的代码,但不确定如何读取每个文件(目前使用 readdir 和 forEach)并将每个文件添加到提要中。
试试这个:
var id3 = require('id3-parser')
var fs = require('fs')
var path = require('path')
function promiseFromCallback (fn) {
return new Promise(function (resolve, reject) {
return fn(function (err, result) {
return err ? reject(err) : resolve(result)
})
})
}
function dirID3 (directory) {
return promiseFromCallback(function (gotDir) {
return fs.readdir(directory, gotDir)
}).then(function (files) {
return Promise.all(files.map(function (file) {
var filePath = path.join(directory, file)
return promiseFromCallback(function (gotStat) {
return fs.stat(filePath, gotStat)
}).then(function (stat) {
return stat.isFile() ? promiseFromCallback(function (gotBuffer) {
return fs.readFile(filePath, gotBuffer)
}).then(function (fbuff) {
return id3.parse(fbuff)
}).then(function (tag) {
return { path: filePath, tag: tag }
}) : null
})
}))
}).then(function (id3Items) {
var result = {}
id3Items.forEach(function (id3Item) {
if (id3Item) result[id3Item.path] = id3Item.tag
})
return result
})
}
然后像这样使用它:
dirID3('podcasts').then(function (dirInfo) {
console.log('ID3 info for directory', dirInfo)
})