mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-09-05 21:16:52 +00:00
Compare commits
20 Commits
Alpha.2022
...
Alpha.2022
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a1e9669843 | ||
![]() |
2b41658783 | ||
![]() |
02f82e43d3 | ||
![]() |
dbe63c390f | ||
![]() |
9f70d5d379 | ||
![]() |
8010333485 | ||
![]() |
454cd58f97 | ||
![]() |
cf8d2f8515 | ||
![]() |
4b91c3e25b | ||
![]() |
1840a10f1e | ||
![]() |
d250524208 | ||
![]() |
2c2c34f1a6 | ||
![]() |
c380fd83f6 | ||
![]() |
e12264466e | ||
![]() |
2b0b14cd7a | ||
![]() |
d1c50323b1 | ||
![]() |
e06f9eaaa9 | ||
![]() |
ed1974dfbc | ||
![]() |
ba3dd5f1bc | ||
![]() |
089559d058 |
63
.gitattributes
vendored
63
.gitattributes
vendored
@@ -1,63 +0,0 @@
|
|||||||
###############################################################################
|
|
||||||
# Set default behavior to automatically normalize line endings.
|
|
||||||
###############################################################################
|
|
||||||
* text=auto
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Set default behavior for command prompt diff.
|
|
||||||
#
|
|
||||||
# This is need for earlier builds of msysgit that does not have it on by
|
|
||||||
# default for csharp files.
|
|
||||||
# Note: This is only used by command line
|
|
||||||
###############################################################################
|
|
||||||
#*.cs diff=csharp
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Set the merge driver for project and solution files
|
|
||||||
#
|
|
||||||
# Merging from the command prompt will add diff markers to the files if there
|
|
||||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
|
||||||
# the diff markers are never inserted). Diff markers may cause the following
|
|
||||||
# file extensions to fail to load in VS. An alternative would be to treat
|
|
||||||
# these files as binary and thus will always conflict and require user
|
|
||||||
# intervention with every merge. To do so, just uncomment the entries below
|
|
||||||
###############################################################################
|
|
||||||
#*.sln merge=binary
|
|
||||||
#*.csproj merge=binary
|
|
||||||
#*.vbproj merge=binary
|
|
||||||
#*.vcxproj merge=binary
|
|
||||||
#*.vcproj merge=binary
|
|
||||||
#*.dbproj merge=binary
|
|
||||||
#*.fsproj merge=binary
|
|
||||||
#*.lsproj merge=binary
|
|
||||||
#*.wixproj merge=binary
|
|
||||||
#*.modelproj merge=binary
|
|
||||||
#*.sqlproj merge=binary
|
|
||||||
#*.wwaproj merge=binary
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# behavior for image files
|
|
||||||
#
|
|
||||||
# image files are treated as binary by default.
|
|
||||||
###############################################################################
|
|
||||||
#*.jpg binary
|
|
||||||
#*.png binary
|
|
||||||
#*.gif binary
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# diff behavior for common document formats
|
|
||||||
#
|
|
||||||
# Convert binary document formats to text before diffing them. This feature
|
|
||||||
# is only available from the command line. Turn it on by uncommenting the
|
|
||||||
# entries below.
|
|
||||||
###############################################################################
|
|
||||||
#*.doc diff=astextplain
|
|
||||||
#*.DOC diff=astextplain
|
|
||||||
#*.docx diff=astextplain
|
|
||||||
#*.DOCX diff=astextplain
|
|
||||||
#*.dot diff=astextplain
|
|
||||||
#*.DOT diff=astextplain
|
|
||||||
#*.pdf diff=astextplain
|
|
||||||
#*.PDF diff=astextplain
|
|
||||||
#*.rtf diff=astextplain
|
|
||||||
#*.RTF diff=astextplain
|
|
452
.gitignore
vendored
452
.gitignore
vendored
@@ -1,452 +0,0 @@
|
|||||||
# Created by .ignore support plugin (hsz.mobi)
|
|
||||||
### VisualStudioCode template
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
*.code-workspace
|
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
|
||||||
.history/
|
|
||||||
|
|
||||||
### VisualStudio template
|
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
|
||||||
## files generated by popular Visual Studio add-ons.
|
|
||||||
##
|
|
||||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
|
||||||
|
|
||||||
# User-specific files
|
|
||||||
*.rsuser
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
*.userosscache
|
|
||||||
*.sln.docstates
|
|
||||||
|
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
|
||||||
*.userprefs
|
|
||||||
|
|
||||||
# Mono auto generated files
|
|
||||||
mono_crash.*
|
|
||||||
|
|
||||||
# Build results
|
|
||||||
[Dd]ebug/
|
|
||||||
[Dd]ebugPublic/
|
|
||||||
[Rr]elease/
|
|
||||||
[Rr]eleases/
|
|
||||||
x64/
|
|
||||||
x86/
|
|
||||||
[Ww][Ii][Nn]32/
|
|
||||||
[Aa][Rr][Mm]/
|
|
||||||
[Aa][Rr][Mm]64/
|
|
||||||
bld/
|
|
||||||
[Bb]in/
|
|
||||||
[Oo]bj/
|
|
||||||
[Ll]og/
|
|
||||||
[Ll]ogs/
|
|
||||||
|
|
||||||
# Visual Studio 2015/2017 cache/options directory
|
|
||||||
.vs/
|
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
|
||||||
#wwwroot/
|
|
||||||
|
|
||||||
# Visual Studio 2017 auto generated files
|
|
||||||
Generated\ Files/
|
|
||||||
|
|
||||||
# MSTest test Results
|
|
||||||
[Tt]est[Rr]esult*/
|
|
||||||
[Bb]uild[Ll]og.*
|
|
||||||
|
|
||||||
# NUnit
|
|
||||||
*.VisualState.xml
|
|
||||||
TestResult.xml
|
|
||||||
nunit-*.xml
|
|
||||||
|
|
||||||
# Build Results of an ATL Project
|
|
||||||
[Dd]ebugPS/
|
|
||||||
[Rr]eleasePS/
|
|
||||||
dlldata.c
|
|
||||||
|
|
||||||
# Benchmark Results
|
|
||||||
BenchmarkDotNet.Artifacts/
|
|
||||||
|
|
||||||
# .NET Core
|
|
||||||
project.lock.json
|
|
||||||
project.fragment.lock.json
|
|
||||||
artifacts/
|
|
||||||
|
|
||||||
# ASP.NET Scaffolding
|
|
||||||
ScaffoldingReadMe.txt
|
|
||||||
|
|
||||||
# StyleCop
|
|
||||||
StyleCopReport.xml
|
|
||||||
|
|
||||||
# Files built by Visual Studio
|
|
||||||
*_i.c
|
|
||||||
*_p.c
|
|
||||||
*_h.h
|
|
||||||
*.ilk
|
|
||||||
*.meta
|
|
||||||
*.obj
|
|
||||||
*.iobj
|
|
||||||
*.pch
|
|
||||||
*.pdb
|
|
||||||
*.ipdb
|
|
||||||
*.pgc
|
|
||||||
*.pgd
|
|
||||||
*.rsp
|
|
||||||
*.sbr
|
|
||||||
*.tlb
|
|
||||||
*.tli
|
|
||||||
*.tlh
|
|
||||||
*.tmp
|
|
||||||
*.tmp_proj
|
|
||||||
*_wpftmp.csproj
|
|
||||||
*.log
|
|
||||||
*.vspscc
|
|
||||||
*.vssscc
|
|
||||||
.builds
|
|
||||||
*.pidb
|
|
||||||
*.svclog
|
|
||||||
*.scc
|
|
||||||
|
|
||||||
# Chutzpah Test files
|
|
||||||
_Chutzpah*
|
|
||||||
|
|
||||||
# Visual C++ cache files
|
|
||||||
ipch/
|
|
||||||
*.aps
|
|
||||||
*.ncb
|
|
||||||
*.opendb
|
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
|
||||||
*.cachefile
|
|
||||||
*.VC.db
|
|
||||||
*.VC.VC.opendb
|
|
||||||
|
|
||||||
# Visual Studio profiler
|
|
||||||
*.psess
|
|
||||||
*.vsp
|
|
||||||
*.vspx
|
|
||||||
*.sap
|
|
||||||
|
|
||||||
# Visual Studio Trace Files
|
|
||||||
*.e2e
|
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
|
||||||
$tf/
|
|
||||||
|
|
||||||
# Guidance Automation Toolkit
|
|
||||||
*.gpState
|
|
||||||
|
|
||||||
# ReSharper is a .NET coding add-in
|
|
||||||
_ReSharper*/
|
|
||||||
*.[Rr]e[Ss]harper
|
|
||||||
*.DotSettings.user
|
|
||||||
|
|
||||||
# TeamCity is a build add-in
|
|
||||||
_TeamCity*
|
|
||||||
|
|
||||||
# DotCover is a Code Coverage Tool
|
|
||||||
*.dotCover
|
|
||||||
|
|
||||||
# AxoCover is a Code Coverage Tool
|
|
||||||
.axoCover/*
|
|
||||||
!.axoCover/settings.json
|
|
||||||
|
|
||||||
# Coverlet is a free, cross platform Code Coverage Tool
|
|
||||||
coverage*.json
|
|
||||||
coverage*.xml
|
|
||||||
coverage*.info
|
|
||||||
|
|
||||||
# Visual Studio code coverage results
|
|
||||||
*.coverage
|
|
||||||
*.coveragexml
|
|
||||||
|
|
||||||
# NCrunch
|
|
||||||
_NCrunch_*
|
|
||||||
.*crunch*.local.xml
|
|
||||||
nCrunchTemp_*
|
|
||||||
|
|
||||||
# MightyMoose
|
|
||||||
*.mm.*
|
|
||||||
AutoTest.Net/
|
|
||||||
|
|
||||||
# Web workbench (sass)
|
|
||||||
.sass-cache/
|
|
||||||
|
|
||||||
# Installshield output folder
|
|
||||||
[Ee]xpress/
|
|
||||||
|
|
||||||
# DocProject is a documentation generator add-in
|
|
||||||
DocProject/buildhelp/
|
|
||||||
DocProject/Help/*.HxT
|
|
||||||
DocProject/Help/*.HxC
|
|
||||||
DocProject/Help/*.hhc
|
|
||||||
DocProject/Help/*.hhk
|
|
||||||
DocProject/Help/*.hhp
|
|
||||||
DocProject/Help/Html2
|
|
||||||
DocProject/Help/html
|
|
||||||
|
|
||||||
# Click-Once directory
|
|
||||||
publish/
|
|
||||||
|
|
||||||
# Publish Web Output
|
|
||||||
*.[Pp]ublish.xml
|
|
||||||
*.azurePubxml
|
|
||||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
|
||||||
# but database connection strings (with potential passwords) will be unencrypted
|
|
||||||
*.pubxml
|
|
||||||
*.publishproj
|
|
||||||
|
|
||||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
|
||||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
|
||||||
# in these scripts will be unencrypted
|
|
||||||
PublishScripts/
|
|
||||||
|
|
||||||
# NuGet Packages
|
|
||||||
*.nupkg
|
|
||||||
# NuGet Symbol Packages
|
|
||||||
*.snupkg
|
|
||||||
# The packages folder can be ignored because of Package Restore
|
|
||||||
**/[Pp]ackages/*
|
|
||||||
# except build/, which is used as an MSBuild target.
|
|
||||||
!**/[Pp]ackages/build/
|
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
|
||||||
#!**/[Pp]ackages/repositories.config
|
|
||||||
# NuGet v3's project.json files produces more ignorable files
|
|
||||||
*.nuget.props
|
|
||||||
*.nuget.targets
|
|
||||||
|
|
||||||
# Microsoft Azure Build Output
|
|
||||||
csx/
|
|
||||||
*.build.csdef
|
|
||||||
|
|
||||||
# Microsoft Azure Emulator
|
|
||||||
ecf/
|
|
||||||
rcf/
|
|
||||||
|
|
||||||
# Windows Store app package directories and files
|
|
||||||
AppPackages/
|
|
||||||
BundleArtifacts/
|
|
||||||
Package.StoreAssociation.xml
|
|
||||||
_pkginfo.txt
|
|
||||||
*.appx
|
|
||||||
*.appxbundle
|
|
||||||
*.appxupload
|
|
||||||
|
|
||||||
# Visual Studio cache files
|
|
||||||
# files ending in .cache can be ignored
|
|
||||||
*.[Cc]ache
|
|
||||||
# but keep track of directories ending in .cache
|
|
||||||
!?*.[Cc]ache/
|
|
||||||
|
|
||||||
# Others
|
|
||||||
ClientBin/
|
|
||||||
~$*
|
|
||||||
*~
|
|
||||||
*.dbmdl
|
|
||||||
*.dbproj.schemaview
|
|
||||||
*.jfm
|
|
||||||
*.pfx
|
|
||||||
*.publishsettings
|
|
||||||
orleans.codegen.cs
|
|
||||||
|
|
||||||
# Including strong name files can present a security risk
|
|
||||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
|
||||||
#*.snk
|
|
||||||
|
|
||||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
|
||||||
#bower_components/
|
|
||||||
|
|
||||||
# RIA/Silverlight projects
|
|
||||||
Generated_Code/
|
|
||||||
|
|
||||||
# Backup & report files from converting an old project file
|
|
||||||
# to a newer Visual Studio version. Backup files are not needed,
|
|
||||||
# because we have git ;-)
|
|
||||||
_UpgradeReport_Files/
|
|
||||||
Backup*/
|
|
||||||
UpgradeLog*.XML
|
|
||||||
UpgradeLog*.htm
|
|
||||||
ServiceFabricBackup/
|
|
||||||
*.rptproj.bak
|
|
||||||
|
|
||||||
# SQL Server files
|
|
||||||
*.mdf
|
|
||||||
*.ldf
|
|
||||||
*.ndf
|
|
||||||
|
|
||||||
# Business Intelligence projects
|
|
||||||
*.rdl.data
|
|
||||||
*.bim.layout
|
|
||||||
*.bim_*.settings
|
|
||||||
*.rptproj.rsuser
|
|
||||||
*- [Bb]ackup.rdl
|
|
||||||
*- [Bb]ackup ([0-9]).rdl
|
|
||||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
|
||||||
|
|
||||||
# Microsoft Fakes
|
|
||||||
FakesAssemblies/
|
|
||||||
|
|
||||||
# GhostDoc plugin setting file
|
|
||||||
*.GhostDoc.xml
|
|
||||||
|
|
||||||
# Node.js Tools for Visual Studio
|
|
||||||
.ntvs_analysis.dat
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
|
||||||
*.plg
|
|
||||||
|
|
||||||
# Visual Studio 6 workspace options file
|
|
||||||
*.opt
|
|
||||||
|
|
||||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
|
||||||
*.vbw
|
|
||||||
|
|
||||||
# Visual Studio LightSwitch build output
|
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/ModelManifest.xml
|
|
||||||
**/*.Server/GeneratedArtifacts
|
|
||||||
**/*.Server/ModelManifest.xml
|
|
||||||
_Pvt_Extensions
|
|
||||||
|
|
||||||
# Paket dependency manager
|
|
||||||
.paket/paket.exe
|
|
||||||
paket-files/
|
|
||||||
|
|
||||||
# FAKE - F# Make
|
|
||||||
.fake/
|
|
||||||
|
|
||||||
# CodeRush personal settings
|
|
||||||
.cr/personal
|
|
||||||
|
|
||||||
# Python Tools for Visual Studio (PTVS)
|
|
||||||
__pycache__/
|
|
||||||
*.pyc
|
|
||||||
|
|
||||||
# Cake - Uncomment if you are using it
|
|
||||||
# tools/**
|
|
||||||
# !tools/packages.config
|
|
||||||
|
|
||||||
# Tabs Studio
|
|
||||||
*.tss
|
|
||||||
|
|
||||||
# Telerik's JustMock configuration file
|
|
||||||
*.jmconfig
|
|
||||||
|
|
||||||
# BizTalk build output
|
|
||||||
*.btp.cs
|
|
||||||
*.btm.cs
|
|
||||||
*.odx.cs
|
|
||||||
*.xsd.cs
|
|
||||||
|
|
||||||
# OpenCover UI analysis results
|
|
||||||
OpenCover/
|
|
||||||
|
|
||||||
# Azure Stream Analytics local run output
|
|
||||||
ASALocalRun/
|
|
||||||
|
|
||||||
# MSBuild Binary and Structured Log
|
|
||||||
*.binlog
|
|
||||||
|
|
||||||
# NVidia Nsight GPU debugger configuration file
|
|
||||||
*.nvuser
|
|
||||||
|
|
||||||
# MFractors (Xamarin productivity tool) working folder
|
|
||||||
.mfractor/
|
|
||||||
|
|
||||||
# Local History for Visual Studio
|
|
||||||
.localhistory/
|
|
||||||
|
|
||||||
# BeatPulse healthcheck temp database
|
|
||||||
healthchecksdb
|
|
||||||
|
|
||||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
|
||||||
MigrationBackup/
|
|
||||||
|
|
||||||
# Ionide (cross platform F# VS Code tools) working folder
|
|
||||||
.ionide/
|
|
||||||
|
|
||||||
# Fody - auto-generated XML schema
|
|
||||||
FodyWeavers.xsd
|
|
||||||
|
|
||||||
### JetBrains template
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
.idea/
|
|
||||||
/.idea
|
|
||||||
/src/ZonyLrcTools.Cli/TempFiles/
|
|
71
README.md
71
README.md
@@ -1,4 +1,4 @@
|
|||||||
简体中文 | [English](./en_US.md)
|
简体中文 | [English](./docs/en_US.md)
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
@@ -9,11 +9,11 @@ ZonyLrcToolX 4 是一个基于 CEF 的跨平台歌词下载工具。
|
|||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
|
|
||||||
Windows 用户请在软件目录当中,按住 Shift + 右键呼出菜单,然后选择 PowerShell (部分用户可能显示的是 *命令提示符*),根据下述说明执行命令即可。
|
Windows 用户请在软件目录当中,按住 Shift + 右键呼出菜单,然后选择 PowerShell/命令提示符/Windows 终端,根据下述说明执行命令即可。
|
||||||
|
|
||||||
macOS 和 Linux 用户请打开终端,切换到软件目录,一样执行命令即可。
|
macOS 和 Linux 用户请打开终端,切换到软件目录,一样执行命令即可。
|
||||||
|
|
||||||
### 命令
|
### 子命令
|
||||||
|
|
||||||
#### 歌曲下载
|
#### 歌曲下载
|
||||||
|
|
||||||
@@ -36,6 +36,8 @@ macOS 和 Linux 用户请打开终端,切换到软件目录,一样执行命
|
|||||||
|
|
||||||
#### 加密格式转换
|
#### 加密格式转换
|
||||||
|
|
||||||
|
子命令为 `util`,可用于转换部分加密歌曲,**仅供个人研究学习使用,思路与源码都来自于网络**。
|
||||||
|
|
||||||
目前软件支持 NCM、QCM(开发中...🚧) 格式的音乐文件转换,命令如下。
|
目前软件支持 NCM、QCM(开发中...🚧) 格式的音乐文件转换,命令如下。
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -44,19 +46,56 @@ macOS 和 Linux 用户请打开终端,切换到软件目录,一样执行命
|
|||||||
|
|
||||||
### 配置文件
|
### 配置文件
|
||||||
|
|
||||||
程序的部分配置信息需要在 `appsettings.json` 进行更改,下面标注了各个配置的说明。
|
程序的所有的配置信息,都在 `config.yaml` 进行更改,下面标注了各个配置的说明。
|
||||||
|
|
||||||
| 属性 | 说明 | 示例值 |
|
```yaml
|
||||||
| ------------------------------------------------- | ------------------------------------------------------------ | ------------------------------- |
|
globalOption:
|
||||||
| ToolOption.SupportFileExtensions | 允许扫描的歌曲文件后缀名,以 `;` 号隔开多个后缀。 | `*.mp3;*.flac` |
|
# 允许扫描的歌曲文件后缀名。
|
||||||
| ToolOption.NetworkOptions.Enable | 是否启用 HTTP 网络代理服务,true 表示启用,false 表示禁用。 | false |
|
supportFileExtensions:
|
||||||
| ToolOption.NetworkOptions.ProxyIp | HTTP 网络代理服务的 IP,在 `Enable` 为 false 时会忽略该属性值。 | 127.0.0.1 |
|
- '*.mp3'
|
||||||
| ToolOption.NetworkOptions.ProxyPort | HTTP 网络代理服务的 端口,在 `Enable` 为 false 时会忽略该属性值。 | 8080 |
|
- '*.flac'
|
||||||
| TagInfoProviderOptions.FileNameRegularExpressions | 文件名 Tag 标签信息读取器使用,使用正则表达式匹配歌曲名和歌手,请使用命名分组编写正则表达式。 | (?'artist'.+)\\s-\\s(?'name'.+) |
|
- '*.wav'
|
||||||
| LyricDownloader.[n].Name | 指定歌词下载器的配置项标识,对应具体的歌词下载器。 | NetEase 或 QQ |
|
# 网络代理服务设置,仅支持 HTTP 代理。
|
||||||
| LyricDownloader.[n].Priority | 指定歌词下载器的优先级,按升序排列,如果值设置为 `-1` 则代表禁用。 | `1` |
|
networkOptions:
|
||||||
| BlockWordOptions.IsEnable | 是否启用屏蔽词词典。 | false |
|
isEnable: false # 是否启用代理。
|
||||||
| BlockWordOptions.BlockWordDictionaryFile | 屏蔽词词典的位置。 | `./BlockWords.json` |
|
ip: 127.0.0.1 # 代理服务 IP 地址。
|
||||||
|
port: 4780 # 代理服务端口号。
|
||||||
|
|
||||||
|
# 下载器的相关参数配置。
|
||||||
|
provider:
|
||||||
|
# 标签扫描器的相关参数配置。
|
||||||
|
tag:
|
||||||
|
# 支持的标签扫描器。
|
||||||
|
plugin:
|
||||||
|
- name: Taglib # 基于 Taglib 库的标签扫描器。
|
||||||
|
priority: 1 # 优先级,升序排列。
|
||||||
|
- name: FileName # 基于文件名的标签扫描器。
|
||||||
|
priority: 2
|
||||||
|
# 基于文件名扫描器的扩展参数。
|
||||||
|
extensions:
|
||||||
|
# 正则表达式,用于匹配文件名中的作者信息和歌曲信息,可根据
|
||||||
|
# 自己的需求进行调整。
|
||||||
|
regularExpressions: "(?'artist'.+)\\s-\\s(?'name'.+)"
|
||||||
|
# 歌曲标签屏蔽字典替换功能。
|
||||||
|
blockWord:
|
||||||
|
isEnable: false # 是否启用屏蔽字典。
|
||||||
|
filePath: 'BlockWords.json' # 屏蔽字典的路径。
|
||||||
|
# 歌词下载器的相关参数配置。
|
||||||
|
lyric:
|
||||||
|
# 支持的歌词下载器。
|
||||||
|
plugin:
|
||||||
|
- name: NetEase # 基于网易云音乐的歌词下载器。
|
||||||
|
priority: 1 # 优先级,升序排列。
|
||||||
|
- name: QQ # 基于 QQ 音乐的歌词下载器。
|
||||||
|
priority: 2
|
||||||
|
- name: KuGou # 基于酷狗音乐的歌词下载器。
|
||||||
|
priority: 3
|
||||||
|
# 歌词下载的一些共有配置参数。
|
||||||
|
config:
|
||||||
|
isOneLine: true # 双语歌词是否合并为一行展示。
|
||||||
|
lineBreak: '\n' # 换行符的类型。
|
||||||
|
isEnableTranslation: false # 是否启用翻译歌词。
|
||||||
|
```
|
||||||
|
|
||||||
### 屏蔽字典
|
### 屏蔽字典
|
||||||
|
|
||||||
@@ -72,7 +111,7 @@ macOS 和 Linux 用户请打开终端,切换到软件目录,一样执行命
|
|||||||
|
|
||||||
## 捐赠
|
## 捐赠
|
||||||
|
|
||||||
暂无
|
<img src="./docs/img/alipay.jpg" width="200"/><img src="./docs/img/wechat.jpg" width="200"/>
|
||||||
|
|
||||||
## 路线图
|
## 路线图
|
||||||
|
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QQ/@EntryIndexedValue">QQ</s:String>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Decryptor/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gour/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Zony/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
|
BIN
docs/img/alipay.jpg
Normal file
BIN
docs/img/alipay.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 247 KiB |
BIN
docs/img/wechat.jpg
Normal file
BIN
docs/img/wechat.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 211 KiB |
@@ -17,7 +17,7 @@ using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
|||||||
using ZonyLrcTools.Cli.Infrastructure.Tag;
|
using ZonyLrcTools.Cli.Infrastructure.Tag;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.Threading;
|
using ZonyLrcTools.Cli.Infrastructure.Threading;
|
||||||
|
|
||||||
namespace ZonyLrcTools.Cli.Commands
|
namespace ZonyLrcTools.Cli.Commands.SubCommand
|
||||||
{
|
{
|
||||||
[Command("download", Description = "下载歌词文件或专辑图像。")]
|
[Command("download", Description = "下载歌词文件或专辑图像。")]
|
||||||
public class DownloadCommand : ToolCommandBase
|
public class DownloadCommand : ToolCommandBase
|
||||||
@@ -82,7 +82,7 @@ namespace ZonyLrcTools.Cli.Commands
|
|||||||
|
|
||||||
private async Task<List<string>> ScanMusicFilesAsync()
|
private async Task<List<string>> ScanMusicFilesAsync()
|
||||||
{
|
{
|
||||||
var files = (await _fileScanner.ScanAsync(Directory, _options.SupportFileExtensions.Split(';')))
|
var files = (await _fileScanner.ScanAsync(Directory, _options.SupportFileExtensions))
|
||||||
.SelectMany(t => t.FilePaths)
|
.SelectMany(t => t.FilePaths)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@@ -103,7 +103,9 @@ namespace ZonyLrcTools.Cli.Commands
|
|||||||
|
|
||||||
var warpTask = new WarpTask(ParallelNumber);
|
var warpTask = new WarpTask(ParallelNumber);
|
||||||
var warpTaskList = files.Select(file => warpTask.RunAsync(() => Task.Run(async () => await _tagLoader.LoadTagAsync(file))));
|
var warpTaskList = files.Select(file => warpTask.RunAsync(() => Task.Run(async () => await _tagLoader.LoadTagAsync(file))));
|
||||||
var result = await Task.WhenAll(warpTaskList);
|
var result = (await Task.WhenAll(warpTaskList))
|
||||||
|
.Where(m => m != null)
|
||||||
|
.Where(m => !string.IsNullOrEmpty(m.Name) || !string.IsNullOrEmpty(m.Artist));
|
||||||
|
|
||||||
_logger.LogInformation($"已成功加载 {files.Count} 个音乐文件的标签信息。");
|
_logger.LogInformation($"已成功加载 {files.Count} 个音乐文件的标签信息。");
|
||||||
|
|
||||||
@@ -112,7 +114,7 @@ namespace ZonyLrcTools.Cli.Commands
|
|||||||
|
|
||||||
private IEnumerable<ILyricDownloader> GetLyricDownloaderList()
|
private IEnumerable<ILyricDownloader> GetLyricDownloaderList()
|
||||||
{
|
{
|
||||||
var downloader = _options.LyricDownloaderOptions
|
var downloader = _options.Provider.Lyric.Plugin
|
||||||
.Where(op => op.Priority != -1)
|
.Where(op => op.Priority != -1)
|
||||||
.OrderBy(op => op.Priority)
|
.OrderBy(op => op.Priority)
|
||||||
.Join(_lyricDownloaderList,
|
.Join(_lyricDownloaderList,
|
@@ -11,7 +11,7 @@ using ZonyLrcTools.Cli.Infrastructure.IO;
|
|||||||
using ZonyLrcTools.Cli.Infrastructure.MusicDecryption;
|
using ZonyLrcTools.Cli.Infrastructure.MusicDecryption;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.Threading;
|
using ZonyLrcTools.Cli.Infrastructure.Threading;
|
||||||
|
|
||||||
namespace ZonyLrcTools.Cli.Commands
|
namespace ZonyLrcTools.Cli.Commands.SubCommand
|
||||||
{
|
{
|
||||||
public enum SupportFileType
|
public enum SupportFileType
|
||||||
{
|
{
|
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using McMaster.Extensions.CommandLineUtils;
|
using McMaster.Extensions.CommandLineUtils;
|
||||||
|
|
||||||
|
17
src/ZonyLrcTools.Cli/Config/ProviderOption.cs
Normal file
17
src/ZonyLrcTools.Cli/Config/ProviderOption.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
||||||
|
using ZonyLrcTools.Cli.Infrastructure.Tag;
|
||||||
|
|
||||||
|
namespace ZonyLrcTools.Cli.Config;
|
||||||
|
|
||||||
|
public class ProviderOption
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 标签加载器相关的配置属性。
|
||||||
|
/// </summary>
|
||||||
|
public TagOption Tag { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 歌词下载相关的配置信息。
|
||||||
|
/// </summary>
|
||||||
|
public LyricOption Lyric { get; set; }
|
||||||
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.Network;
|
using ZonyLrcTools.Cli.Infrastructure.Network;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.Tag;
|
using ZonyLrcTools.Cli.Infrastructure.Tag;
|
||||||
@@ -8,19 +9,9 @@ namespace ZonyLrcTools.Cli.Config
|
|||||||
public class ToolOptions
|
public class ToolOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持的音乐文件后缀集合,以 ; 进行分隔。
|
/// 支持的音乐文件后缀集合。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SupportFileExtensions { get; set; }
|
public List<string> SupportFileExtensions { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 歌词下载相关的配置信息。
|
|
||||||
/// </summary>
|
|
||||||
public LyricItemCollectionOption LyricOption { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 标签加载器相关的配置属性。
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<TagInfoProviderInstance> TagInfoProviderOptions { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 网络代理相关的配置信息。
|
/// 网络代理相关的配置信息。
|
||||||
@@ -28,13 +19,8 @@ namespace ZonyLrcTools.Cli.Config
|
|||||||
public NetworkOptions NetworkOptions { get; set; }
|
public NetworkOptions NetworkOptions { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 歌词下载器相关的配置属性。
|
/// 定义下载器的相关配置信息。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<LyricDownloaderOption> LyricDownloaderOptions { get; set; }
|
public ProviderOption Provider { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 屏蔽词功能相关配置。
|
|
||||||
/// </summary>
|
|
||||||
public BlockWordOption BlockWordOptions { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -31,8 +31,8 @@ namespace ZonyLrcTools.Cli.Infrastructure.DependencyInject
|
|||||||
|
|
||||||
return new HttpClientHandler
|
return new HttpClientHandler
|
||||||
{
|
{
|
||||||
UseProxy = option.NetworkOptions.Enable,
|
UseProxy = option.NetworkOptions.IsEnable,
|
||||||
Proxy = new WebProxy($"{option.NetworkOptions.ProxyIp}:{option.NetworkOptions.ProxyPort}")
|
Proxy = new WebProxy($"{option.NetworkOptions.Ip}:{option.NetworkOptions.Port}")
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,10 +46,10 @@ namespace ZonyLrcTools.Cli.Infrastructure.DependencyInject
|
|||||||
{
|
{
|
||||||
var configuration = new ConfigurationBuilder()
|
var configuration = new ConfigurationBuilder()
|
||||||
.SetBasePath(Directory.GetCurrentDirectory())
|
.SetBasePath(Directory.GetCurrentDirectory())
|
||||||
.AddJsonFile("appsettings.json")
|
.AddYamlFile("config.yaml")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
services.Configure<ToolOptions>(configuration.GetSection("ToolOption"));
|
services.Configure<ToolOptions>(configuration.GetSection("globalOption"));
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@@ -9,8 +9,15 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
|||||||
/// 根据指定的歌曲数据构建新的 <see cref="LyricItemCollection"/> 实例。
|
/// 根据指定的歌曲数据构建新的 <see cref="LyricItemCollection"/> 实例。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sourceLyric">原始歌词数据。</param>
|
/// <param name="sourceLyric">原始歌词数据。</param>
|
||||||
/// <param name="translateLyric">翻译歌词数据。</param>
|
|
||||||
/// <returns>构建完成的 <see cref="LyricItemCollection"/> 对象。</returns>
|
/// <returns>构建完成的 <see cref="LyricItemCollection"/> 对象。</returns>
|
||||||
LyricItemCollection Build(string sourceLyric, string translateLyric = null);
|
LyricItemCollection Build(string sourceLyric);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据指定的歌曲数据构建新的 <see cref="LyricItemCollection"/> 实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceLyric">原始歌词数据。</param>
|
||||||
|
/// <param name="translationLyric">翻译歌词数据。</param>
|
||||||
|
/// <returns>构建完成的 <see cref="LyricItemCollection"/> 对象。</returns>
|
||||||
|
LyricItemCollection Build(string sourceLyric, string translationLyric);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,17 +4,13 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
|||||||
{
|
{
|
||||||
public class GetLyricAccessKeyRequest
|
public class GetLyricAccessKeyRequest
|
||||||
{
|
{
|
||||||
[JsonProperty("ver")]
|
[JsonProperty("ver")] public int UnknownParameters1 { get; }
|
||||||
public int UnknownParameters1 { get; }
|
|
||||||
|
|
||||||
[JsonProperty("man")]
|
[JsonProperty("man")] public string UnknownParameters2 { get; }
|
||||||
public string UnknownParameters2 { get; }
|
|
||||||
|
|
||||||
[JsonProperty("client")]
|
[JsonProperty("client")] public string UnknownParameters3 { get; }
|
||||||
public string UnknownParameters3 { get; }
|
|
||||||
|
|
||||||
[JsonProperty("hash")]
|
[JsonProperty("hash")] public string FileHash { get; }
|
||||||
public string FileHash { get; }
|
|
||||||
|
|
||||||
public GetLyricAccessKeyRequest(string fileHash)
|
public GetLyricAccessKeyRequest(string fileHash)
|
||||||
{
|
{
|
||||||
|
@@ -5,22 +5,17 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
|||||||
{
|
{
|
||||||
public class GetLyricAccessKeyResponse
|
public class GetLyricAccessKeyResponse
|
||||||
{
|
{
|
||||||
[JsonProperty("status")]
|
[JsonProperty("status")] public int Status { get; set; }
|
||||||
public int Status { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("errcode")]
|
[JsonProperty("errcode")] public int ErrorCode { get; set; }
|
||||||
public int ErrorCode { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("candidates")]
|
[JsonProperty("candidates")] public List<GetLyricAccessKeyDataObject> AccessKeyDataObjects { get; set; }
|
||||||
public List<GetLyricAccessKeyDataObject> AccessKeyDataObjects { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetLyricAccessKeyDataObject
|
public class GetLyricAccessKeyDataObject
|
||||||
{
|
{
|
||||||
[JsonProperty("accesskey")]
|
[JsonProperty("accesskey")] public string AccessKey { get; set; }
|
||||||
public string AccessKey { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("id")]
|
[JsonProperty("id")] public string Id { get; set; }
|
||||||
public string Id { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -6,14 +6,11 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
|||||||
{
|
{
|
||||||
public class SongSearchRequest
|
public class SongSearchRequest
|
||||||
{
|
{
|
||||||
[JsonProperty("filter")]
|
[JsonProperty("filter")] public int Filter { get; }
|
||||||
public int Filter { get; }
|
|
||||||
|
|
||||||
[JsonProperty("platform")]
|
[JsonProperty("platform")] public string Platform { get; }
|
||||||
public string Platform { get; }
|
|
||||||
|
|
||||||
[JsonProperty("keyword")]
|
[JsonProperty("keyword")] public string Keyword { get; }
|
||||||
public string Keyword { get; }
|
|
||||||
|
|
||||||
public SongSearchRequest(string musicName, string artistName)
|
public SongSearchRequest(string musicName, string artistName)
|
||||||
{
|
{
|
||||||
|
@@ -5,23 +5,18 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
|||||||
{
|
{
|
||||||
public class SongSearchResponse
|
public class SongSearchResponse
|
||||||
{
|
{
|
||||||
[JsonProperty("status")]
|
[JsonProperty("status")] public int Status { get; set; }
|
||||||
public int Status { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("data")]
|
[JsonProperty("data")] public SongSearchResponseInnerData Data { get; set; }
|
||||||
public SongSearchResponseInnerData Data { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("error_code")]
|
[JsonProperty("error_code")] public int ErrorCode { get; set; }
|
||||||
public int ErrorCode { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("error_msg")]
|
[JsonProperty("error_msg")] public string ErrorMessage { get; set; }
|
||||||
public string ErrorMessage { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SongSearchResponseInnerData
|
public class SongSearchResponseInnerData
|
||||||
{
|
{
|
||||||
[JsonProperty("lists")]
|
[JsonProperty("lists")] public List<SongSearchResponseSongDetail> List { get; set; }
|
||||||
public List<SongSearchResponseSongDetail> List { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SongSearchResponseSongDetail
|
public class SongSearchResponseSongDetail
|
||||||
|
@@ -16,9 +16,9 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsPruneMusic => Count == 0;
|
public bool IsPruneMusic => Count == 0;
|
||||||
|
|
||||||
public LyricItemCollectionOption Option { get; private set; }
|
public LyricConfigOption Option { get; private set; }
|
||||||
|
|
||||||
public LyricItemCollection(LyricItemCollectionOption option)
|
public LyricItemCollection(LyricConfigOption option)
|
||||||
{
|
{
|
||||||
Option = option;
|
Option = option;
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,6 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
|||||||
var option = left.Option;
|
var option = left.Option;
|
||||||
var newCollection = new LyricItemCollection(option);
|
var newCollection = new LyricItemCollection(option);
|
||||||
var indexDiff = left.Count - right.Count;
|
var indexDiff = left.Count - right.Count;
|
||||||
|
|
||||||
if (!option.IsOneLine)
|
if (!option.IsOneLine)
|
||||||
{
|
{
|
||||||
left.ForEach(item => newCollection.Add(item));
|
left.ForEach(item => newCollection.Add(item));
|
||||||
@@ -74,10 +73,10 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
|||||||
|
|
||||||
// 遍历未处理的歌词项,将其添加到返回集合当中。
|
// 遍历未处理的歌词项,将其添加到返回集合当中。
|
||||||
var leftWaitProcessIndex = leftMarkDict
|
var leftWaitProcessIndex = leftMarkDict
|
||||||
.Where(item => item.Value)
|
.Where(item => !item.Value)
|
||||||
.Select(pair => pair.Key);
|
.Select(pair => pair.Key);
|
||||||
var rightWaitProcessIndex = rightMarkDict
|
var rightWaitProcessIndex = rightMarkDict
|
||||||
.Where(item => item.Value)
|
.Where(item => !item.Value)
|
||||||
.Select(pair => pair.Key);
|
.Select(pair => pair.Key);
|
||||||
|
|
||||||
leftWaitProcessIndex.Foreach(index => newCollection.Add(left[index]));
|
leftWaitProcessIndex.Foreach(index => newCollection.Add(left[index]));
|
||||||
|
@@ -17,21 +17,47 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
|||||||
_options = options.Value;
|
_options = options.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LyricItemCollection Build(string sourceLyric, string translateLyric = null)
|
public LyricItemCollection Build(string sourceLyric)
|
||||||
{
|
{
|
||||||
var items = new LyricItemCollection(_options.LyricOption);
|
var lyric = new LyricItemCollection(_options.Provider.Lyric.Config);
|
||||||
if (string.IsNullOrEmpty(sourceLyric))
|
if (string.IsNullOrEmpty(sourceLyric))
|
||||||
{
|
{
|
||||||
return items;
|
return lyric;
|
||||||
}
|
}
|
||||||
|
|
||||||
var regex = new Regex(@"\[\d+:\d+.\d+\].+\n?");
|
InternalBuildLyricObject(lyric, sourceLyric);
|
||||||
foreach (Match match in regex.Matches(sourceLyric))
|
|
||||||
|
return lyric;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LyricItemCollection Build(string sourceLyric, string translationLyric)
|
||||||
{
|
{
|
||||||
items.Add(new LyricItem(match.Value));
|
var lyric = new LyricItemCollection(_options.Provider.Lyric.Config);
|
||||||
|
if (string.IsNullOrEmpty(sourceLyric))
|
||||||
|
{
|
||||||
|
return lyric;
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
lyric = InternalBuildLyricObject(lyric, sourceLyric);
|
||||||
|
|
||||||
|
if (_options.Provider.Lyric.Config.IsEnableTranslation && !string.IsNullOrEmpty(translationLyric))
|
||||||
|
{
|
||||||
|
var translatedLyric = InternalBuildLyricObject(new LyricItemCollection(_options.Provider.Lyric.Config), translationLyric);
|
||||||
|
return lyric + translatedLyric;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lyric;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LyricItemCollection InternalBuildLyricObject(LyricItemCollection lyric, string sourceText)
|
||||||
|
{
|
||||||
|
var regex = new Regex(@"\[\d+:\d+.\d+\].+\n?");
|
||||||
|
foreach (Match match in regex.Matches(sourceText))
|
||||||
|
{
|
||||||
|
lyric.Add(new LyricItem(match.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lyric;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,17 +0,0 @@
|
|||||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
|
||||||
{
|
|
||||||
public class LyricItemCollectionOption
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 双语歌词是否合并为一行。
|
|
||||||
/// </summary>
|
|
||||||
public bool IsOneLine { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 换行符格式,取值来自 <see cref="LineBreakType"/> 常量类。
|
|
||||||
/// </summary>
|
|
||||||
public string LineBreak { get; set; } = LineBreakType.Windows;
|
|
||||||
|
|
||||||
public static readonly LyricItemCollectionOption NullInstance = new();
|
|
||||||
}
|
|
||||||
}
|
|
28
src/ZonyLrcTools.Cli/Infrastructure/Lyric/LyricOption.cs
Normal file
28
src/ZonyLrcTools.Cli/Infrastructure/Lyric/LyricOption.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ZonyLrcTools.Cli.Infrastructure.Lyric;
|
||||||
|
|
||||||
|
public class LyricOption
|
||||||
|
{
|
||||||
|
public IEnumerable<LyricProviderOption> Plugin { get; set; }
|
||||||
|
|
||||||
|
public LyricConfigOption Config { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LyricConfigOption
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 双语歌词是否合并为一行。
|
||||||
|
/// </summary>
|
||||||
|
public bool IsOneLine { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 换行符格式,取值来自 <see cref="LineBreakType"/> 常量类。
|
||||||
|
/// </summary>
|
||||||
|
public string LineBreak { get; set; } = LineBreakType.Windows;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否启用歌词翻译功能。
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEnableTranslation { get; set; } = false;
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
||||||
{
|
{
|
||||||
public class LyricDownloaderOption
|
public class LyricProviderOption
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 歌词下载器的唯一标识。
|
/// 歌词下载器的唯一标识。
|
@@ -61,7 +61,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.NetEase
|
|||||||
var json = JsonConvert.DeserializeObject<GetLyricResponse>(Encoding.UTF8.GetString(data));
|
var json = JsonConvert.DeserializeObject<GetLyricResponse>(Encoding.UTF8.GetString(data));
|
||||||
if (json?.OriginalLyric == null)
|
if (json?.OriginalLyric == null)
|
||||||
{
|
{
|
||||||
return new LyricItemCollection(LyricItemCollectionOption.NullInstance);
|
return new LyricItemCollection(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.OriginalLyric.Text.Contains("纯音乐,请欣赏"))
|
if (json.OriginalLyric.Text.Contains("纯音乐,请欣赏"))
|
||||||
@@ -71,7 +71,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.NetEase
|
|||||||
|
|
||||||
return _lyricItemCollectionFactory.Build(
|
return _lyricItemCollectionFactory.Build(
|
||||||
json.OriginalLyric.Text,
|
json.OriginalLyric.Text,
|
||||||
json.TranslationLyric?.Text);
|
json.TranslationLyric.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricDownloaderArgs args)
|
protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricDownloaderArgs args)
|
||||||
|
@@ -6,70 +6,32 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic.JsonModel
|
|||||||
{
|
{
|
||||||
public class SongSearchRequest
|
public class SongSearchRequest
|
||||||
{
|
{
|
||||||
[JsonProperty("ct")] public int UnknownParameter1 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("qqmusic_ver")] public int ClientVersion { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("new_json")] public int UnknownParameter2 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("remoteplace")] public string RemotePlace { get; set; }
|
[JsonProperty("remoteplace")] public string RemotePlace { get; set; }
|
||||||
|
|
||||||
[JsonProperty("t")] public int UnknownParameter3 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("aggr")] public int UnknownParameter4 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("cr")] public int UnknownParameter5 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("catZhida")] public int UnknownParameter6 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("lossless")] public int LossLess { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("flag_qc")] public int UnknownParameter7 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("p")] public int Page { get; set; }
|
[JsonProperty("p")] public int Page { get; set; }
|
||||||
|
|
||||||
[JsonProperty("n")] public int Limit { get; set; }
|
[JsonProperty("n")] public int Limit { get; set; }
|
||||||
|
|
||||||
[JsonProperty("w")] public string Keyword { get; set; }
|
[JsonProperty("w")] public string Keyword { get; set; }
|
||||||
|
|
||||||
[JsonProperty("g_tk")] public int UnknownParameter8 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("hostUin")] public int UnknownParameter9 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("format")] public string ResultFormat { get; set; }
|
[JsonProperty("format")] public string ResultFormat { get; set; }
|
||||||
|
|
||||||
[JsonProperty("inCharset")] public string InCharset { get; set; }
|
[JsonProperty("inCharset")] public string InCharset { get; set; }
|
||||||
|
|
||||||
[JsonProperty("outCharset")] public string OutCharset { get; set; }
|
[JsonProperty("outCharset")] public string OutCharset { get; set; }
|
||||||
|
|
||||||
[JsonProperty("notice")] public int UnknownParameter10 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("platform")] public string Platform { get; set; }
|
[JsonProperty("platform")] public string Platform { get; set; }
|
||||||
|
|
||||||
[JsonProperty("needNewCode")] public int UnknownParameter11 { get; set; }
|
|
||||||
|
|
||||||
protected SongSearchRequest()
|
protected SongSearchRequest()
|
||||||
{
|
{
|
||||||
UnknownParameter1 = 24;
|
|
||||||
ClientVersion = 1298;
|
|
||||||
UnknownParameter2 = 1;
|
|
||||||
RemotePlace = "txt.yqq.song";
|
RemotePlace = "txt.yqq.song";
|
||||||
UnknownParameter3 = 0;
|
|
||||||
UnknownParameter4 = 1;
|
|
||||||
UnknownParameter5 = 1;
|
|
||||||
UnknownParameter6 = 1;
|
|
||||||
LossLess = 0;
|
|
||||||
UnknownParameter7 = 0;
|
|
||||||
Page = 1;
|
Page = 1;
|
||||||
Limit = 5;
|
Limit = 5;
|
||||||
UnknownParameter8 = 5381;
|
|
||||||
UnknownParameter9 = 0;
|
|
||||||
ResultFormat = "json";
|
ResultFormat = "json";
|
||||||
InCharset = "utf8";
|
InCharset = "utf8";
|
||||||
OutCharset = "utf8";
|
OutCharset = "utf8";
|
||||||
UnknownParameter10 = 0;
|
|
||||||
Platform = "yqq";
|
Platform = "yqq";
|
||||||
UnknownParameter11 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SongSearchRequest(string musicName, string artistName) : this()
|
public SongSearchRequest(string musicName, string artistName) : this()
|
||||||
|
@@ -22,11 +22,6 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic.JsonModel
|
|||||||
|
|
||||||
public class QQMusicInnerSongItem
|
public class QQMusicInnerSongItem
|
||||||
{
|
{
|
||||||
[JsonProperty("mid")] public string SongId { get; set; }
|
[JsonProperty("songmid")] public string SongId { get; set; }
|
||||||
}
|
|
||||||
|
|
||||||
public class AlbumInfo
|
|
||||||
{
|
|
||||||
[JsonProperty("id")] public long Id { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -8,16 +8,16 @@ namespace ZonyLrcTools.Cli.Infrastructure.Network
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否启用了网络代理功能。
|
/// 是否启用了网络代理功能。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enable { get; set; }
|
public bool IsEnable { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 代理服务器的 Ip。
|
/// 代理服务器的 Ip。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ProxyIp { get; set; }
|
public string Ip { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 代理服务器的 端口。
|
/// 代理服务器的 端口。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ProxyPort { get; set; }
|
public int Port { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -21,7 +21,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
|||||||
|
|
||||||
_wordsDictionary = new Lazy<Dictionary<string, string>>(() =>
|
_wordsDictionary = new Lazy<Dictionary<string, string>>(() =>
|
||||||
{
|
{
|
||||||
var jsonData = File.ReadAllText(_options.BlockWordOptions.BlockWordDictionaryFile);
|
var jsonData = File.ReadAllText(_options.Provider.Tag.BlockWord.FilePath);
|
||||||
return JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonData);
|
return JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,6 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 屏蔽词字典文件,用于替换歌曲名或者歌手名称。
|
/// 屏蔽词字典文件,用于替换歌曲名或者歌手名称。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BlockWordDictionaryFile { get; set; }
|
public string FilePath { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using ZonyLrcTools.Cli.Config;
|
using ZonyLrcTools.Cli.Config;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.DependencyInject;
|
using ZonyLrcTools.Cli.Infrastructure.DependencyInject;
|
||||||
@@ -15,14 +16,18 @@ namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
|||||||
{
|
{
|
||||||
protected readonly IEnumerable<ITagInfoProvider> TagInfoProviders;
|
protected readonly IEnumerable<ITagInfoProvider> TagInfoProviders;
|
||||||
protected readonly IBlockWordDictionary BlockWordDictionary;
|
protected readonly IBlockWordDictionary BlockWordDictionary;
|
||||||
|
protected readonly ILogger<DefaultTagLoader> _logger;
|
||||||
|
|
||||||
protected ToolOptions Options;
|
protected ToolOptions Options;
|
||||||
|
|
||||||
public DefaultTagLoader(IEnumerable<ITagInfoProvider> tagInfoProviders,
|
public DefaultTagLoader(IEnumerable<ITagInfoProvider> tagInfoProviders,
|
||||||
IBlockWordDictionary blockWordDictionary,
|
IBlockWordDictionary blockWordDictionary,
|
||||||
IOptions<ToolOptions> options)
|
IOptions<ToolOptions> options,
|
||||||
|
ILogger<DefaultTagLoader> logger)
|
||||||
{
|
{
|
||||||
TagInfoProviders = tagInfoProviders;
|
TagInfoProviders = tagInfoProviders;
|
||||||
BlockWordDictionary = blockWordDictionary;
|
BlockWordDictionary = blockWordDictionary;
|
||||||
|
_logger = logger;
|
||||||
Options = options.Value;
|
Options = options.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,12 +48,14 @@ namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.LogWarning($"{filePath} 没有找到正确的标签信息,请考虑调整正则表达式。");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void HandleBlockWord(MusicInfo info)
|
protected void HandleBlockWord(MusicInfo info)
|
||||||
{
|
{
|
||||||
if (Options.BlockWordOptions.IsEnable)
|
if (Options.Provider.Tag.BlockWord.IsEnable)
|
||||||
{
|
{
|
||||||
info.Name = BlockWordDictionary.GetValue(info.Name) ?? info.Name;
|
info.Name = BlockWordDictionary.GetValue(info.Name) ?? info.Name;
|
||||||
info.Artist = BlockWordDictionary.GetValue(info.Name) ?? info.Artist;
|
info.Artist = BlockWordDictionary.GetValue(info.Name) ?? info.Artist;
|
||||||
|
@@ -15,7 +15,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
|||||||
{
|
{
|
||||||
public string Name => ConstantName;
|
public string Name => ConstantName;
|
||||||
public const string ConstantName = "FileName";
|
public const string ConstantName = "FileName";
|
||||||
public const string RegularExpressionsOption = "RegularExpressions";
|
public const string RegularExpressionsOption = "regularExpressions";
|
||||||
|
|
||||||
private readonly ToolOptions _options;
|
private readonly ToolOptions _options;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
|||||||
{
|
{
|
||||||
await ValueTask.CompletedTask;
|
await ValueTask.CompletedTask;
|
||||||
|
|
||||||
var regex = _options.TagInfoProviderOptions
|
var regex = _options.Provider.Tag.Plugin
|
||||||
.First(t => t.Name == ConstantName)
|
.First(t => t.Name == ConstantName)
|
||||||
.Extensions[RegularExpressionsOption];
|
.Extensions[RegularExpressionsOption];
|
||||||
|
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
||||||
{
|
{
|
||||||
public class TagInfoProviderInstance
|
public class TagInfoProviderOption
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
@@ -10,4 +11,14 @@ namespace ZonyLrcTools.Cli.Infrastructure.Tag
|
|||||||
|
|
||||||
public Dictionary<string, string> Extensions { get; set; }
|
public Dictionary<string, string> Extensions { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TagOption
|
||||||
|
{
|
||||||
|
public IEnumerable<TagInfoProviderOption> Plugin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 屏蔽词功能相关配置。
|
||||||
|
/// </summary>
|
||||||
|
public BlockWordOption BlockWord { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using McMaster.Extensions.CommandLineUtils;
|
using McMaster.Extensions.CommandLineUtils;
|
||||||
@@ -8,15 +7,17 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
using ZonyLrcTools.Cli.Commands;
|
||||||
|
using ZonyLrcTools.Cli.Commands.SubCommand;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.DependencyInject;
|
using ZonyLrcTools.Cli.Infrastructure.DependencyInject;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.Exceptions;
|
using ZonyLrcTools.Cli.Infrastructure.Exceptions;
|
||||||
|
|
||||||
namespace ZonyLrcTools.Cli.Commands
|
namespace ZonyLrcTools.Cli
|
||||||
{
|
{
|
||||||
[Command("lyric-tool")]
|
[Command("lyric-tool")]
|
||||||
[Subcommand(typeof(DownloadCommand),
|
[Subcommand(typeof(DownloadCommand),
|
||||||
typeof(UtilityCommand))]
|
typeof(UtilityCommand))]
|
||||||
public class ToolCommand : ToolCommandBase
|
public class Program : ToolCommandBase
|
||||||
{
|
{
|
||||||
public static async Task<int> Main(string[] args)
|
public static async Task<int> Main(string[] args)
|
||||||
{
|
{
|
||||||
@@ -74,16 +75,16 @@ namespace ZonyLrcTools.Cli.Commands
|
|||||||
{
|
{
|
||||||
builder
|
builder
|
||||||
.SetBasePath(Directory.GetCurrentDirectory())
|
.SetBasePath(Directory.GetCurrentDirectory())
|
||||||
.AddJsonFile("appsettings.json");
|
.AddYamlFile("config.yaml");
|
||||||
})
|
})
|
||||||
.ConfigureServices((_, services) =>
|
.ConfigureServices((_, services) =>
|
||||||
{
|
{
|
||||||
services.AddSingleton(PhysicalConsole.Singleton);
|
services.AddSingleton(PhysicalConsole.Singleton);
|
||||||
services.BeginAutoDependencyInject<ToolCommand>();
|
services.BeginAutoDependencyInject<Program>();
|
||||||
services.ConfigureConfiguration();
|
services.ConfigureConfiguration();
|
||||||
services.ConfigureToolService();
|
services.ConfigureToolService();
|
||||||
})
|
})
|
||||||
.RunCommandLineApplicationAsync<ToolCommand>(args);
|
.RunCommandLineApplicationAsync<Program>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int HandleException(Exception ex)
|
private static int HandleException(Exception ex)
|
@@ -6,14 +6,15 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.0" />
|
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.1" />
|
||||||
<PackageReference Include="McMaster.Extensions.Hosting.CommandLine" Version="4.0.0" />
|
<PackageReference Include="McMaster.Extensions.Hosting.CommandLine" Version="4.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||||
|
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.2.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="Refit" Version="6.1.15" />
|
<PackageReference Include="Refit" Version="6.3.2" />
|
||||||
<PackageReference Include="Refit.HttpClientFactory" Version="6.1.15" />
|
<PackageReference Include="Refit.HttpClientFactory" Version="6.3.2" />
|
||||||
<PackageReference Include="Refit.Newtonsoft.Json" Version="6.1.15" />
|
<PackageReference Include="Refit.Newtonsoft.Json" Version="6.3.2" />
|
||||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.0" />
|
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
|
||||||
@@ -23,9 +24,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="appsettings.json" />
|
<None Remove="appsettings.json" />
|
||||||
<Content Include="appsettings.json">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<None Remove="Resources\error_msg.json" />
|
<None Remove="Resources\error_msg.json" />
|
||||||
<Content Include="Resources\error_msg.json">
|
<Content Include="Resources\error_msg.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
@@ -34,6 +32,10 @@
|
|||||||
<Content Include="BlockWords.json">
|
<Content Include="BlockWords.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<None Remove="config.yaml" />
|
||||||
|
<Content Include="config.yaml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Debug",
|
|
||||||
"System": "Information",
|
|
||||||
"Microsoft": "Information"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ToolOption": {
|
|
||||||
"SupportFileExtensions": "*.mp3;*.flac;*.wav",
|
|
||||||
"NetworkOptions": {
|
|
||||||
"Enable": false,
|
|
||||||
"ProxyIp": "127.0.0.1",
|
|
||||||
"ProxyPort": 4780
|
|
||||||
},
|
|
||||||
"TagInfoProviderOptions": [
|
|
||||||
{
|
|
||||||
"Name": "Taglib",
|
|
||||||
"Priority": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "FileName",
|
|
||||||
"Priority": 2,
|
|
||||||
"Extensions": {
|
|
||||||
"RegularExpressions": "(?'artist'.+)\\s-\\s(?'name'.+)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"LyricDownloaderOptions": [
|
|
||||||
{
|
|
||||||
"Name": "NetEase",
|
|
||||||
"Priority": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "QQ",
|
|
||||||
"Priority": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "KuGou",
|
|
||||||
"Priority": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"LyricOption": {
|
|
||||||
"IsOneLine": true,
|
|
||||||
"LineBreak": "\n"
|
|
||||||
},
|
|
||||||
"BlockWordOptions": {
|
|
||||||
"IsEnable": false,
|
|
||||||
"BlockWordDictionaryFile": "BlockWords.json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
46
src/ZonyLrcTools.Cli/config.yaml
Normal file
46
src/ZonyLrcTools.Cli/config.yaml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
globalOption:
|
||||||
|
# 允许扫描的歌曲文件后缀名。
|
||||||
|
supportFileExtensions:
|
||||||
|
- '*.mp3'
|
||||||
|
- '*.flac'
|
||||||
|
- '*.wav'
|
||||||
|
# 网络代理服务设置,仅支持 HTTP 代理。
|
||||||
|
networkOptions:
|
||||||
|
isEnable: false # 是否启用代理。
|
||||||
|
ip: 127.0.0.1 # 代理服务 IP 地址。
|
||||||
|
port: 4780 # 代理服务端口号。
|
||||||
|
|
||||||
|
# 下载器的相关参数配置。
|
||||||
|
provider:
|
||||||
|
# 标签扫描器的相关参数配置。
|
||||||
|
tag:
|
||||||
|
# 支持的标签扫描器。
|
||||||
|
plugin:
|
||||||
|
- name: Taglib # 基于 Taglib 库的标签扫描器。
|
||||||
|
priority: 1 # 优先级,升序排列。
|
||||||
|
- name: FileName # 基于文件名的标签扫描器。
|
||||||
|
priority: 2
|
||||||
|
# 基于文件名扫描器的扩展参数。
|
||||||
|
extensions:
|
||||||
|
# 正则表达式,用于匹配文件名中的作者信息和歌曲信息,可根据
|
||||||
|
# 自己的需求进行调整。
|
||||||
|
regularExpressions: "(?'artist'.+)\\s-\\s(?'name'.+)"
|
||||||
|
# 歌曲标签屏蔽字典替换功能。
|
||||||
|
blockWord:
|
||||||
|
isEnable: false # 是否启用屏蔽字典。
|
||||||
|
filePath: 'BlockWords.json' # 屏蔽字典的路径。
|
||||||
|
# 歌词下载器的相关参数配置。
|
||||||
|
lyric:
|
||||||
|
# 支持的歌词下载器。
|
||||||
|
plugin:
|
||||||
|
- name: NetEase # 基于网易云音乐的歌词下载器。
|
||||||
|
priority: 1 # 优先级,升序排列。
|
||||||
|
- name: QQ # 基于 QQ 音乐的歌词下载器。
|
||||||
|
priority: 2
|
||||||
|
- name: KuGou # 基于酷狗音乐的歌词下载器。
|
||||||
|
priority: 3
|
||||||
|
# 歌词下载的一些共有配置参数。
|
||||||
|
config:
|
||||||
|
isOneLine: true # 双语歌词是否合并为一行展示。
|
||||||
|
lineBreak: "\n" # 换行符的类型,记得使用双引号指定。
|
||||||
|
isEnableTranslation: true # 是否启用翻译歌词。
|
@@ -15,7 +15,8 @@ namespace ZonyLrcTools.Tests
|
|||||||
public async Task ScanAsync_Test()
|
public async Task ScanAsync_Test()
|
||||||
{
|
{
|
||||||
var tempMusicFilePath = Path.Combine(Directory.GetCurrentDirectory(), "Temp.mp3");
|
var tempMusicFilePath = Path.Combine(Directory.GetCurrentDirectory(), "Temp.mp3");
|
||||||
File.Create(tempMusicFilePath);
|
var fs = File.Create(tempMusicFilePath);
|
||||||
|
fs.Close();
|
||||||
|
|
||||||
var fileScanner = ServiceProvider.GetRequiredService<IFileScanner>();
|
var fileScanner = ServiceProvider.GetRequiredService<IFileScanner>();
|
||||||
var result = await fileScanner.ScanAsync(
|
var result = await fileScanner.ScanAsync(
|
||||||
|
@@ -12,7 +12,7 @@ namespace ZonyLrcTools.Tests.Infrastructure.Exceptions
|
|||||||
ErrorCodeHelper.LoadErrorMessage();
|
ErrorCodeHelper.LoadErrorMessage();
|
||||||
|
|
||||||
ErrorCodeHelper.ErrorMessages.ShouldNotBeNull();
|
ErrorCodeHelper.ErrorMessages.ShouldNotBeNull();
|
||||||
ErrorCodeHelper.ErrorMessages.Count.ShouldBe(11);
|
ErrorCodeHelper.ErrorMessages.Count.ShouldBe(15);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@@ -9,7 +9,7 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyric
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void LyricCollectionLineBreak_Test()
|
public void LyricCollectionLineBreak_Test()
|
||||||
{
|
{
|
||||||
var lyricObject = new LyricItemCollection(new LyricItemCollectionOption
|
var lyricObject = new LyricItemCollection(new LyricConfigOption
|
||||||
{
|
{
|
||||||
IsOneLine = false,
|
IsOneLine = false,
|
||||||
LineBreak = LineBreakType.MacOs
|
LineBreak = LineBreakType.MacOs
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
||||||
@@ -42,5 +41,33 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyric
|
|||||||
lyric.ShouldNotBeNull();
|
lyric.ShouldNotBeNull();
|
||||||
lyric.IsPruneMusic.ShouldBe(true);
|
lyric.IsPruneMusic.ShouldBe(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DownloadAsync_Issue84_Test()
|
||||||
|
{
|
||||||
|
var lyric = await _lyricDownloader.DownloadAsync("太空彈", "01");
|
||||||
|
lyric.ShouldNotBeNull();
|
||||||
|
lyric.IsPruneMusic.ShouldBe(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// About the new feature mentioned in issue #87.
|
||||||
|
// Github Issue: https://github.com/real-zony/ZonyLrcToolsX/issues/87
|
||||||
|
[Fact]
|
||||||
|
public async Task DownloadAsync_Issue85_Test()
|
||||||
|
{
|
||||||
|
var lyric = await _lyricDownloader.DownloadAsync("Looking at Me", "Sabrina Carpenter");
|
||||||
|
|
||||||
|
lyric.ShouldNotBeNull();
|
||||||
|
lyric.IsPruneMusic.ShouldBeFalse();
|
||||||
|
lyric.ToString().ShouldContain("你看起来失了呼吸");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DownloaderAsync_Issue88_Test()
|
||||||
|
{
|
||||||
|
var lyric = await _lyricDownloader.DownloadAsync("茫茫草原", "姚璎格");
|
||||||
|
|
||||||
|
lyric.ShouldNotBeNull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -21,9 +21,21 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyric
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task DownloadAsync_Test()
|
public async Task DownloadAsync_Test()
|
||||||
{
|
{
|
||||||
var lyric = await _lyricDownloader.DownloadAsync("Hollow", "Janet Leon");
|
var lyric = await _lyricDownloader.DownloadAsync("东风破", "周杰伦");
|
||||||
lyric.ShouldNotBeNull();
|
lyric.ShouldNotBeNull();
|
||||||
lyric.IsPruneMusic.ShouldBe(false);
|
lyric.IsPruneMusic.ShouldBe(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// About the new feature mentioned in issue #87.
|
||||||
|
// Github Issue: https://github.com/real-zony/ZonyLrcToolsX/issues/87
|
||||||
|
[Fact]
|
||||||
|
public async Task DownloadAsync_Issue85_Test()
|
||||||
|
{
|
||||||
|
var lyric = await _lyricDownloader.DownloadAsync("Looking at Me", "Sabrina Carpenter");
|
||||||
|
|
||||||
|
lyric.ShouldNotBeNull();
|
||||||
|
lyric.IsPruneMusic.ShouldBeFalse();
|
||||||
|
lyric.ToString().ShouldContain("你好像快要不能呼吸");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -34,8 +34,8 @@ namespace ZonyLrcTools.Tests.Infrastructure.Network
|
|||||||
public async Task GetAsyncWithProxy_Test()
|
public async Task GetAsyncWithProxy_Test()
|
||||||
{
|
{
|
||||||
var option = ServiceProvider.GetRequiredService<IOptions<ToolOptions>>();
|
var option = ServiceProvider.GetRequiredService<IOptions<ToolOptions>>();
|
||||||
option.Value.NetworkOptions.ProxyIp = "127.0.0.1";
|
option.Value.NetworkOptions.Ip = "127.0.0.1";
|
||||||
option.Value.NetworkOptions.ProxyPort = 4780;
|
option.Value.NetworkOptions.Port = 4780;
|
||||||
|
|
||||||
var client = ServiceProvider.GetRequiredService<IWarpHttpClient>();
|
var client = ServiceProvider.GetRequiredService<IWarpHttpClient>();
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
@@ -14,7 +15,7 @@ namespace ZonyLrcTools.Tests.Infrastructure.Tag
|
|||||||
var tagLoader = ServiceProvider.GetRequiredService<ITagLoader>();
|
var tagLoader = ServiceProvider.GetRequiredService<ITagLoader>();
|
||||||
|
|
||||||
tagLoader.ShouldNotBeNull();
|
tagLoader.ShouldNotBeNull();
|
||||||
var info = await tagLoader.LoadTagAsync(@"D:\はるまきごはん 煮ル果実 くらげP 蜂屋ななし じん かいりきベア - ダンスロボットダンス (アレンジメドレー (キメラver) はるまきごはん×煮ル果実×和田たけあき×栗山夕璃(蜂屋.flac");
|
var info = await tagLoader.LoadTagAsync(Path.Combine(Directory.GetCurrentDirectory(), "MusicFiles", "曾经艺也 - 荀彧(纯音乐版).mp3"));
|
||||||
info.ShouldNotBeNull();
|
info.ShouldNotBeNull();
|
||||||
info.Name.ShouldBe("荀彧(纯音乐版)");
|
info.Name.ShouldBe("荀彧(纯音乐版)");
|
||||||
info.Artist.ShouldBe("曾经艺也");
|
info.Artist.ShouldBe("曾经艺也");
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using ZonyLrcTools.Cli;
|
||||||
using ZonyLrcTools.Cli.Commands;
|
using ZonyLrcTools.Cli.Commands;
|
||||||
using ZonyLrcTools.Cli.Infrastructure.DependencyInject;
|
using ZonyLrcTools.Cli.Infrastructure.DependencyInject;
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ namespace ZonyLrcTools.Tests
|
|||||||
{
|
{
|
||||||
var service = new ServiceCollection();
|
var service = new ServiceCollection();
|
||||||
|
|
||||||
service.BeginAutoDependencyInject<ToolCommand>();
|
service.BeginAutoDependencyInject<Program>();
|
||||||
service.ConfigureToolService();
|
service.ConfigureToolService();
|
||||||
service.ConfigureConfiguration();
|
service.ConfigureConfiguration();
|
||||||
|
|
||||||
|
@@ -7,14 +7,14 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||||
<PackageReference Include="Shouldly" Version="4.0.3" />
|
<PackageReference Include="Shouldly" Version="4.0.3" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="3.1.0">
|
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
Reference in New Issue
Block a user