我正在开发一个提取 YouTube 视频音频并将其保存到您的计算机的项目。
为此,我使用了来自 GitHub 的名为 YouTubeExtractor 的库。 .
我正在使用后台工作程序,以便在下载文件时使 UI 可用。这是我到目前为止的代码。
public partial class MainWindow : Window
{
private readonly BackgroundWorker worker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
worker.DoWork += worker_DoWork;
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
}
private void downloadButton_Click(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
string link;
double percentage;
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
this.Dispatcher.Invoke((Action)(() =>
{
link = videoURL.Text;
}));
/*
* Get the available video formats.
* We'll work with them in the video and audio download examples.
*/
IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(link);
/*
* We want the first extractable video with the highest audio quality.
*/
VideoInfo video = videoInfos
.Where(info => info.CanExtractAudio)
.OrderByDescending(info => info.AudioBitrate)
.First();
/*
* If the video has a decrypted signature, decipher it
*/
if (video.RequiresDecryption)
{
DownloadUrlResolver.DecryptDownloadUrl(video);
}
/*
* Create the audio downloader.
* The first argument is the video where the audio should be extracted from.
* The second argument is the path to save the audio file.
*/
var audioDownloader = new AudioDownloader(video, System.IO.Path.Combine("C:/Downloads", video.Title + video.AudioExtension));
// Register the progress events. We treat the download progress as 85% of the progress and the extraction progress only as 15% of the progress,
// because the download will take much longer than the audio extraction.
audioDownloader.DownloadProgressChanged += (send, args) => Console.WriteLine(args.ProgressPercentage * 0.85);
audioDownloader.AudioExtractionProgressChanged += (send, args) => Console.WriteLine(85 + args.ProgressPercentage * 0.15);
/*
* Execute the audio downloader.
* For GUI applications note, that this method runs synchronously.
*/
audioDownloader.Execute();
}
}
}
我的问题是我想显示这个
audioDownloader.DownloadProgressChanged += (send, args) => Console.WriteLine(args.ProgressPercentage * 0.85);
audioDownloader.AudioExtractionProgressChanged += (send, args) => Console.WriteLine(85 + args.ProgressPercentage * 0.15);
在标签或进度条等 UI 元素中,而不是 Console.WriteLine
每当我这样做
label1.Text = (85 + args.ProgressPercentage * 0.15);
它给我一个错误,比如“调用线程无法访问此对象,因为不同的线程拥有它。”
我知道您可以与代表一起解决这个问题,我需要一个关于如何解决的明确说明。
谢谢你。
最佳答案
这是使用任务和 async
执行此操作的现代方法。/await
关键词
加上 Dispatcher.BeginInvoke
的用法用于更新您的 UI。
代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using YoutubeExtractor;
namespace WpfApplication1
{
public partial class MainWindow
{
public MainWindow() {
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e) {
string videoUrl = @"https://www.youtube.com/watch?v=5aXsrYI3S6g";
await DownloadVideoAsync(videoUrl);
}
private Task DownloadVideoAsync(string url) {
return Task.Run(() => {
IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(url);
VideoInfo videoInfo = videoInfos.FirstOrDefault();
if (videoInfo != null) {
if (videoInfo.RequiresDecryption) {
DownloadUrlResolver.DecryptDownloadUrl(videoInfo);
}
string savePath =
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
Path.ChangeExtension("myVideo", videoInfo.VideoExtension));
var downloader = new VideoDownloader(videoInfo, savePath);
downloader.DownloadProgressChanged += downloader_DownloadProgressChanged;
downloader.Execute();
}
});
}
private void downloader_DownloadProgressChanged(object sender, ProgressEventArgs e) {
Dispatcher.BeginInvoke((Action) (() => {
double progressPercentage = e.ProgressPercentage;
ProgressBar1.Value = progressPercentage;
TextBox1.Text = string.Format("{0:F} %", progressPercentage);
}));
}
}
}
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350">
<Grid>
<StackPanel>
<Button Click="Button_Click" Content="Download" />
<ProgressBar x:Name="ProgressBar1"
Height="20"
Maximum="100" />
<TextBox x:Name="TextBox1" />
</StackPanel>
</Grid>
</Window>
关于c# - 向用户界面报告下载进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26446769/