基于youtube-dl:VK音乐

图片

2020年,我们将使用不同的音乐服务,但作为过去时代的遗物,在被遗忘的VK个人资料中,许多人拥有音乐。没有下载功能,但是如果您急需保存录音怎么办?

由于此类软件未在公共领域中找到,除了几个需要通过VK授权的Web服务(这不是很安全)之外,我们将考虑在现代C#中创建自托管实用程序以上传音频的过程,该过程不会将配置文件数据合并到第三方服务。



程序员工作的价值之一是简单,如果可能的话,代码的简洁性。因此,我们将粘合几个现有的库以获得所需的解决方案。

该实用程序将像这样工作:

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


首先,让我们创建一个存储库并在一个csproj文件中描述项目依赖项

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <!--    -->
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <!--  null   ,    NRE -->
        <Nullable>enable</Nullable>
        <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
        <!--  C# 9     top-level   -->
        <LangVersion>9</LangVersion>
    </PropertyGroup>
    <ItemGroup>
        <!--  VK API     -->
        <PackageReference Include="VkNet" Version="1.56.0" />
        <!--   ,   -->
        <PackageReference Include="VkNet.AudioBypassService" Version="1.7.0" />
    </ItemGroup>
</Project>


之后,凭着良知,您可以开始编写代码。我们需要VK中的实用程序授权,并具有对我们的个人资料的完全访问权限。正如我们所看到的,由于.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;
    }
}


让我们描述加载的录音的入口点和过滤器。我们为此使用顶级程序,并在初始化api时直接在Application.cs文件中验证参数

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


使引理搜索大写的音频记录

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


我们将Linq及其条目用于所有音频记录。特别感谢habrauser超级黑客一种获取带有常规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存储库,其中有少量新增内容和启动文档

祝大家有个美好的一天!



All Articles