JavaScript中如何获取pipe()状态 使用ytdl-core实现YouTube下载进度展示
ytdl-core 本地计算下载进度实现方案
你不需要自己监听文件写入状态或者请求服务器,ytdl-core原生提供了progress事件可直接获取下载进度相关数据,所有计算都在本地完成,具体实现如下:
核心实现逻辑
- 不要直接链式调用
ytdl().pipe(),先把ytdl返回的可读流实例单独存储 - 监听流的
progress事件直接获取已下载字节数、总字节数,直接计算百分比即可 - 可同时监听流的
error、close事件处理下载出错、手动取消的场景
完整代码示例
const ytdl = require('ytdl-core'); const fs = require('fs'); const path = require('path'); // 配置下载参数 const videoUrl = '你的YouTube视频链接'; const savePath = path.resolve(__dirname, 'download.mp4'); // 初始化流实例 const videoStream = ytdl(videoUrl, { quality: 'highestvideo' }); const writeStream = fs.createWriteStream(savePath); // 监听进度事件 videoStream.on('progress', (chunkLength, downloadedBytes, totalBytes) => { // 计算百分比,保留2位小数 const downloadPercent = (downloadedBytes / totalBytes * 100).toFixed(2); // 此处可将进度值传入你的UI渲染逻辑 console.log(`当前进度:${downloadPercent}% | 已下载:${(downloadedBytes/1024/1024).toFixed(2)}MB | 总大小:${(totalBytes/1024/1024).toFixed(2)}MB`); }); // 监听下载完成 writeStream.on('finish', () => { console.log('下载完成'); }); // 监听下载错误 videoStream.on('error', (err) => { console.error('下载出错:', err); // 可在此处添加清理未完成文件的逻辑 }); // 监听下载取消(手动调用videoStream.destroy()会触发该事件) writeStream.on('close', () => { const { bytesWritten } = writeStream; const totalSize = videoStream.size? videoStream.size : 0; if (bytesWritten < totalSize && totalSize > 0) { console.log('下载已被手动取消'); } }); // 启动写入 videoStream.pipe(writeStream);
补充说明
- 如果需要手动取消下载,直接调用
videoStream.destroy()即可,不需要额外维护取消状态 - 若你确实需要通过文件写入状态计算进度,也可通过
writeStream.bytesWritten属性获取已写入的字节数,配合从response头中拿到的content-length计算百分比,精度和原生progress事件一致 - 所有逻辑均在本地执行,无任何额外的外部请求
内容的提问来源于stack exchange,提问作者user16028444
相关产品推荐
相关产品推荐

