diff --git a/src/ZonyLrcTools.Cli/Commands/UtilityCommand.cs b/src/ZonyLrcTools.Cli/Commands/UtilityCommand.cs index 335b46a..c3b0996 100644 --- a/src/ZonyLrcTools.Cli/Commands/UtilityCommand.cs +++ b/src/ZonyLrcTools.Cli/Commands/UtilityCommand.cs @@ -1,9 +1,14 @@ +using System; using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using ZonyLrcTools.Cli.Infrastructure.Exceptions; using ZonyLrcTools.Cli.Infrastructure.IO; +using ZonyLrcTools.Cli.Infrastructure.MusicDecryption; using ZonyLrcTools.Cli.Infrastructure.Threading; namespace ZonyLrcTools.Cli.Commands @@ -20,45 +25,79 @@ namespace ZonyLrcTools.Cli.Commands [Command("util", Description = "提供常用的工具类功能。")] public class UtilityCommand : ToolCommandBase { + private readonly ILogger _logger; + private readonly IMusicDecryptor _musicDecryptor; + [Required(ErrorMessage = "音乐格式为必须参数,请指定 -t 参数。")] [Option("-t|--type", CommandOptionType.SingleValue, Description = "需要转换的文件格式,参数[Ncm、Qcm]。", ShowInHelpText = true)] public SupportFileType Type { get; set; } [Required(ErrorMessage = "文件路径为必须按参数,请传入有效路径。")] - [Argument(0, "Path", "指定需要转换的音乐文件路径,支持目录和文件路径。")] - public string Path { get; set; } + [Argument(0, "FilePath", "指定需要转换的音乐文件路径,支持目录和文件路径。")] + public string FilePath { get; set; } private readonly IFileScanner _fileScanner; - public UtilityCommand(IFileScanner fileScanner) + public UtilityCommand(IFileScanner fileScanner, + ILogger logger, + IMusicDecryptor musicDecryptor) { _fileScanner = fileScanner; + _logger = logger; + _musicDecryptor = musicDecryptor; } protected override async Task OnExecuteAsync(CommandLineApplication app) { - if (Directory.Exists(Path)) + if (Directory.Exists(FilePath)) { - var files = await _fileScanner.ScanAsync(Path, new[] {"*.ncm"}); + _logger.LogInformation("开始扫描文件夹,请稍等..."); + + var files = (await _fileScanner.ScanAsync(FilePath, new[] {"*.ncm"})) + .SelectMany(f => f.FilePaths) + .ToList(); + + _logger.LogInformation($"扫描完成,共 {files.Count} 个文件,准备转换。"); var wrapTask = new WarpTask(4); - var tasks = files - .SelectMany(f => f.FilePaths) - .Select(path => wrapTask.RunAsync(() => Convert(path))); + var tasks = files.Select(path => wrapTask.RunAsync(() => Convert(path))); await Task.WhenAll(tasks); } - else if (File.Exists(Path)) + else if (File.Exists(FilePath)) { - await Convert(Path); + await Convert(FilePath); } + _logger.LogInformation("所有文件已经转换完成..."); + return 0; } private async Task Convert(string filePath) { - await Task.CompletedTask; + if (Type != SupportFileType.Ncm) + { + throw new ErrorCodeException(ErrorCodes.OnlySupportNcmFormatFile); + } + + var memoryStream = new MemoryStream(); + await using var file = File.Open(filePath, FileMode.Open); + { + var buffer = new Memory(new byte[2048]); + while (await file.ReadAsync(buffer) > 0) + { + await memoryStream.WriteAsync(buffer); + } + } + + var result = await _musicDecryptor.ConvertMusic(memoryStream.ToArray()); + var newFileName = Path.Combine(Path.GetDirectoryName(filePath), + $"{Path.GetFileNameWithoutExtension(filePath)}.{((JObject) result.ExtensionObjects["JSON"]).SelectToken("$.format").Value()}"); + + await using var musicFileStream = File.Create(newFileName); + await musicFileStream.WriteAsync(result.Data); + await musicFileStream.FlushAsync(); } } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Cli/Infrastructure/Exceptions/ErrorCodes.cs b/src/ZonyLrcTools.Cli/Infrastructure/Exceptions/ErrorCodes.cs index 7e81281..d9b9b18 100644 --- a/src/ZonyLrcTools.Cli/Infrastructure/Exceptions/ErrorCodes.cs +++ b/src/ZonyLrcTools.Cli/Infrastructure/Exceptions/ErrorCodes.cs @@ -81,6 +81,11 @@ namespace ZonyLrcTools.Cli.Infrastructure.Exceptions /// public const int HttpResponseConvertJsonFailed = 50010; + /// + /// 文本: 目前仅支持 NCM 格式的歌曲转换操作。 + /// + public const int OnlySupportNcmFormatFile = 50011; + #endregion } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Cli/Resources/error_msg.json b/src/ZonyLrcTools.Cli/Resources/error_msg.json index ccc0264..0df9598 100644 --- a/src/ZonyLrcTools.Cli/Resources/error_msg.json +++ b/src/ZonyLrcTools.Cli/Resources/error_msg.json @@ -15,6 +15,7 @@ "50007": "TagLib 标签读取器出现了预期之外的异常。", "50008": "服务接口限制,无法进行请求,请尝试使用代理服务器。", "50009": "对目标服务器执行 Http 请求失败。", - "50010": "Http 请求的结果反序列化为 Json 失败。" + "50010": "Http 请求的结果反序列化为 Json 失败。", + "50011": "目前仅支持 NCM 格式的歌曲转换操作。" } } \ No newline at end of file