【问题标题】:Need help parsing id3 tags asyncrhonously in node.js using id3-parser需要帮助使用 id3-parser 在 node.js 中异步解析 id3 标签
【发布时间】:2016-12-10 01:03:00
【问题描述】:

我有一个完整的 mp3 文件夹,我想使用 id3-parser npm 模块对其进行解析,以便我可以返回一个 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)并将每个文件添加到提要中。

【问题讨论】:

    标签: node.js asynchronous promise id3


    【解决方案1】:

    试试这个:

    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)
    })
    

    【讨论】:

    • 谢谢。试图理解您的解决方案中的所有链接然后。还没测试。
    • 哇,这正是我需要的。谢谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多