Advertisement
Guest User

Linqpad 7 script to create vp9 webms using ffmpeg 2

a guest
Jul 7th, 2022
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.63 KB | None | 0 0
  1. // Creates a webm in the directory `$Path` named "`$OutputFile`.webm".
  2. // Requires ffmpeg be installed and accessible in PATH.
  3. // Could take a while to encode!
  4. // =====================
  5. var config = new EncodeWebmConfig
  6. {
  7.     Path = @"G:\Movies\Anime\Genocyber (1994) [DVD] [kuchikirukia]",
  8.     SourceFile = "01. Genocyber [DVD 540p Hi10P AC-3 dual-audio][kuchikirukia].mkv",
  9.     TempFile = "input.mkv",
  10.     OutputFile = "genocyber-cockblocked",
  11.     StartTime = DateTime.Parse("00:19:05.324"),
  12.     EndTime = DateTime.Parse("00:19:21.296"),
  13.     Resolution = new Vector2(720, 540),
  14.     ResolutionDivisor = 2, // Divide the resolution by this number to get the output resolution
  15.     WithSubtitles = false,
  16.     WithAudio = false,
  17.     AudioCodec = "vorbis",
  18.     TargetBitrate = 1.8m,
  19.     TwoPassMethod = true,
  20.     UseCrfTwoPass = true,
  21.     Crf = 20, // 0-51, 0 best, 30 default
  22.     NativeAac = false,
  23.     Framerate = 0,
  24.     FastMode = false,
  25. };
  26.  
  27.  
  28. // Run
  29. // =====================
  30. var arguments = CreateVp9FfmpegArgs(config);
  31. EncodeWebm(config, arguments);
  32.  
  33.  
  34. // Argument generation
  35. // =====================
  36. string CreateVp9FfmpegArgs(EncodeWebmConfig config)
  37. {
  38.     // https://trac.ffmpeg.org/wiki/Encode/VP9
  39.     var sb = new StringBuilder();
  40.     sb.Append(GetBaseVp9Args(config));
  41.    
  42.     if (config.TwoPassMethod)
  43.     {
  44.         sb.Append($" -pass 1 -an -f null NUL");
  45.        
  46.         sb.Append($" && ffmpeg");
  47.         sb.Append(GetBaseVp9Args(config));
  48.         sb.Append($" -pass 2");
  49.     }
  50.  
  51.     if (config.WithAudio)
  52.     {
  53.         // https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio
  54.         if (config.NativeAac)
  55.         {
  56.             sb.Append($" -c:a copy");
  57.         }
  58.         else
  59.         {
  60.             sb.Append($" -c:a {config.AudioCodec} -strict -2");
  61.         }
  62.     }
  63.     else
  64.     {
  65.         sb.Append($" -an");
  66.     }
  67.  
  68.     sb.Append($" -movflags +faststart \"{config.OutputFile}.webm\"");
  69.     return sb.ToString();
  70.    
  71.     string GetBaseVp9Args(EncodeWebmConfig config)
  72.     {
  73.         var sb = new StringBuilder();
  74.         sb.Append($" -y -i {config.TempFile}");
  75.         sb.Append($" -c:v libvpx-vp9");
  76.        
  77.         if (config.TwoPassMethod && config.UseCrfTwoPass)
  78.         {
  79.             sb.Append($" -b:v 0 -crf {config.Crf}");
  80.         }
  81.         else
  82.         {
  83.             // Target bitrate
  84.             sb.Append($" -b:v {config.TargetBitrate:0}M");
  85.         }
  86.    
  87.         // Framerate
  88.         if (config.Framerate > 0)
  89.         {
  90.             sb.Append($" -r {config.Framerate}");
  91.         }
  92.        
  93.         sb.Append($" -nostats"); // -loglevel 2");
  94.  
  95.         // Go fast
  96.         if (config.FastMode)
  97.         {
  98.             sb.Append($" -row-mt 1 -tile-columns 5 -threads 10 -speed 2");
  99.         }
  100.        
  101.         if (!config.WithSubtitles)
  102.         {
  103.             sb.Append($" -sn");
  104.         }
  105.         else
  106.         {
  107.             // https://trac.ffmpeg.org/wiki/HowToBurnSubtitlesIntoVideo
  108.             // -sn to not include built-in
  109.             sb.Append($" -sn -vf subtitles={config.TempFile}");
  110.         }
  111.  
  112.         sb.Append($" -ss {config.StartTime.ToString("HH:mm:ss.fff")} -t {config.Duration.ToString(@"hh\:mm\:ss\.fff")}");
  113.         sb.Append($" -s {config.ScaledResolution.X}x{config.ScaledResolution.Y}");
  114.        
  115.         return sb.ToString();
  116.     }
  117. }
  118.  
  119. void EncodeWebm(EncodeWebmConfig config, string arguments)
  120. {
  121.     $"ffmpeg {arguments}".Dump();
  122.    
  123.     var start = DateTime.Now;
  124.    
  125.     Directory.SetCurrentDirectory(config.Path);
  126.     Util.Cmd($"del {config.TempFile}");
  127.     Util.Cmd($"mklink {config.TempFile} \"{config.SourceFile}\"");
  128.     Util.Cmd($"ffmpeg {arguments}");
  129.     Util.Cmd($"del {config.TempFile}");
  130.    
  131.     var end = DateTime.Now;
  132.     var duration = end - start;
  133.     $"Job took {duration.ToString()}".Dump();
  134. }
  135.  
  136. class EncodeWebmConfig
  137. {
  138.     // Root directory we start in. Output will be published here.
  139.     public string Path { get; set; }
  140.    
  141.     // The video file you want to clip a webm from. Include extension.
  142.     public string SourceFile { get; set; }
  143.    
  144.     // If you want subtitles, specify it here. If it's an MKV with embedded subtitles, set this to the same as the source file.
  145.     // Commented out - using MKV built-in subs using the TempFile alias
  146.     //public string SubtitlesFile { get; set; }
  147.    
  148.     // Name of temp file created when processing. Is deleted afterwards. (Actually a symbolic link).
  149.     public string TempFile { get; set; }
  150.    
  151.     // The name of the output file. Don't include .webm
  152.     public string OutputFile { get; set; }
  153.    
  154.     // Start time in the video to clip from
  155.     public DateTime StartTime { get; set; }
  156.    
  157.     // End time in the video to clip to
  158.     public DateTime EndTime { get; set; }
  159.    
  160.     // Include audio in output
  161.     public bool WithAudio { get; set; } = true;
  162.    
  163.     // Include subtitles in output
  164.     public bool WithSubtitles { get; set; } = false;
  165.    
  166.     // Target bitrate. Doesn't apply in two-pass CRF mode.
  167.     public decimal TargetBitrate { get; set; } = 3.0m;
  168.    
  169.     // Target output video resolution
  170.     public Vector2 Resolution { get; set; }
  171.    
  172.     // Use the two-pass method (takes longer; better quality).
  173.     // See: https://trac.ffmpeg.org/wiki/Encode/VP9
  174.     public bool TwoPassMethod { get; set; } = false;
  175.    
  176.     // Is the video using AAC encoding already? Then copy the audio directly into the output.
  177.     public bool NativeAac { get; set; }
  178.    
  179.     // Target output framerate. Set to zero to be auto.
  180.     public int Framerate { get; set; }
  181.    
  182.     // Use the CRF method when using the two-pass method.
  183.     public bool UseCrfTwoPass { get; set; }
  184.  
  185.     // A witch doctor on the internet told me you can unlock secret speed techniques by setting "-row-mt 1 -tile-columns 5 -threads 10 -speed 2"
  186.     // Not sure I believe it, but here's the setting for it.
  187.     public bool FastMode { get; set; }
  188.    
  189.     // CRF value, 0-51. 0 is lossless.
  190.     public int Crf { get; set; } = 30;
  191.    
  192.     // If > 0, divide the output resolution by this much.
  193.     public int ResolutionDivisor { get; set; } = 0;
  194.    
  195.     public string AudioCodec { get; set; } = "vorbis";
  196.  
  197.     public TimeSpan Duration => (EndTime - StartTime);
  198.    
  199.     public Vector2 ScaledResolution => (ResolutionDivisor > 0 ? Resolution / ResolutionDivisor : Resolution);
  200. }
  201.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement