Кроссплатформенный графический интерфейс для yt-dlp, написанный на .NET, Avalonia UI и SukiUI.
Приложение помогает скачивать видео, аудио и плейлисты без ручной сборки длинных команд в терминале: пользователь вставляет ссылку, анализирует доступные параметры, добавляет задачу в очередь и запускает загрузку.
- Анализ одиночных видео и плейлистов через
yt-dlp. - Очередь загрузок с последовательной обработкой задач.
- Выбор контейнера:
MP4,MKV,WebM,MP3. - Выбор разрешения для одиночного видео только из реально доступных video-форматов
yt-dlp, включая 2K/4K, если они есть у ролика. - Для плейлистов используется быстрый
--flat-playlist, поэтому доступен режимМаксимальноебез долгого анализа каждого ролика. - Выбор ручных и автоматических субтитров, если они есть в метаданных.
- Выбор аудиодорожки, если платформа отдает языковые дорожки в форматах.
- Встраивание метаданных и обложки.
- Отмена анализа и остановка текущей загрузки.
- Светлая/темная тема.
Для запуска нужны:
- .NET SDK/Runtime под целевую версию проекта (
net10.0); yt-dlp;ffmpeg.
Приложение ищет внешние утилиты в таком порядке:
- Папка
toolsрядом с приложением. - Директория приложения.
- Системный
PATH.
Если yt-dlp или ffmpeg не найдены, интерфейс покажет предупреждение и заблокирует действия, требующие этих утилит.
dotnet runПроверка сборки:
dotnet build --no-restore- Поле URL принимает HTTP/HTTPS-ссылку на видео или плейлист.
- Кнопка
Анализироватьзапускает получение метаданных. - Во время анализа появляется индикатор загрузки и кнопка
Отменить. - Если зависимости не найдены, отображается отдельный warning-блок.
После успешного анализа показываются:
- превью;
- название, автор и длительность;
- доступные разрешения;
- контейнер;
- субтитры;
- аудиодорожка;
- опции встраивания метаданных и обложки.
Разрешения не захардкожены. Для одиночного видео список строится из массива formats, который возвращает yt-dlp. Псевдоформаты вроде storyboard/mhtml/json отфильтровываются.
Очередь показывает:
- название задачи;
- выбранные параметры;
- статус:
В очереди,Завершено,Ошибка; - прогресс, скорость и ETA для активной загрузки;
- кнопку удаления, если загрузка сейчас не выполняется.
Очередь обрабатывается последовательно. При остановке текущий процесс yt-dlp завершается через CancellationToken, а незавершенная задача возвращается в ожидание.
Проект построен вокруг MVVM:
Modelsсодержат чистые модели данных:VideoInfo,DownloadTask,DownloadOptions,DownloadProgress.Viewsсодержат Avalonia/SukiUI-разметку.ViewModelsсвязывают UI и сервисы.Servicesинкапсулируют процессы, очередь, зависимости, загрузку превью, фабрики задач и парсинг метаданных.
MainWindowViewModel разбит на partial-файлы:
MainWindowViewModel.cs— зависимости, observable-свойства и инициализация.MainWindowViewModel.Commands.cs— команды UI.MainWindowViewModel.Options.cs— заполнение списков настроек и созданиеDownloadOptions.MainWindowViewModel.State.cs— вычисляемые UI-состояния (CanAnalyze,CanStartDownload,IsQueueEmptyи т.д.).
Так основной класс остается коротким, а связанные части UI-логики лежат рядом и читаются отдельно.
ProcessRunnerзапускает внешние процессы, читает stdout/stderr и поддерживает отмену.ExternalToolResolverнаходитyt-dlpиffmpegи передает дальше абсолютные пути.YtDlpServiceстроит аргументыyt-dlp, валидирует URL/опции и запускает анализ или скачивание.DownloadQueueManagerпоследовательно обрабатывает очередь и обновляет observable-состояние через UI dispatcher.DownloadTaskFactoryсоздает задачи загрузки для одиночного видео или плейлиста.ImageLoaderзагружает превью с таймаутом, лимитом размера и проверкой типа контента.DependencyManagerпроверяет наличиеyt-dlpиffmpeg.
Парсинг метаданных вынесен в Services/Parser:
MetadataParserFactoryвыбирает парсер по_type.VideoMetadataParserразбирает одиночное видео.PlaylistMetadataParserразбирает плейлист.YtDlpFormatMetadataфильтрует реальные скачиваемые video-форматы и извлекает доступные разрешения.
В проекте учтены основные риски для GUI-обертки над внешней CLI-утилитой:
- аргументы процесса передаются через
ProcessStartInfo.ArgumentList, а не склеиваются в одну строку; ProcessRunnerтребует абсолютный путь к исполняемому файлу;- URL принимаются только со схемами
httpиhttps; - контейнеры, разрешения и языковые коды валидируются перед запуском
yt-dlp; - stderr читается вместе со stdout, чтобы процесс не зависал на заполненном буфере;
- загрузка превью ограничена 10 MB и ожидает
image/*; - сетевые операции и процессы поддерживают отмену;
- UI-коллекции обновляются через dispatcher.
- KISS: логика разбита на небольшие классы и partial-файлы без лишнего DI-фреймворка.
- SRP: процесс, очередь, парсинг, загрузка изображений и создание задач разделены.
- DIP: ViewModel зависит от интерфейсов сервисов (
IYtDlpService,IImageLoader,IDownloadTaskFactoryи других). - OCP: новые парсеры метаданных можно добавить через
IMetadataParser.
Для текущего размера проекта ручная сборка зависимостей в App.axaml.cs остается достаточно простой. Если проект будет расти, следующим шагом можно добавить полноценный DI-контейнер и read-only интерфейс очереди вместо прямой отдачи ObservableCollection.