node-ytdl-core承诺音频标题和文件下载

时间:2017-05-30 16:21:44

标签: javascript node.js

我对承诺相对较新,而且在使用node-ytdl-core时我遇到了两件事情。

 exports.downloadMP3 = function(bot, msg, sSuffix) {
    return Promise
    .all([
        ytdl(sSuffix, {filter : 'audioonly',}).pipe(fs.createWriteStream('audio.mp3')),
        promiseTitle(sSuffix)
    ])
    .then(function(results) {msg.channel.sendFile('audio.mp3', results[1], '', '')})
    .catch(error => console.error(error));
}

function promiseTitle(sSuffix) {
    return new Promise(function (resolve, reject) {
        ytdl.getInfo(sSuffix, function(err, info) {
            if (err) reject(err);
            console.log(info.title);
            return resolve(info.title);
        });
    });
}

当我使用上面的代码时,返回的标题是一个沿着a25998454d48491.V的字符串,尽管控制台记录了正确的标题。意味着承诺并没有回复我想要的价值。

此外,createWriteStream在文件发送之前没有得到解决(sendFile),这意味着我得到一个0byte文件,虽然稍微完成文件下载并且在文件系统中具有正确的大小/内容。

因此,我的问题是如何在我的承诺中返回正确的值,并将createWriteStream转换为承诺?

提前致谢。

1 个答案:

答案 0 :(得分:0)

想出来。标题很好,但sendFile()不允许' /'在文件名中。我正在测试的视频有这个角色。在下面的代码中的进一步模式我设法通过使用流事件将流的所有数据附加到数组来将ytdl流转换为缓冲区。可以使用另一个事件(结束事件)来最终发送缓冲区。

exports.downloadMP3 = function(bot, msg, sSuffix) {
    return Promise
    .all([
        promiseTitle(sSuffix)
    ])
    .then(function(results) {
        let stream = ytdl(sSuffix, {filter : 'audioonly',});
        let aData = [];

        stream.on('data', function(data) {
          aData.push(data);
        });

        stream.on('end', function() {
            let buffer = Buffer.concat(aData);
            let title = results[0].replace(/[^a-zA-Z0-9]/g,'_');
            console.log(title);
            msg.channel.sendFile(buffer, `${title}.mp3`, '', '');
        });
    })
    .catch(error => console.error(error));
}

function promiseTitle(sSuffix) {
    return new Promise(function (resolve, reject) {
        ytdl.getInfo(sSuffix, function(err, info) {
            if (err) reject(err);
            console.log(info);
            resolve(info.title);
        });
    });
}