Program.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Net.Mime;
  5. using System.Reflection;
  6. using System.Text;
  7. using TagLib;
  8. using File = System.IO.File;
  9. // ReSharper disable InconsistentNaming
  10. namespace Id3TagBatchProcess
  11. {
  12. internal class Program
  13. {
  14. private static void Main(string[] args)
  15. {
  16. Console.WriteLine("Id3 Tag Batch Procesor");
  17. Console.WriteLine();
  18. try
  19. {
  20. RealMain(args);
  21. }
  22. catch (Exception e)
  23. {
  24. Console.WriteLine($"ERROR:{e.Message}");
  25. }
  26. Console.WriteLine();
  27. Console.Write("Press ENTER to exit...");
  28. Console.ReadLine();
  29. }
  30. private const string OP_DIR_EMB_COVER_MP3 = "embcover_mp3_jpg_dir";
  31. private const string OP_DIR_EMB_COVER_M4A = "embcover_m4a_jpg_dir";
  32. private const string OP_EMB_COVER = "embcover";
  33. private const string OP_EMB_LRC = "emblrc";
  34. private static void RealMain(string[] args)
  35. {
  36. if (0 == args.Length)
  37. {
  38. Console.WriteLine($"Useage: {Path.GetFileName(Assembly.GetExecutingAssembly().CodeBase)} <op> [args...]");
  39. Console.WriteLine($"Available ops:");
  40. Console.WriteLine($" * {OP_EMB_LRC} <inputPath> <lrcPath> <outputPath>");
  41. Console.WriteLine($" Embed lyrics into file(utf8)");
  42. Console.WriteLine($" * {OP_EMB_COVER} <inputPath> <coverPath> <outputPath> [mime-type]");
  43. Console.WriteLine($" Embed cover into file, default mine-type is {MediaTypeNames.Image.Jpeg}");
  44. Console.WriteLine($" * {OP_DIR_EMB_COVER_MP3} <inputDir> <outputDir> -- lookup dir, embed same file name jpg/jpeg into mp3");
  45. Console.WriteLine($" Lookup dir, embed same file name jpg/jpeg into mp3");
  46. Console.WriteLine($" Embed abc.jpg or abc.jpeg into abc.mp3 and save a copy to output dir.");
  47. Console.WriteLine($" * {OP_DIR_EMB_COVER_M4A} <inputDir> <outputDir> -- lookup dir, embed same file name jpg/jpeg into m4a");
  48. Console.WriteLine($" Lookup dir, embed same file name jpg/jpeg into m4a");
  49. Console.WriteLine($" Embed abc.jpg or abc.jpeg into abc.m4a and save a copy to output dir.");
  50. Console.WriteLine($"");
  51. Console.WriteLine($" + More on demand");
  52. return;
  53. }
  54. var op = args[0];
  55. var argsToOp = args.Skip(1).ToArray();
  56. switch (op)
  57. {
  58. default: throw new ArgumentException($"No recognizable op:{op}");
  59. case OP_DIR_EMB_COVER_MP3: EmbJpegCoverDir(argsToOp, "*.mp3"); break;
  60. case OP_DIR_EMB_COVER_M4A: EmbJpegCoverDir(argsToOp, "*.m4a"); break;
  61. case OP_EMB_COVER: EmbCover(argsToOp); break;
  62. case OP_EMB_LRC: EmbLrc(argsToOp); break;
  63. }
  64. }
  65. private static void EmbCover(string[] args)
  66. {
  67. if (args.Length < 3) throw new ArgumentException("args need 3");
  68. var pathIn = args[0];
  69. var pathCover = args[1];
  70. var pathOutput = args[2];
  71. var mimeType = args.Length > 3 ? args[4] : MediaTypeNames.Image.Jpeg;
  72. if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"inputPath `{pathIn}' not found.");
  73. if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"coverPath `{pathCover}' not found.");
  74. Console.WriteLine($"Processing {pathIn}...");
  75. Console.WriteLine($"Comver image:{pathCover}");
  76. File.Copy(pathIn, pathOutput);
  77. EmbedConverIntoFile(pathOutput, pathCover, mimeType);
  78. // 12345678901234
  79. Console.WriteLine($"Saved to: {pathOutput}");
  80. }
  81. private static void EmbLrc(string[] args)
  82. {
  83. if (args.Length < 3) throw new ArgumentException("args need 2");
  84. var pathIn = args[0];
  85. var pathLrc = args[1];
  86. var pathOutput = args[2];
  87. if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"inputPath `{pathIn}' not found.");
  88. if (false == File.Exists(pathIn)) throw new DirectoryNotFoundException($"coverPath `{pathLrc}' not found.");
  89. Console.WriteLine($"Processing {pathIn}...");
  90. Console.WriteLine($"Comver image:{pathLrc}");
  91. File.Copy(pathIn, pathOutput);
  92. EmbedLrcIntoFile(pathOutput, pathLrc);
  93. // 12345678901234
  94. Console.WriteLine($"Saved to: {pathOutput}");
  95. }
  96. // impl
  97. private static void EmbJpegCoverDir(string[] args, string pattern)
  98. {
  99. if (args.Length != 2) throw new ArgumentException("args need 2");
  100. var dirIn = args[0];
  101. var dirOut = args[1];
  102. if (false == Directory.Exists(dirIn)) throw new DirectoryNotFoundException($"inputDir `{dirIn}' not found.");
  103. if (false == Directory.Exists(dirOut)) throw new DirectoryNotFoundException($"outputDir `{dirOut} not found.'");
  104. Console.WriteLine($"Enter directory:{dirIn}");
  105. var files = Directory.GetFiles(dirIn, pattern);
  106. if (0 == files.Length)
  107. {
  108. Console.WriteLine($"Not result for {pattern}");
  109. }
  110. else
  111. {
  112. foreach (var file in files)
  113. {
  114. // 12345678901234
  115. Console.WriteLine($"Processing {file}...");
  116. var imgFilePath = Path.ChangeExtension(file, ".jpg");
  117. if (false == File.Exists(imgFilePath)) imgFilePath = Path.ChangeExtension(file, ".jpeg");
  118. if (false == File.Exists(imgFilePath))
  119. {
  120. Console.WriteLine("Cover image file not found, Skipped. ***");
  121. continue;
  122. }
  123. // 12345678901234
  124. Console.WriteLine($"Comver image:{imgFilePath}");
  125. var destFileName = Path.Combine(dirOut, Path.GetFileName(file));
  126. File.Copy(file, destFileName);
  127. EmbedConverIntoFile(destFileName, imgFilePath, MediaTypeNames.Image.Jpeg);
  128. // 12345678901234
  129. Console.WriteLine($"Saved to: {destFileName}");
  130. }
  131. }
  132. Console.WriteLine($"Leave directory:{dirIn}");
  133. }
  134. private static void EmbedConverIntoFile(string filePath, string coverPath, string mimeType)
  135. {
  136. var mediaFile = TagLib.File.Create(filePath);
  137. var pic = new Picture //REF: stackoverflow.com/a/30285220/2430943
  138. {
  139. Type = PictureType.FrontCover,
  140. Description = "Cover",
  141. MimeType = mimeType,
  142. Data = File.ReadAllBytes(coverPath)
  143. };
  144. mediaFile.Tag.Pictures = new IPicture[] { pic };
  145. mediaFile.Save();
  146. }
  147. private static void EmbedLrcIntoFile(string filePath, string lrcPath)
  148. {
  149. var mediaFile = TagLib.File.Create(filePath);
  150. mediaFile.Tag.Lyrics = File.ReadAllText(lrcPath,Encoding.UTF8);
  151. mediaFile.Save();
  152. }
  153. }
  154. }