我构建了一个简单的youtube下载器cli。看起来像这样(不进行任何arg解析即可简化重现):
const ytdl = require('ytdl-core');
const config = require('config');
const progressBar = require('./progressBar');
const logger = require('./logger');
const ffmpeg = require('fluent-ffmpeg');
const url = 'https://www.youtube.com/watch?v=Np8ibIagn3M';
const getInfo = async (url) => {
logger.info(`Getting metadata for ${url}`);
const response = await ytdl.getBasicInfo(url);
const info = response.videoDetails.title;
logger.info(`Title: ${info}`);
return info;
};
const getStream = async (url) => {
logger.info(`Downloading from ${url} ...`);
let allReceived = false;
return new Promise((resolve, reject) => {
const stream = ytdl(url, {
quality: 'highest',
filter: (format) => format.container === 'mp4',
})
.on('progress', (_, totalDownloaded, total) => {
if (!allReceived) {
progressBar.start(total, 0, {
mbTotal: (total / 1024 / 1024).toFixed(2),
mbValue: 0,
});
allReceived = true;
}
progressBar.increment();
progressBar.update(totalDownloaded, {
mbValue: (totalDownloaded / 1024 / 1024).toFixed(2),
});
})
.on('end', () => {
progressBar.stop();
logger.info('Successfully downloaded the stream!');
});
return resolve(stream);
});
};
const convertToMp3 = async (stream, title) => {
return new Promise((resolve, reject) => {
ffmpeg({ source: stream })
.output(`${config.get('audioDir')}/${title}.mp3`)
.audioBitrate('192k')
.run();
return resolve();
});
};
const main = async (url) => {
const info = await getInfo(url);
console.log('here 1');
const stream = await getStream(url);
console.log('here 2');
await convertToMp3(stream, info);
console.log('done');
};
main(url);
输出如下:
➜ node youtube.js
info: Getting metadata for https://www.youtube.com/watch?v=Np8ibIagn3M
info: Title: Tu boca - (Bachata Remix Dj Khalid)
here 1
info: Downloading from https://www.youtube.com/watch?v=Np8ibIagn3M ...
here 2
done
[Progress] [████████████████████████████████████████] 100% | Downloaded: 7.15/7.15 MB | Elapsed Time: 5s
info: Successfully downloaded the stream!
但是,我希望得到以下输出:
➜ node youtube.js
info: Getting metadata for https://www.youtube.com/watch?v=Np8ibIagn3M
info: Title: Tu boca - (Bachata Remix Dj Khalid)
here 1
info: Downloading from https://www.youtube.com/watch?v=Np8ibIagn3M ...
[Progress] [████████████████████████████████████████] 100% | Downloaded: 7.15/7.15 MB | Elapsed Time: 5s
here 2
info: Successfully downloaded the stream!
done
我认为我在理解异步/等待方面遇到了麻烦。据我了解,函数的赋值使我可以等待结果。但是,它似乎不起作用。我不知道为什么以及如何正确调试它。
已编辑:
const getStream = async (url) => {
logger.info(`Downloading from ${url} ...`);
let allReceived = false;
return new Promise((resolve, reject) => {
const stream = ytdl(url, {
quality: 'highest',
filter: (format) => format.container === 'mp4',
})
.on('progress', (_, totalDownloaded, total) => {
console.log('totalDownloaded: ' + totalDownloaded);
if (!allReceived) {
console.log('total: ' + total);
progressBar.start(total, 0, {
mbTotal: (total / 1024 / 1024).toFixed(2),
mbValue: 0,
});
allReceived = true;
}
progressBar.increment();
progressBar.update(totalDownloaded, {
mbValue: (totalDownloaded / 1024 / 1024).toFixed(2),
});
})
.on('end', () => {
progressBar.stop();
logger.info('Successfully downloaded the stream!');
resolve(stream);
});
});
};
但是现在是这样的:
➜ node youtube.js
info: Getting metadata for https://www.youtube.com/watch?v=Np8ibIagn3M
info: Title: Tu boca - (Bachata Remix Dj Khalid)
here 1
info: Downloading from https://www.youtube.com/watch?v=Np8ibIagn3M ...
[Progress] [██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 14% | Downloaded: 1.02/7.15 MB | Elapsed Time: 52s
添加了console.log:
totalDownloaded: 16384
total: 7493903
[Progress] [░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0% | Downloaded: 0/7.15 MB | Elapsed Time: 0stotalDownloaded: 32768
totalDownloaded: 49152
totalDownloaded: 65536
totalDownloaded: 81920
totalDownloaded: 98304
totalDownloaded: 114688
totalDownloaded: 131072
totalDownloaded: 147456
totalDownloaded: 163840
totalDownloaded: 180224
totalDownloaded: 196608
totalDownloaded: 212992
totalDownloaded: 229376
totalDownloaded: 245760
totalDownloaded: 262144
totalDownloaded: 278528
totalDownloaded: 294912
totalDownloaded: 311296
totalDownloaded: 327680
totalDownloaded: 344064
totalDownloaded: 360448
totalDownloaded: 376832
totalDownloaded: 393216
totalDownloaded: 409600
totalDownloaded: 425984
totalDownloaded: 442368
totalDownloaded: 458752
totalDownloaded: 475136
totalDownloaded: 491520
totalDownloaded: 507904
totalDownloaded: 524288
totalDownloaded: 540672
totalDownloaded: 557056
totalDownloaded: 573440
totalDownloaded: 589824
totalDownloaded: 606208
totalDownloaded: 622592
totalDownloaded: 638976
totalDownloaded: 655360
totalDownloaded: 671744
totalDownloaded: 688128
totalDownloaded: 704512
totalDownloaded: 720896
totalDownloaded: 737280
totalDownloaded: 753664
totalDownloaded: 770048
totalDownloaded: 786432
totalDownloaded: 802816
totalDownloaded: 819200
totalDownloaded: 835584
totalDownloaded: 851968
totalDownloaded: 868352
totalDownloaded: 884736
totalDownloaded: 901120
totalDownloaded: 917504
totalDownloaded: 933888
totalDownloaded: 950272
totalDownloaded: 966656
totalDownloaded: 983040
totalDownloaded: 999424
totalDownloaded: 1015808
totalDownloaded: 1032192
totalDownloaded: 1048576
totalDownloaded: 1064960
[Progress] [██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 14% | Downloaded: 1.02/7.15 MB | Elapsed Time: 25s
答案 0 :(得分:0)
您已经正确使用了Promise,但是您似乎想要一个不同的输出。这就是getStream()
内部的情况:
假设您希望事件5在4之前发生,则需要删除resolve(stream)
中的getStream()
,并将其移至on("end", {...})
回调函数的末尾,如下所示:< / p>
.on('end', () => {
progressBar.stop();
logger.info('Successfully downloaded the stream!');
resolve(stream);
});