Bladeren bron

add: m4a to mp4 with static cover

HOME 1 jaar geleden
bovenliggende
commit
d651ed18af
1 gewijzigde bestanden met toevoegingen van 97 en 12 verwijderingen
  1. 97 12
      BatchProcess/Program.cs

+ 97 - 12
BatchProcess/Program.cs

@@ -3,7 +3,6 @@ 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;
@@ -53,6 +52,7 @@ namespace BatchProcess
         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 const string OP_CONVERT_LIB_FLAC_TO_AAC_IN_DIR = "convert_lib_flac_to_aac_in_dir";
+        private const string OP_CONVERT_LIB_SUBSET_TO_MP4_IN_DIR = "op_convert_lib_subset_to_mp4_in_dir";
 
         private static void RealMain(string[] args)
         {
@@ -87,6 +87,9 @@ namespace BatchProcess
                 Console.WriteLine($" *  {OP_CONVERT_LIB_FLAC_TO_AAC_IN_DIR} <libDir> [q value]");
                 Console.WriteLine($"        Convert to aac and copy tags to output, default q is 1.0");
                 Console.WriteLine($"        libDir/Album/Track.flac -> libDir/Album/AAC_Q1.00/Track.m4a");
+                Console.WriteLine($" *  {OP_CONVERT_LIB_SUBSET_TO_MP4_IN_DIR} <libDir> [subset]");
+                Console.WriteLine($"        Convert to mp4(static cover) and copy tags to output, default subset is AAC_Q1.00");
+                Console.WriteLine($"        libDir/Album/subset/Track.m4a -> libDir/Album/subset_MP4/Track.mp4");
                 Console.WriteLine($"");
                 Console.WriteLine($" +  More on demand");
                 return;
@@ -94,7 +97,7 @@ namespace BatchProcess
 
             var op = args[0];
 
-            Console.WriteLine($"OP:{op}");
+            Console.WriteLine($"OP: {op}");
 
             var argsToOp = args.Skip(1).ToArray();
 
@@ -117,11 +120,91 @@ namespace BatchProcess
                 case OP_CONVERT_FLAC_TO_AAC: ConvertFlacToAac(argsToOp); break;
                 case OP_CONVERT_LIB_FLAC_TO_AAC: ConvertLibFlacToAac(argsToOp); break;
                 case OP_CONVERT_LIB_FLAC_TO_AAC_IN_DIR: ConvertLibFlacToAacInDir(argsToOp); break;
+                case OP_CONVERT_LIB_SUBSET_TO_MP4_IN_DIR: ConvertLibSubsetToMp4InDir(argsToOp); break;
             }
         }
 
         // impl
 
+        private static void ConvertLibSubsetToMp4InDir(string[] args)
+        {
+            if (args.Length < 1) throw new ArgumentException("args least need 1");
+            var libDir = args[0]; var subset = args.Length > 1 ? args[1] : "AAC_Q1.00";
+
+            if (false == Directory.Exists(libDir)) throw new DirectoryNotFoundException($"lib dir `{libDir}' not found.");
+
+            foreach (var discDir in Directory.GetDirectories(libDir))
+            {
+                var subsetDir = Path.Combine(discDir, subset); if (false == Directory.Exists(subsetDir)) continue;
+
+                foreach (var track in Directory.GetFiles(subsetDir))
+                {
+                    var outDir = Path.Combine(discDir, subset + "_MP4");
+                    var outFile = Path.Combine(outDir, Path.GetFileNameWithoutExtension(track) + ".MP4");
+
+                    if (File.Exists(outFile)) { Console.WriteLine($"SKIP: exist. `{outFile}'"); continue; }
+
+                    byte[] coverBytes;
+                    try
+                    {
+                        using var tag = TagLib.File.Create(track);
+                        coverBytes = tag.Tag.Pictures.Where(p => p.Type == PictureType.FrontCover).Select(p => p.Data.ToArray()).FirstOrDefault();
+                    }
+                    catch (Exception e) { Console.WriteLine($"ERR: {e.Message} in `{track}'"); continue; }
+
+                    if (coverBytes == null) { Console.WriteLine($"WARN: skip. no cover in `{track}'"); continue; }
+
+                   
+
+                    var tmp = Path.GetTempFileName();
+                    File.WriteAllBytes(tmp, coverBytes);
+
+                    if (Directory.Exists(outDir) == false) { Console.WriteLine($"Create dir `{outDir}'"); Directory.CreateDirectory(outDir); }
+
+                    Console.WriteLine($"PROCESS: `{track}'");
+
+                    var ffMpegArgs = new string[]
+                    {
+                        "-n","-hide_banner","-stats","-v","warning",
+                        "-framerate","60",
+                        "-loop","1","-i",tmp,
+                        "-i",track,
+                        "-map_metadata","-1","-map_chapters","-1",
+                        "-shortest",
+                        
+                        "-vf","scale=-1:480",
+
+                        "-c:v","h264","-pix_fmt","yuv420p",
+                        "-preset","placebo",
+                        "-crf","28","-bf","1250","-g","1250","-keyint_min","250",
+
+                        "-c:a","copy",
+                        
+                        outFile
+                    };
+
+                    var process = new Process
+                    {
+                        StartInfo =
+                        {
+                            FileName = "ffmpeg",
+                            CreateNoWindow = false,
+                            UseShellExecute = false,
+                            
+                        }
+                    };
+                    foreach (var item in ffMpegArgs) process.StartInfo.ArgumentList.Add(item);
+                    process.Start();
+                    process.PriorityClass = ProcessPriorityClass.BelowNormal;
+                    process.WaitForExit();
+
+                    File.Delete(tmp);//delete temp cover file
+
+                    if (process.ExitCode == 0) CopyTag(new[] { track, outFile }, false);
+                }
+            }
+        }
+
         private static void ConvertLibFlacToAacInDir(string[] args)
         {
             if (args.Length < 1) throw new ArgumentException("args least need 1");
@@ -137,18 +220,18 @@ namespace BatchProcess
             {
                 var outAlbDir = Path.Combine(albDir, $"AAC_Q{q:N2}");
 
-                if (false == Directory.Exists(outAlbDir))
-                {
-                    Console.WriteLine($"Create dir:{outAlbDir}");
-                    Directory.CreateDirectory(outAlbDir);
-                }
-
                 foreach (var flacPath in Directory.GetFiles(albDir, "*.flac"))
                 {
+                    if (false == Directory.Exists(outAlbDir))
+                    {
+                        Console.WriteLine($"Create dir:{outAlbDir}");
+                        Directory.CreateDirectory(outAlbDir);
+                    }
+
                     var outM4APath = Path.Combine(outAlbDir, Path.ChangeExtension(Path.GetFileName(flacPath), ".m4a"));
                     Console.WriteLine(
-                        ConvertFlacToAac(new[] {flacPath, outM4APath, $"{q}"}) 
-                            ? $"Convert OK. -> {outM4APath}" 
+                        ConvertFlacToAac(new[] { flacPath, outM4APath, $"{q}" })
+                            ? $"Convert OK. -> {outM4APath}"
                             : $"Exist, Skipped. {outM4APath}"
                     );
                 }
@@ -271,7 +354,7 @@ namespace BatchProcess
             return true;
         }
 
-        private static void CopyTag(string[] args)
+        private static void CopyTag(string[] args, bool cover = true)
         {
             if (args.Length < 2) throw new ArgumentException("args need 2");
             var pathIn = args[0];
@@ -282,13 +365,15 @@ namespace BatchProcess
             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;
+            if (cover) dst.Tag.Pictures = src.Tag.Pictures;
             src.Dispose();
             dst.Save();
             dst.Dispose();