如何解决节点js异步/等待ytdl和ffmpeg的Promise问题
我构建了一个简单的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,{
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,total) => {
console.log('totalDownloaded: ' + totalDownloaded);
if (!allReceived) {
console.log('total: ' + total);
progressBar.start(total,() => {
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
解决方法
您已经正确使用了Promise,但是您似乎想要一个不同的输出。这就是getStream()
内部的情况:
- 登录“从$ {url}下载”。
- 创建一个承诺并返回。
- 设置“进度”和“结束”的事件监听器。
- 解决承诺(并继续执行程序)
- 获取“结束”事件;运行回调函数并记录“已成功下载流!”。
假设您希望事件5在4之前发生,则需要删除resolve(stream)
中的getStream()
,并将其移至on("end",{...})
回调函数的末尾,如下所示:
.on('end',() => {
progressBar.stop();
logger.info('Successfully downloaded the stream!');
resolve(stream);
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。