Normantas

NSVideoFilter.cs

Jun 5th, 2021
590
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using FFMediaToolkit.Decoding;
  2. using SixLabors.ImageSharp;
  3. using SixLabors.ImageSharp.PixelFormats;
  4. using System.IO;
  5. using System.Drawing.Imaging;
  6. using System.Drawing;
  7. using Color = System.Drawing.Color;
  8. using System;
  9. using System.Collections.Generic;
  10. using FFMediaToolkit.Encoding;
  11. using FFMediaToolkit.Graphics;
  12. using MediaToolkit;
  13. using MediaToolkit.Options;
  14. namespace GrayScaleFilter
  15. {
  16.     static class NSVideoFilter
  17.     {
  18.         private static string systemDir = System.AppDomain.CurrentDomain.BaseDirectory;
  19.         private static string outputImageDir = $"{systemDir}images";
  20.         private static string FFmpegPath = $@"{systemDir}ffmpeg";
  21.         public static void ConvertVideo(string inputPath, string outputPath, Func<Bitmap, Bitmap> filterFuction)
  22.         {
  23.             FFMediaToolkit.FFmpegLoader.FFmpegPath = FFmpegPath;
  24.             //CreateDirectory();
  25.             //ExtractImages(inputPath, filterFuction);
  26.             DeleteOutputFile(outputPath);
  27.             CombineImagesToVid(inputPath);
  28.             //DeleteImageDir();
  29.             Console.WriteLine("-----------------------");
  30.             Console.WriteLine("Filter Has been applied");
  31.         }
  32.         public static void ConvertToNeonware(string inputPath, string outputPath)
  33.             => ConvertVideo(inputPath, outputPath, NSBitmapFilter.ConvertToNeonware);
  34.         public static void ConvertToGrayscale(string inputPath, string outputPath)
  35.             => ConvertVideo(inputPath, outputPath, NSBitmapFilter.ConvertToGrayscale);
  36.         public static string GetDirOutputPath() // For QuickUse
  37.             => $@"{systemDir}output.mp4";
  38.         private static void DeleteOutputFile(string filePath)
  39.         {
  40.             // Deletes Output file if already exists so it can Override it.
  41.             if (File.Exists(filePath))
  42.                 File.Delete(filePath);  
  43.         }
  44.         private static void CreateDirectory()
  45.         {
  46.             // Creates directory for saving images
  47.             if (Directory.Exists(outputImageDir) == false)
  48.             {
  49.                 Console.WriteLine("Images Directory Added");
  50.                 Directory.CreateDirectory(outputImageDir);
  51.             }
  52.             else
  53.             {
  54.                 DeleteImageDir();
  55.             }
  56.         }
  57.  
  58.         private static void DeleteImageDir()
  59.         {
  60.             // Deletes ./images directory
  61.             System.IO.DirectoryInfo di = new DirectoryInfo(outputImageDir);
  62.             foreach (FileInfo file in di.GetFiles())
  63.             {
  64.                 file.Delete();
  65.             }
  66.             foreach (DirectoryInfo dir in di.GetDirectories())
  67.             {
  68.                 dir.Delete(true);
  69.             }
  70.             Console.WriteLine("Images Directory Emptied");
  71.         }
  72.  
  73.         private static void CombineImagesToVid(string fileLocation)
  74.         {
  75.             // Uses FFMPEG
  76.             System.IO.DirectoryInfo directory = new DirectoryInfo(outputImageDir);
  77.             FFMediaToolkit.Decoding.MediaFile mediaFile = FFMediaToolkit.Decoding.MediaFile.Open(fileLocation);
  78.             FFmpegCommunicator.Start();
  79.             Console.WriteLine($"Adding: images to video");
  80.             FFmpegCommunicator.Execute($" -f image2 -framerate 24 -pattern_type glob -i \'{outputImageDir}\\*.png\' -vf format=yuv420p output.mp4");
  81.             FFmpegCommunicator.End();
  82.         }
  83.         private static int ExtractImages(string fileLocation, Func<Bitmap,Bitmap> filterFunction)
  84.         {
  85.             // Extracts images to outputImageDir
  86.             int frameCount = 1;
  87.             FFMediaToolkit.Decoding.MediaFile originalFile = FFMediaToolkit.Decoding.MediaFile.Open(fileLocation);
  88.             Console.WriteLine($"Duration: {originalFile.Info.Duration}, FrameCount: {originalFile.Video.Info.NumberOfFrames}, AvgFrameRate: {originalFile.Video.Info.AvgFrameRate}");
  89.             while (originalFile.Video.TryGetNextFrame(out FFMediaToolkit.Graphics.ImageData imageData))
  90.             {
  91.                 filterFunction(imageData.ToBitmap()).Save($"{outputImageDir}/{frameCount++}.png");
  92.                 Console.WriteLine($"Exported Image Count: {frameCount - 1}");
  93.             }
  94.             return frameCount;
  95.         }
  96.  
  97.         private static unsafe Bitmap ToBitmap(this FFMediaToolkit.Graphics.ImageData bitmap)
  98.         {
  99.             // Converts ImageData to Bitmap
  100.             // Uses FFMediaToolKit for ImageData
  101.             // ImageData -> Bitmap (unsafe)
  102.             fixed (byte* p = bitmap.Data)
  103.             {
  104.                 return new Bitmap(bitmap.ImageSize.Width, bitmap.ImageSize.Height, bitmap.Stride, PixelFormat.Format24bppRgb, new System.IntPtr(p));
  105.             }
  106.         }
  107.  
  108.         private static FFMediaToolkit.Graphics.ImageData ToImageData(this Bitmap bitmap)
  109.         {
  110.             // Converts Bitmap to ImageData
  111.             // Uses FFMediaToolKit for ImageData
  112.             // Bitmap -> ImageData (safe)
  113.             var rect = new System.Drawing.Rectangle(System.Drawing.Point.Empty, bitmap.Size);
  114.             var bitLock = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
  115.             FFMediaToolkit.Graphics.ImageData bitmapData = FFMediaToolkit.Graphics.ImageData.FromPointer(bitLock.Scan0,FFMediaToolkit.Graphics.ImagePixelFormat.Bgr24, bitmap.Size);
  116.             bitmap.UnlockBits(bitLock);
  117.             return bitmapData;
  118.         }
  119.         /* Legacy Functions
  120.          private static void CombineImagesToVid(string fileLocation, int frameCount)
  121.          {
  122.            using Splicer;
  123.             using Splicer.Timeline;
  124.             using Splicer.Renderer;
  125.             using Splicer.WindowsMedia;
  126.  
  127.              // Uses Splicer
  128.              System.IO.DirectoryInfo directory = new DirectoryInfo(outputImageDir);
  129.              FFMediaToolkit.Decoding.MediaFile mediaFile = FFMediaToolkit.Decoding.MediaFile.Open(fileLocation);
  130.              double timeFps = 1 / mediaFile.Video.Info.AvgFrameRate;
  131.              ITimeline timeline = new DefaultTimeline();
  132.              IGroup group = timeline.AddVideoGroup($"video", mediaFile.Video.Info.AvgFrameRate, 32, mediaFile.Video.Info.FrameSize.Width, mediaFile.Video.Info.FrameSize.Height);
  133.              ITrack videoTrack = group.AddTrack();
  134.              for (int i = 0; i < frameCount; i++)
  135.              {
  136.  
  137.                  Console.WriteLine($"Adding: image {outputImageDir}\\{i}.jpeg to video");
  138.                  videoTrack.AddImage($"{outputImageDir}\\{i}.jpeg",0,i* timeFps, (i+1)* timeFps);
  139.              }
  140.  
  141.  
  142.              // Adds audio
  143.              ITrack audioTrack = timeline.AddAudioGroup().AddTrack();
  144.  
  145.              // IClip audio = audioTrack.AddAudio(fileLocation, 0, videoTrack.Duration);
  146.  
  147.              IRenderer renderer = new WindowsMediaRenderer(timeline, outputPath, WindowsMediaProfiles.HighQualityVideo);
  148.              renderer.Render();
  149.              timeline.Dispose();
  150.          }
  151.          private static void SetUpVideoSettings(string fileLocation)
  152.         {
  153.             // Legacy Function
  154.             // Uses FFMediaToolKit
  155.             // Uses MediaToolKit
  156.             FFMediaToolkit.Decoding.MediaFile originalFile = FFMediaToolkit.Decoding.MediaFile.Open(fileLocation);
  157.             var inputFile = new MediaToolkit.Model.MediaFile { Filename = outputPath };
  158.             var outputFile = new MediaToolkit.Model.MediaFile { Filename = $@"{systemDir}outputTranscoded.mp4" };
  159.  
  160.             var conversionOptions = new ConversionOptions
  161.             {
  162.                 VideoFps = Convert.ToInt32(Math.Ceiling(originalFile.Video.Info.AvgFrameRate)),
  163.                 MaxVideoDuration = (TimeSpan)originalFile.Video.Info.Duration,
  164.                 VideoAspectRatio = VideoAspectRatio.R16_9,
  165.                 VideoSize = VideoSize.Ntsc,
  166.             };
  167.             using (var engine = new Engine())
  168.             {
  169.                 engine.Convert(inputFile, outputFile, conversionOptions);
  170.             }
  171.         }
  172.          private static void CombineImagesUsingFFMTK(string fileLocation, int frameCount)
  173.         {
  174.             // Not working
  175.             File.Delete(outputPath);
  176.             System.IO.DirectoryInfo directory = new DirectoryInfo(outputImageDir);
  177.             FFMediaToolkit.Decoding.MediaFile mediaFile = FFMediaToolkit.Decoding.MediaFile.Open(fileLocation);
  178.             // You can set there codec, bitrate, frame rate and many other options.
  179.             var settings = new VideoEncoderSettings(width: mediaFile.Video.Info.FrameSize.Width, height: mediaFile.Video.Info.FrameSize.Height, framerate: 30, codec: VideoCodec.H264);
  180.             settings.EncoderPreset = EncoderPreset.Fast;
  181.             settings.CRF = 17;
  182.             using (var video = MediaBuilder.CreateContainer(outputPath).WithVideo(settings).Create())
  183.             {
  184.                 for (int i = 0; i < frameCount; i++)
  185.                 {
  186.                     Bitmap bitmap = new Bitmap($"{outputImageDir}\\{i}.jpeg");
  187.                     System.Drawing.Rectangle rect = new System.Drawing.Rectangle(System.Drawing.Point.Empty, bitmap.Size);
  188.                     BitmapData bitLock = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
  189.                     FFMediaToolkit.Graphics.ImageData bitmapImageData = FFMediaToolkit.Graphics.ImageData.FromPointer(bitLock.Scan0, ImagePixelFormat.Bgr24, bitmap.Size);
  190.                     Console.WriteLine($"Adding: image {outputImageDir}\\{i}.jpeg to video");
  191.                     video.Video.AddFrame(bitmapImageData);
  192.                     bitmap.UnlockBits(bitLock);
  193.                 }
  194.             }
  195.         }
  196.          
  197.          */
  198.     }
  199. }
  200.  
RAW Paste Data