使用YoutubeExplod下载YouTube MP3时如何判断IProgress进度达100%
原提问内容
我需要在我的软件中将YouTube视频下载为MP3格式。为此我使用了 YoutubeExplode 库。下载方法中有一个可选参数 IProgress(附方法参数定义截图)。
但我此前从未接触过IProgress,因此想咨询:如何判断IProgress的值达到了100%?
现有代码如下:
var youtube = new YoutubeClient(); var streamManifest = await youtube.Videos.Streams.GetManifestAsync(ytURL); var streamInfo = streamManifest.GetAudioOnly().WithHighestBitrate(); if (streamInfo != null) { // Download the stream to file await youtube.Videos.Streams.DownloadAsync(streamInfo, Utilities.songPath + @"\" + songNameWithArtist + ".mp3", cancellationToken:cancelDownload); }
解答
该库的DownloadAsync方法的进度参数实际接收IProgress<double>类型,回调传入的浮点数范围为01,对应0%100%的完成比例,数值为1时即代表进度达到100%。
不需要自行实现IProgress接口,直接使用.NET内置的Progress<double>类即可完成进度接收,该类会自动处理跨线程的UI更新同步,适配WinForm、WPF等带界面的项目。
调整后的可直接运行的代码
var youtube = new YoutubeClient(); var streamManifest = await youtube.Videos.Streams.GetManifestAsync(ytURL); var streamInfo = streamManifest.GetAudioOnly().WithHighestBitrate(); if (streamInfo != null) { // 初始化进度接收对象 var downloadProgress = new Progress<double>(); // 绑定进度变化触发的逻辑 downloadProgress.ProgressChanged += (_, currentRate) => { // 将0~1的比例转换为直观的百分比显示 var percent = currentRate * 100; // 可在此处更新UI进度条等元素 Console.WriteLine($"当前下载进度:{percent:0.#}%"); // 浮点数存在精度误差,判断100%时需用极小差值范围匹配,避免永远触发不到判断 if (Math.Abs(currentRate - 1) < 0.0001) { Console.WriteLine("下载已达100%"); // 此处可写入100%完成后的业务逻辑 } }; // 下载流到本地文件 await youtube.Videos.Streams.DownloadAsync( streamInfo, Utilities.songPath + @"\" + songNameWithArtist + ".mp3", progress: downloadProgress, cancellationToken: cancelDownload ); // 更稳妥的100%判断位置:当前await代码执行完成且未抛出异常时,即代表下载完整结束 // 因为进度回调是实时推送的,偶发的精度问题可能导致回调端判断不到100%,但方法本身的完成状态是确定的 Console.WriteLine("下载流程执行完毕"); }
注意事项
- 不要直接用
currentRate == 1判断是否到100%,受浮点数精度影响,实际推送的数值可能是0.9999999这类近似值,直接做等值判断会永远触发不了100%的逻辑。 - 如果在进度回调里需要更新UI,不需要额外编写线程切换逻辑,
Progress<T>会自动将回调投递到创建该实例时所在的同步上下文,避免跨线程操作UI的报错。 - 如果下载过程中触发了取消令牌,方法会抛出
OperationCanceledException,不会走到后续的完成逻辑,也不会推送100%的进度值。
内容的提问来源于stack exchange,提问作者ProgramerRightNow
相关产品推荐
相关产品推荐

