C# 9 и музыка ВК

от автора

image

В 2020ом мы пользуемся разными музыкальными сервисами, но как реликт давно ушедшей эпохи, в забытом профиле ВК, у многих по прежнему хранится старая коллекция собранной когда-то музыки. Функции для загрузки нет, но что если позарез нужно спасти свою аудиозапись?
Поэтому под катом мы рассмотрим создание self-hosted утилиты для загрузки аудио, не сливающее данные профиля соцсети стороннему сервису, продемонстрировав заодно всю мощь экосистемы кроссплатформенного .NET.

Работать утилита будет так:

 dotnet vkm [login] [password] [audio-lemma]

Перво-наперво создадим репозиторий и опишем в одном файле csproj зависимости проекта

<Project Sdk="Microsoft.NET.Sdk">     <PropertyGroup>         <!--Утилита будет работать из консоли-->         <OutputType>Exe</OutputType>         <TargetFramework>netcoreapp3.1</TargetFramework>         <!--Строго запрещаем null -->         <Nullable>enable</Nullable>         <TreatWarningsAsErrors>true</TreatWarningsAsErrors>         <!--И включаем C# 9 -->         <LangVersion>9</LangVersion>     </PropertyGroup>     <ItemGroup>         <!--Зависимость от VK API без необходимости вручную получать токен-->         <PackageReference Include="VkNet" Version="1.56.0" />         <!--Доступ к своим сообщениям, комментариям и музыке-->         <PackageReference Include="VkNet.AudioBypassService" Version="1.7.0" />     </ItemGroup> </Project>

После этого с чистой совестью можно приступать к написанию кода. Нам потребуется авторизация утилиты в ВК с полным доступом к своему профилю. И как мы видим, благодаря экосистеме .NET, сделать это невероятно просто:

static class Vk {     internal static VkApi LoginToVkApi(string login, string password)     {         // Включаем доступ к своим сообщениям, комментариям и аудиозаписям         var api = new VkApi(new ServiceCollection().AddAudioBypass());         api.Authorize(new ApiAuthParams         {              ApplicationId = 1980660,             Login = login,              Password = password,              Settings = All          });         $"Login as vk.com/id{api.UserId}".Println(DarkBlue);         return api;     } }

Опишем точку входа и фильтр загружаемых аудиозаписей. Используем для этого top-level programs и прямо в файле Application.cs валидируем аргументы, одновременно инициализируя api

var vk = args.Length switch {     3 => LoginToVkApi(args[0], args[1]),     _ => throw new ArgumentException("Invalid arguments. Usage:\n" +         "  dotnet vkm [login] [password] \n" +     ) };

Приводим лемму для поиска аудиозаписи к upper-case

var lemma = args.Last().ToUpperInvariant();

И грепаем с помощью Linq все аудиозаписи с её вхождением. Отдельное спасибо хабраюзеру SuperHackerVk за способ получения mp3-ссылки регуляркой.

var audios = vk.Audio.Get(new AudioGetParams { Count = 6000 })     .Where(x => x.Title.ToUpperInvariant().Contains(lemma))     .Select(x => (x.Title, Url: Regex.Replace(         x.Url.ToString(),         @"/[a-zA-Z\d]{6,}(/.*?[a-zA-Z\d]+?)/index.m3u8()",         @"$1$2.mp3"     )));

Наконец остается только загрузить свои найденные аудио:

using var http = new HttpClient(); foreach (var (title, url) in audios) {     $"Downloading {title}...".Println(DarkBlue);     await WriteAllBytesAsync($"{title}.mp3", await http.GetByteArrayAsync(url)); }

Вот и все! Утилита написана и готова к использованию в личных целях. Заметно как C# с каждым годом все больше превращается в хороший мультитул, позволяющий решать любой спектр задач. Расширения синтаксических возможностей которые при анонсах кажутся загромождающими язык, на практике напротив, позволяют сократить код и сделать его простым и понятным.

Репозиторий на GitHub c небольшими дополнениями и документацией по запуску.

Всем удачного дня!

ссылка на оригинал статьи https://habr.com/ru/post/525346/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *