private static (FFMpegArguments, Action <FFMpegArgumentOptions> outputOptions) BuildSnapshotArguments(IMediaAnalysis source, Size?size = null, TimeSpan?captureTime = null) { captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3); size = PrepareSnapshotSize(source, size); return(FFMpegArguments .FromFileInput(source, options => options .Seek(captureTime)), options => options .WithVideoCodec(VideoCodec.Png) .WithFrameOutputCount(1) .Resize(size)); }
private static (FFMpegArguments, Action <FFMpegArgumentOptions> outputOptions) BuildSnapshotArguments( string input, IMediaAnalysis source, Size?size = null, TimeSpan?captureTime = null, int?streamIndex = null, int inputFileIndex = 0) { captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3); size = PrepareSnapshotSize(source, size); streamIndex = streamIndex == null ? 0 : source.VideoStreams.FirstOrDefault(videoStream => videoStream.Index == streamIndex).Index; return(FFMpegArguments .FromFileInput(input, false, options => options .Seek(captureTime)), options => options .SelectStream((int)streamIndex, inputFileIndex) .WithVideoCodec(VideoCodec.Png) .WithFrameOutputCount(1) .Resize(size)); }
/// <summary> /// Convert a video do a different format. /// </summary> /// <param name="source">Input video source.</param> /// <param name="output">Output information.</param> /// <param name="type">Target conversion video type.</param> /// <param name="speed">Conversion target speed/quality (faster speed = lower quality).</param> /// <param name="size">Video size.</param> /// <param name="audioQuality">Conversion target audio quality.</param> /// <param name="multithreaded">Is encoding multithreaded.</param> /// <returns>Output video information.</returns> public static bool Convert( string input, string output, ContainerFormat format, Speed speed = Speed.SuperFast, VideoSize size = VideoSize.Original, AudioQuality audioQuality = AudioQuality.Normal, bool multithreaded = false) { FFMpegHelper.ExtensionExceptionCheck(output, format.Extension); var source = FFProbe.Analyse(input); FFMpegHelper.ConversionSizeExceptionCheck(source); var scale = VideoSize.Original == size ? 1 : (double)source.PrimaryVideoStream !.Height / (int)size; var outputSize = new Size((int)(source.PrimaryVideoStream !.Width / scale), (int)(source.PrimaryVideoStream.Height / scale)); if (outputSize.Width % 2 != 0) { outputSize.Width += 1; } return(format.Name switch { "mp4" => FFMpegArguments .FromFileInput(input) .OutputToFile(output, true, options => options .UsingMultithreading(multithreaded) .WithVideoCodec(VideoCodec.LibX264) .WithVideoBitrate(2400) .WithVideoFilters(filterOptions => filterOptions .Scale(outputSize)) .WithSpeedPreset(speed) .WithAudioCodec(AudioCodec.Aac) .WithAudioBitrate(audioQuality)) .ProcessSynchronously(), "ogv" => FFMpegArguments .FromFileInput(input) .OutputToFile(output, true, options => options .UsingMultithreading(multithreaded) .WithVideoCodec(VideoCodec.LibTheora) .WithVideoBitrate(2400) .WithVideoFilters(filterOptions => filterOptions .Scale(outputSize)) .WithSpeedPreset(speed) .WithAudioCodec(AudioCodec.LibVorbis) .WithAudioBitrate(audioQuality)) .ProcessSynchronously(), "mpegts" => FFMpegArguments .FromFileInput(input) .OutputToFile(output, true, options => options .CopyChannel() .WithBitStreamFilter(Channel.Video, Filter.H264_Mp4ToAnnexB) .ForceFormat(VideoType.Ts)) .ProcessSynchronously(), "webm" => FFMpegArguments .FromFileInput(input) .OutputToFile(output, true, options => options .UsingMultithreading(multithreaded) .WithVideoCodec(VideoCodec.LibVpx) .WithVideoBitrate(2400) .WithVideoFilters(filterOptions => filterOptions .Scale(outputSize)) .WithSpeedPreset(speed) .WithAudioCodec(AudioCodec.LibVorbis) .WithAudioBitrate(audioQuality)) .ProcessSynchronously(), _ => throw new ArgumentOutOfRangeException(nameof(format)) });