Browse Source

change project name and add more batch op

HOME 2 years ago
parent
commit
d59cf560d2

+ 7 - 3
Id3TagBatchProcess/Id3TagBatchProcess.csproj

@@ -7,13 +7,14 @@
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <ProjectGuid>{165C4021-2755-49B9-AB25-3EDAB449E2D5}</ProjectGuid>
     <OutputType>Exe</OutputType>
-    <RootNamespace>Id3TagBatchProcess</RootNamespace>
-    <AssemblyName>Id3TagBatchProcess</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <RootNamespace>BatchProcess</RootNamespace>
+    <AssemblyName>BatchProcess</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <NuGetPackageImportStamp>
     </NuGetPackageImportStamp>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -24,6 +25,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <LangVersion>latest</LangVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -33,6 +35,7 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <LangVersion>latest</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
     <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
@@ -60,6 +63,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
+    <None Include="app.config" />
     <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

+ 385 - 0
BatchProcess/Program.cs

@@ -0,0 +1,385 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net.Mime;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using TagLib;
+using File = System.IO.File;
+
+// ReSharper disable InconsistentNaming
+
+namespace BatchProcess
+{
+    internal class Program
+    {
+        private static void Main(string[] args)
+        {
+            Console.WriteLine("Batch Processor");
+            Console.WriteLine();
+
+            var skipPause = false;
+            if (args.Length > 0 && args[0].ToLower() == "--no-pause")
+            {
+                skipPause = true;
+                args = args.Skip(1).ToArray();
+            }
+
+            try
+            {
+                RealMain(args);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine($"ERROR:{e.GetType().Name},{e.Message}");
+            }
+
+            Console.WriteLine();
+
+            if (skipPause) return;
+            Console.Write("Press ENTER to exit...");
+            Console.ReadLine();
+        }
+
+        private const string OP_DIR_EMB_COVER_MP3 = "embcover_mp3_jpg_dir";
+        private const string OP_DIR_EMB_COVER_M4A = "embcover_m4a_jpg_dir";
+        private const string OP_EMB_COVER = "embcover";
+        private const string OP_COPY = "copy";
+        private const string OP_EMB_COVER_IF_NOT_EMBEDDED = "embcover_if_not_embedded";
+        private const string OP_EMB_COVER_IF_NOT_EMBEDDED_COVER_DOT_JPG = "embcover_if_not_embedded_cover_jpg";
+        private const string OP_EMB_LRC = "emblrc";
+        private const string OP_CONVERT_FLAC_TO_AAC = "convert_flac_to_aac";
+        private const string OP_CONVERT_LIB_FLAC_TO_AAC = "convert_lib_flac_to_aac";
+
+        private static void RealMain(string[] args)
+        {
+            if (0 == args.Length)
+            {
+                Console.WriteLine($"Usage: {Path.GetFileName(Assembly.GetExecutingAssembly().CodeBase)} <op> [args...]");
+                Console.WriteLine($"Prefix ops:");
+                Console.WriteLine($" *  --no-pause");
+                Console.WriteLine($"        Disable enter key to exit");
+                Console.WriteLine($"Available ops:");
+                Console.WriteLine($" *  {OP_COPY} <sourcePath> <targetPath>");
+                Console.WriteLine($"        Copy tags from source to target (replace)");
+                Console.WriteLine($" *  {OP_EMB_LRC} <inputPath> <lrcPath> <outputPath>");
+                Console.WriteLine($"        Embed lyrics into file(utf8)");
+                Console.WriteLine($" *  {OP_EMB_COVER}|{OP_EMB_COVER_IF_NOT_EMBEDDED} <inputPath> <coverPath> [outputPath] [mime-type]");
+                Console.WriteLine($"        Embed cover into file, default mine-type is {MediaTypeNames.Image.Jpeg}");
+                Console.WriteLine($" *  {OP_EMB_COVER_IF_NOT_EMBEDDED_COVER_DOT_JPG} <inputPath>");
+                Console.WriteLine($"        Embed cover into file if not embedded, same folder cover.jpg");
+                Console.WriteLine($" *  {OP_DIR_EMB_COVER_MP3} <inputDir> <outputDir> -- lookup dir, embed same file name jpg/jpeg into mp3");
+                Console.WriteLine($"        Lookup dir, embed same file name jpg/jpeg into mp3");
+                Console.WriteLine($"        Embed abc.jpg or abc.jpeg into abc.mp3 and save a copy to output dir.");
+                Console.WriteLine($" *  {OP_DIR_EMB_COVER_M4A} <inputDir> <outputDir> -- lookup dir, embed same file name jpg/jpeg into m4a");
+                Console.WriteLine($"        Lookup dir, embed same file name jpg/jpeg into m4a");
+                Console.WriteLine($"        Embed abc.jpg or abc.jpeg into abc.m4a and save a copy to output dir.");
+                Console.WriteLine($" *  {OP_CONVERT_FLAC_TO_AAC} <inputPath> <outputPath> [q value]");
+                Console.WriteLine($"        Convert to aac and copy tags to output, default q is 1.0");
+                Console.WriteLine($" *  {OP_CONVERT_LIB_FLAC_TO_AAC} <inputDir> <outputDir> [q value]");
+                Console.WriteLine($"        Convert to aac and copy tags to output, default q is 1.0");
+                Console.WriteLine($"        inputDir/Album/Track.flac -> outputDir/Album/Track.m4a");
+                Console.WriteLine($"        Also copy inputDir/Album/cover.jpg to outDir/Album/cover.jpg if found");
+
+                Console.WriteLine($"");
+                Console.WriteLine($" +  More on demand");
+                return;
+            }
+
+            var op = args[0];
+
+            Console.WriteLine($"OP:{op}");
+
+            var argsToOp = args.Skip(1).ToArray();
+
+            switch (op.ToLower())
+            {
+                default: throw new ArgumentException($"No recognizable op:{op}");
+                case OP_DIR_EMB_COVER_MP3: EmbJpegCoverDir(argsToOp, "*.mp3"); break;
+                case OP_DIR_EMB_COVER_M4A: EmbJpegCoverDir(argsToOp, "*.m4a"); break;
+                case OP_EMB_COVER: EmbCover(argsToOp, true); break;
+                case OP_EMB_COVER_IF_NOT_EMBEDDED: EmbCover(argsToOp, false); break;
+                case OP_EMB_LRC: EmbLrc(argsToOp); break;
+                case OP_COPY: CopyTag(argsToOp); break;
+                case OP_EMB_COVER_IF_NOT_EMBEDDED_COVER_DOT_JPG:
+                    if (argsToOp.Length != 1) throw new ArgumentException("args need 1");
+                    // ReSharper disable once AssignNullToNotNullAttribute
+                    var argsMod = new[] { argsToOp[0], Path.Combine(Path.GetDirectoryName(argsToOp[0]), "cover.jpg") };
+                    EmbCover(argsMod, false);
+                    break;
+
+                case OP_CONVERT_FLAC_TO_AAC: ConvertFlacToAac(argsToOp); break;
+                case OP_CONVERT_LIB_FLAC_TO_AAC: ConvertLibFlacToAac(argsToOp); break;
+            }
+        }
+
+        // impl
+
+        private static void ConvertLibFlacToAac(string[] args)
+        {
+            if (args.Length < 2) throw new ArgumentException("args least need 2");
+            var inDir = args[0];
+            var outDir = args[1];
+
+            if (false == Directory.Exists(inDir)) throw new DirectoryNotFoundException($"input dir `{inDir}' not found.");
+            if (false == Directory.Exists(outDir)) throw new DirectoryNotFoundException($"output dir `{inDir}' not found.");
+
+            var q = args.Length > 2 && float.TryParse(args[2], out var tq) && tq is >= 0 and <= 1
+                ? tq
+                : 1.0;
+
+            foreach (var albDir in Directory.GetDirectories(inDir))
+            {
+                var albDirName = Path.GetFileName(albDir);
+                var outAlbDir = Path.Combine(outDir, albDirName);
+                if (false == Directory.Exists(outAlbDir))
+                {
+                    Console.WriteLine($"Create dir:{outAlbDir}");
+                    Directory.CreateDirectory(outAlbDir);
+                }
+
+                var coverPath = Path.Combine(albDir, "cover.jpg");
+                var destCoverPath = Path.Combine(outAlbDir, "cover.jpg");
+                if (File.Exists(coverPath) && false == File.Exists(destCoverPath))
+                {
+                    Console.WriteLine($"Copy {coverPath}");
+                    Console.WriteLine($"  -> {destCoverPath} ");
+                    File.Copy(coverPath, destCoverPath);
+                }
+
+                foreach (var flacPath in Directory.GetFiles(albDir, "*.flac"))
+                {
+                    var outM4APath = Path.Combine(outAlbDir, Path.ChangeExtension(Path.GetFileName(flacPath), ".m4a"));
+                    if (ConvertFlacToAac(new[] { flacPath, outM4APath, $"{q}" }))
+                    {
+                        Console.WriteLine($"Convert OK. -> {outM4APath}");
+                    }
+                    else
+                    {
+                        Console.WriteLine($"Exist, Skipped. {outM4APath}");
+                    }
+                }
+            }
+        }
+
+        private static bool ConvertFlacToAac(string[] args)
+        {
+            if (args.Length < 2) throw new ArgumentException("args least need 2");
+            var pathIn = args[0];
+            var pathOutput = args[1];
+            var q = args.Length > 2 && float.TryParse(args[2], out var tq) && tq is >= 0 and <= 1
+                ? tq
+                : 1.0;
+
+            if (false == File.Exists(pathIn)) throw new FileNotFoundException($"sourcePath `{pathIn}' not found.");
+            if (File.Exists(pathOutput)) return false;
+            if (false == Directory.Exists(Path.GetDirectoryName(pathOutput))) throw new DirectoryNotFoundException($"targetPath dir not found.");
+
+            Console.WriteLine($"Processing   {pathIn}...");
+
+            var flacProcess = new Process
+            {
+                StartInfo =
+                {
+                    FileName = "FLAC",
+                    Arguments = $"-s -c -d \"{pathIn}\"",
+                    RedirectStandardOutput = true,
+                    UseShellExecute = false,
+                }
+            };
+
+            var aacProcess = new Process
+            {
+                StartInfo =
+                {
+                    FileName = "NeroAacEnc",
+                    Arguments = $"-if - -q {q} -of \"{pathOutput}\"",
+                    RedirectStandardInput = true,
+                    UseShellExecute = false,
+                }
+            };
+
+            flacProcess.Start();
+            aacProcess.Start();
+
+            var pipe = Task.Factory.StartNew(() =>
+            {
+                try
+                {
+                    flacProcess.StandardOutput.BaseStream.CopyTo(aacProcess.StandardInput.BaseStream, 1024 * 512);
+                }
+                catch
+                {
+                    //EAT ERROR
+                }
+
+                try
+                {
+                    aacProcess.StandardInput.BaseStream.Close();
+                }
+                catch
+                {
+                    //EAT ERROR
+                }
+            });
+
+            Task.WaitAll(pipe);
+            flacProcess.WaitForExit();
+            aacProcess.WaitForExit();
+
+            CopyTag(args);
+            return true;
+        }
+
+        private static void CopyTag(string[] args)
+        {
+            if (args.Length < 2) throw new ArgumentException("args need 2");
+            var pathIn = args[0];
+            var pathOutput = args[1];
+
+            if (false == File.Exists(pathIn)) throw new FileNotFoundException($"sourcePath `{pathIn}' not found.");
+            if (false == Directory.Exists(Path.GetDirectoryName(pathOutput))) throw new DirectoryNotFoundException($"targetPath dir not found.");
+            if (false == File.Exists(pathOutput)) throw new FileNotFoundException($"targetPath `{pathOutput}' not found.");
+
+            using var src = TagLib.File.Create(pathIn);
+            var dst = TagLib.File.Create(pathOutput);
+            dst.Tag.Clear();
+            dst.Save();
+            dst.Dispose();
+            dst = TagLib.File.Create(pathOutput);
+            src.Tag.CopyTo(dst.Tag, true);
+            dst.Tag.Pictures = src.Tag.Pictures;
+            src.Dispose();
+            dst.Save();
+            dst.Dispose();
+            Console.WriteLine("Tag Copied.");
+        }
+
+        private static void EmbCover(string[] args, bool overwrite)
+        {
+            if (args.Length < 2) throw new ArgumentException("args least need 2");
+            var pathIn = args[0];
+            var pathCover = args[1];
+            var pathOutput = args.Length > 2 ? args[2] : args[0];
+            var mimeType = args.Length > 3 ? args[4] : MediaTypeNames.Image.Jpeg;
+
+            if (false == File.Exists(pathIn)) throw new FileNotFoundException($"inputPath `{pathIn}' not found.");
+            if (false == File.Exists(pathCover)) throw new FileNotFoundException($"coverPath `{pathCover}' not found.");
+
+            Console.WriteLine($"Processing   {pathIn}...");
+            Console.WriteLine($"Comver image:{pathCover}");
+
+            if (pathIn != pathOutput) File.Copy(pathIn, pathOutput, true);
+
+            if (EmbedCoverIntoFile(pathOutput, pathCover, mimeType, overwrite))
+            {
+                //                  12345678901234
+                Console.WriteLine($"Saved to:    {pathOutput}");
+            }
+            else
+            {
+                Console.WriteLine("Skipped.");
+            }
+        }
+
+        private static void EmbLrc(string[] args)
+        {
+            if (args.Length < 3) throw new ArgumentException("args need 2");
+            var pathIn = args[0];
+            var pathLrc = args[1];
+            var pathOutput = args[2];
+
+            if (false == File.Exists(pathIn)) throw new FileNotFoundException($"inputPath `{pathIn}' not found.");
+            if (false == File.Exists(pathLrc)) throw new FileNotFoundException($"coverPath `{pathLrc}' not found.");
+
+            Console.WriteLine($"Processing   {pathIn}...");
+            Console.WriteLine($"Comver image:{pathLrc}");
+
+            if (pathIn != pathOutput) File.Copy(pathIn, pathOutput);
+
+            EmbedLrcIntoFile(pathOutput, pathLrc);
+
+            //                  12345678901234
+            Console.WriteLine($"Saved to:    {pathOutput}");
+        }
+
+        private static void EmbJpegCoverDir(string[] args, string pattern)
+        {
+            if (args.Length != 2) throw new ArgumentException("args need 2");
+
+            var dirIn = args[0];
+            var dirOut = args[1];
+
+            if (false == Directory.Exists(dirIn)) throw new DirectoryNotFoundException($"inputDir `{dirIn}' not found.");
+            if (false == Directory.Exists(dirOut)) throw new DirectoryNotFoundException($"outputDir `{dirOut} not found.'");
+
+            Console.WriteLine($"Enter directory:{dirIn}");
+            var files = Directory.GetFiles(dirIn, pattern);
+            if (0 == files.Length)
+            {
+                Console.WriteLine($"Not result for {pattern}");
+            }
+            else
+            {
+                foreach (var file in files)
+                {
+                    //                  12345678901234
+                    Console.WriteLine($"Processing   {file}...");
+
+                    var imgFilePath = Path.ChangeExtension(file, ".jpg");
+                    if (false == File.Exists(imgFilePath)) imgFilePath = Path.ChangeExtension(file, ".jpeg");
+                    if (false == File.Exists(imgFilePath))
+                    {
+                        Console.WriteLine("Cover image file not found, Skipped. ***");
+                        continue;
+                    }
+
+                    //                  12345678901234
+                    Console.WriteLine($"Comver image:{imgFilePath}");
+
+                    var destFileName = Path.Combine(dirOut, Path.GetFileName(file));
+                    File.Copy(file, destFileName);
+
+                    EmbedCoverIntoFile(destFileName, imgFilePath, MediaTypeNames.Image.Jpeg);
+
+                    //                  12345678901234
+                    Console.WriteLine($"Saved to:    {destFileName}");
+                }
+            }
+            Console.WriteLine($"Leave directory:{dirIn}");
+        }
+
+        private static bool EmbedCoverIntoFile(string filePath, string coverPath, string mimeType, bool overwrite = true)
+        {
+            using var mediaFile = TagLib.File.Create(filePath);
+
+            if (!overwrite)
+            {
+                if (mediaFile.Tag.Pictures.Any(p => p.Type == PictureType.FrontCover)) return false;
+            }
+
+            var pic = new Picture //REF: stackoverflow.com/a/30285220/2430943
+            {
+                Type = PictureType.FrontCover,
+                Description = "Cover",
+                MimeType = mimeType,
+                Data = File.ReadAllBytes(coverPath)
+            };
+            mediaFile.Tag.Pictures = new IPicture[] { pic };
+
+            mediaFile.Save();
+            return true;
+        }
+
+        private static void EmbedLrcIntoFile(string filePath, string lrcPath)
+        {
+            var mediaFile = TagLib.File.Create(filePath);
+
+            mediaFile.Tag.Lyrics = File.ReadAllText(lrcPath, Encoding.UTF8);
+
+            mediaFile.Save();
+        }
+    }
+}

Id3TagBatchProcess/Properties/AssemblyInfo.cs → BatchProcess/Properties/AssemblyInfo.cs


Id3TagBatchProcess/packages.config → BatchProcess/packages.config


+ 0 - 190
Id3TagBatchProcess/Program.cs

@@ -1,190 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Net.Mime;
-using System.Reflection;
-using System.Text;
-using TagLib;
-using File = System.IO.File;
-// ReSharper disable InconsistentNaming
-
-namespace Id3TagBatchProcess
-{
-    internal class Program
-    {
-        private static void Main(string[] args)
-        {
-            Console.WriteLine("Id3 Tag Batch Procesor");
-            Console.WriteLine();
-
-            try
-            {
-                RealMain(args);
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine($"ERROR:{e.Message}");
-            }
-
-            Console.WriteLine();
-            Console.Write("Press ENTER to exit...");
-            Console.ReadLine();
-        }
-
-        private const string OP_DIR_EMB_COVER_MP3 = "embcover_mp3_jpg_dir";
-        private const string OP_DIR_EMB_COVER_M4A = "embcover_m4a_jpg_dir";
-        private const string OP_EMB_COVER = "embcover";
-        private const string OP_EMB_LRC = "emblrc";
-
-        private static void RealMain(string[] args)
-        {
-            if (0 == args.Length)
-            {
-                Console.WriteLine($"Useage: {Path.GetFileName(Assembly.GetExecutingAssembly().CodeBase)} <op> [args...]");
-                Console.WriteLine($"Available ops:");
-                Console.WriteLine($" *  {OP_EMB_LRC} <inputPath> <lrcPath> <outputPath>");
-                Console.WriteLine($"        Embed lyrics into file(utf8)");
-                Console.WriteLine($" *  {OP_EMB_COVER} <inputPath> <coverPath> <outputPath> [mime-type]");
-                Console.WriteLine($"        Embed cover into file, default mine-type is {MediaTypeNames.Image.Jpeg}");
-                Console.WriteLine($" *  {OP_DIR_EMB_COVER_MP3} <inputDir> <outputDir> -- lookup dir, embed same file name jpg/jpeg into mp3");
-                Console.WriteLine($"        Lookup dir, embed same file name jpg/jpeg into mp3");
-                Console.WriteLine($"        Embed abc.jpg or abc.jpeg into abc.mp3 and save a copy to output dir.");
-                Console.WriteLine($" *  {OP_DIR_EMB_COVER_M4A} <inputDir> <outputDir> -- lookup dir, embed same file name jpg/jpeg into m4a");
-                Console.WriteLine($"        Lookup dir, embed same file name jpg/jpeg into m4a");
-                Console.WriteLine($"        Embed abc.jpg or abc.jpeg into abc.m4a and save a copy to output dir.");
-
-                Console.WriteLine($"");
-                Console.WriteLine($" +  More on demand");
-                return;
-            }
-
-            var op = args[0];
-            var argsToOp = args.Skip(1).ToArray();
-
-            switch (op)
-            {
-                default: throw new ArgumentException($"No recognizable op:{op}");
-                case OP_DIR_EMB_COVER_MP3: EmbJpegCoverDir(argsToOp, "*.mp3"); break;
-                case OP_DIR_EMB_COVER_M4A: EmbJpegCoverDir(argsToOp, "*.m4a"); break;
-                case OP_EMB_COVER: EmbCover(argsToOp); break;
-                case OP_EMB_LRC: EmbLrc(argsToOp); break;
-            }
-        }
-
-        private static void EmbCover(string[] args)
-        {
-            if (args.Length < 3) throw new ArgumentException("args need 3");
-            var pathIn = args[0];
-            var pathCover = args[1];
-            var pathOutput = args[2];
-            var mimeType = args.Length > 3 ? args[4] : MediaTypeNames.Image.Jpeg;
-
-            if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"inputPath `{pathIn}' not found.");
-            if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"coverPath `{pathCover}' not found.");
-
-            Console.WriteLine($"Processing   {pathIn}...");
-            Console.WriteLine($"Comver image:{pathCover}");
-
-            File.Copy(pathIn, pathOutput);
-
-            EmbedConverIntoFile(pathOutput, pathCover, mimeType);
-
-            //                  12345678901234
-            Console.WriteLine($"Saved to:    {pathOutput}");
-        }
-
-        private static void EmbLrc(string[] args)
-        {
-            if (args.Length < 3) throw new ArgumentException("args need 2");
-            var pathIn = args[0];
-            var pathLrc = args[1];
-            var pathOutput = args[2];
-
-            if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"inputPath `{pathIn}' not found.");
-            if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"coverPath `{pathLrc}' not found.");
-
-            Console.WriteLine($"Processing   {pathIn}...");
-            Console.WriteLine($"Comver image:{pathLrc}");
-
-            File.Copy(pathIn, pathOutput);
-
-            EmbedLrcIntoFile(pathOutput, pathLrc);
-
-            //                  12345678901234
-            Console.WriteLine($"Saved to:    {pathOutput}");
-        }
-
-        // impl
-
-        private static void EmbJpegCoverDir(string[] args, string pattern)
-        {
-            if (args.Length != 2) throw new ArgumentException("args need 2");
-
-            var dirIn = args[0];
-            var dirOut = args[1];
-
-            if (false == Directory.Exists(dirIn)) throw new DirectoryNotFoundException($"inputDir `{dirIn}' not found.");
-            if (false == Directory.Exists(dirOut)) throw new DirectoryNotFoundException($"outputDir `{dirOut} not found.'");
-
-            Console.WriteLine($"Enter directory:{dirIn}");
-            var files = Directory.GetFiles(dirIn, pattern);
-            if (0 == files.Length)
-            {
-                Console.WriteLine($"Not result for {pattern}");
-            }
-            else
-            {
-                foreach (var file in files)
-                {
-                    //                  12345678901234
-                    Console.WriteLine($"Processing   {file}...");
-
-                    var imgFilePath = Path.ChangeExtension(file, ".jpg");
-                    if (false == File.Exists(imgFilePath)) imgFilePath = Path.ChangeExtension(file, ".jpeg");
-                    if (false == File.Exists(imgFilePath))
-                    {
-                        Console.WriteLine("Cover image file not found, Skipped. ***");
-                        continue;
-                    }
-
-                    //                  12345678901234
-                    Console.WriteLine($"Comver image:{imgFilePath}");
-
-                    var destFileName = Path.Combine(dirOut, Path.GetFileName(file));
-                    File.Copy(file, destFileName);
-
-                    EmbedConverIntoFile(destFileName, imgFilePath, MediaTypeNames.Image.Jpeg);
-
-                    //                  12345678901234
-                    Console.WriteLine($"Saved to:    {destFileName}");
-                }
-            }
-            Console.WriteLine($"Leave directory:{dirIn}");
-        }
-
-        private static void EmbedConverIntoFile(string filePath, string coverPath, string mimeType)
-        {
-            var mediaFile = TagLib.File.Create(filePath);
-
-            var pic = new Picture //REF: stackoverflow.com/a/30285220/2430943
-            {
-                Type = PictureType.FrontCover,
-                Description = "Cover",
-                MimeType = mimeType,
-                Data = File.ReadAllBytes(coverPath)
-            };
-            mediaFile.Tag.Pictures = new IPicture[] { pic };
-
-            mediaFile.Save();
-        }
-
-        private static void EmbedLrcIntoFile(string filePath, string lrcPath)
-        {
-            var mediaFile = TagLib.File.Create(filePath);
-
-            mediaFile.Tag.Lyrics = File.ReadAllText(lrcPath,Encoding.UTF8);
-
-            mediaFile.Save();
-        }
-    }
-}

+ 6 - 6
MusicTool.sln

@@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 16
 VisualStudioVersion = 16.0.29728.190
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Id3TagBatchProcess", "Id3TagBatchProcess\Id3TagBatchProcess.csproj", "{165C4021-2755-49B9-AB25-3EDAB449E2D5}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LrcTool", "LyricTools\LrcTool.csproj", "{D9749FB1-3DC8-4967-A74D-9D4139950BB2}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LrcToolNet4DebugLauncher", "LyricTools\LrcToolNet4DebugLauncher.csproj", "{4729633E-E50E-47F4-AC9B-38412BB5D693}"
@@ -16,16 +14,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "@", "@", "{1F900AE3-F1C6-4C
 		NuGet.config = NuGet.config
 	EndProjectSection
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BatchProcess", "BatchProcess\BatchProcess.csproj", "{165C4021-2755-49B9-AB25-3EDAB449E2D5}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Release|Any CPU = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Release|Any CPU.Build.0 = Release|Any CPU
 		{D9749FB1-3DC8-4967-A74D-9D4139950BB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{D9749FB1-3DC8-4967-A74D-9D4139950BB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{D9749FB1-3DC8-4967-A74D-9D4139950BB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -38,6 +34,10 @@ Global
 		{E23D02D8-44FF-48B6-AC00-E42C5143C19F}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{E23D02D8-44FF-48B6-AC00-E42C5143C19F}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{E23D02D8-44FF-48B6-AC00-E42C5143C19F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{165C4021-2755-49B9-AB25-3EDAB449E2D5}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 2 - 0
MusicTool.sln.DotSettings

@@ -0,0 +1,2 @@
+<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:Boolean x:Key="/Default/UserDictionary/Words/=FLAC/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>