Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Creates a webm in the directory `$Path` named "`$OutputFile`.webm".
- // Requires ffmpeg be installed and accessible in PATH.
- // Could take a while to encode!
- // =====================
- var config = new EncodeWebmConfig
- {
- Path = @"G:\Movies\Anime\Genocyber (1994) [DVD] [kuchikirukia]",
- SourceFile = "01. Genocyber [DVD 540p Hi10P AC-3 dual-audio][kuchikirukia].mkv",
- TempFile = "input.mkv",
- OutputFile = "genocyber-cockblocked",
- StartTime = DateTime.Parse("00:19:05.324"),
- EndTime = DateTime.Parse("00:19:21.296"),
- Resolution = new Vector2(720, 540),
- ResolutionDivisor = 2, // Divide the resolution by this number to get the output resolution
- WithSubtitles = false,
- WithAudio = false,
- AudioCodec = "vorbis",
- TargetBitrate = 1.8m,
- TwoPassMethod = true,
- UseCrfTwoPass = true,
- Crf = 20, // 0-51, 0 best, 30 default
- NativeAac = false,
- Framerate = 0,
- FastMode = false,
- };
- // Run
- // =====================
- var arguments = CreateVp9FfmpegArgs(config);
- EncodeWebm(config, arguments);
- // Argument generation
- // =====================
- string CreateVp9FfmpegArgs(EncodeWebmConfig config)
- {
- // https://trac.ffmpeg.org/wiki/Encode/VP9
- var sb = new StringBuilder();
- sb.Append(GetBaseVp9Args(config));
- if (config.TwoPassMethod)
- {
- sb.Append($" -pass 1 -an -f null NUL");
- sb.Append($" && ffmpeg");
- sb.Append(GetBaseVp9Args(config));
- sb.Append($" -pass 2");
- }
- if (config.WithAudio)
- {
- // https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio
- if (config.NativeAac)
- {
- sb.Append($" -c:a copy");
- }
- else
- {
- sb.Append($" -c:a {config.AudioCodec} -strict -2");
- }
- }
- else
- {
- sb.Append($" -an");
- }
- sb.Append($" -movflags +faststart \"{config.OutputFile}.webm\"");
- return sb.ToString();
- string GetBaseVp9Args(EncodeWebmConfig config)
- {
- var sb = new StringBuilder();
- sb.Append($" -y -i {config.TempFile}");
- sb.Append($" -c:v libvpx-vp9");
- if (config.TwoPassMethod && config.UseCrfTwoPass)
- {
- sb.Append($" -b:v 0 -crf {config.Crf}");
- }
- else
- {
- // Target bitrate
- sb.Append($" -b:v {config.TargetBitrate:0}M");
- }
- // Framerate
- if (config.Framerate > 0)
- {
- sb.Append($" -r {config.Framerate}");
- }
- sb.Append($" -nostats"); // -loglevel 2");
- // Go fast
- if (config.FastMode)
- {
- sb.Append($" -row-mt 1 -tile-columns 5 -threads 10 -speed 2");
- }
- if (!config.WithSubtitles)
- {
- sb.Append($" -sn");
- }
- else
- {
- // https://trac.ffmpeg.org/wiki/HowToBurnSubtitlesIntoVideo
- // -sn to not include built-in
- sb.Append($" -sn -vf subtitles={config.TempFile}");
- }
- sb.Append($" -ss {config.StartTime.ToString("HH:mm:ss.fff")} -t {config.Duration.ToString(@"hh\:mm\:ss\.fff")}");
- sb.Append($" -s {config.ScaledResolution.X}x{config.ScaledResolution.Y}");
- return sb.ToString();
- }
- }
- void EncodeWebm(EncodeWebmConfig config, string arguments)
- {
- $"ffmpeg {arguments}".Dump();
- var start = DateTime.Now;
- Directory.SetCurrentDirectory(config.Path);
- Util.Cmd($"del {config.TempFile}");
- Util.Cmd($"mklink {config.TempFile} \"{config.SourceFile}\"");
- Util.Cmd($"ffmpeg {arguments}");
- Util.Cmd($"del {config.TempFile}");
- var end = DateTime.Now;
- var duration = end - start;
- $"Job took {duration.ToString()}".Dump();
- }
- class EncodeWebmConfig
- {
- // Root directory we start in. Output will be published here.
- public string Path { get; set; }
- // The video file you want to clip a webm from. Include extension.
- public string SourceFile { get; set; }
- // If you want subtitles, specify it here. If it's an MKV with embedded subtitles, set this to the same as the source file.
- // Commented out - using MKV built-in subs using the TempFile alias
- //public string SubtitlesFile { get; set; }
- // Name of temp file created when processing. Is deleted afterwards. (Actually a symbolic link).
- public string TempFile { get; set; }
- // The name of the output file. Don't include .webm
- public string OutputFile { get; set; }
- // Start time in the video to clip from
- public DateTime StartTime { get; set; }
- // End time in the video to clip to
- public DateTime EndTime { get; set; }
- // Include audio in output
- public bool WithAudio { get; set; } = true;
- // Include subtitles in output
- public bool WithSubtitles { get; set; } = false;
- // Target bitrate. Doesn't apply in two-pass CRF mode.
- public decimal TargetBitrate { get; set; } = 3.0m;
- // Target output video resolution
- public Vector2 Resolution { get; set; }
- // Use the two-pass method (takes longer; better quality).
- // See: https://trac.ffmpeg.org/wiki/Encode/VP9
- public bool TwoPassMethod { get; set; } = false;
- // Is the video using AAC encoding already? Then copy the audio directly into the output.
- public bool NativeAac { get; set; }
- // Target output framerate. Set to zero to be auto.
- public int Framerate { get; set; }
- // Use the CRF method when using the two-pass method.
- public bool UseCrfTwoPass { get; set; }
- // 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"
- // Not sure I believe it, but here's the setting for it.
- public bool FastMode { get; set; }
- // CRF value, 0-51. 0 is lossless.
- public int Crf { get; set; } = 30;
- // If > 0, divide the output resolution by this much.
- public int ResolutionDivisor { get; set; } = 0;
- public string AudioCodec { get; set; } = "vorbis";
- public TimeSpan Duration => (EndTime - StartTime);
- public Vector2 ScaledResolution => (ResolutionDivisor > 0 ? Resolution / ResolutionDivisor : Resolution);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement