/// <summary> /// Joins a list of video files. /// </summary> /// <param name="output">Output video file.</param> /// <param name="videos">List of vides that need to be joined together.</param> /// <returns>Output video information.</returns> public VideoInfo Join(FileInfo output, params VideoInfo[] videos) { FFMpegHelper.OutputExistsExceptionCheck(output); FFMpegHelper.InputsExistExceptionCheck(videos.Select(video => video.ToFileInfo()).ToArray()); var temporaryVideoParts = videos.Select(video => { FFMpegHelper.ConversionSizeExceptionCheck(video); var destinationPath = video.FullName.Replace(video.Extension, FileExtension.Ts); Convert( video, new FileInfo(destinationPath), VideoType.Ts ); return(destinationPath); }).ToList(); var args = ArgumentsStringifier.InputConcat(temporaryVideoParts) + ArgumentsStringifier.Copy() + ArgumentsStringifier.BitStreamFilter(Channel.Audio, Filter.Aac_AdtstoAsc) + ArgumentsStringifier.Output(output); try { if (!RunProcess(args, output)) { throw new FFMpegException(FFMpegExceptionType.Operation, "Could not join the provided video files."); } return(new VideoInfo(output)); } finally { Cleanup(temporaryVideoParts); } }
/// <summary> /// Strips a video file of audio. /// </summary> /// <param name="source">Source video file.</param> /// <param name="output">Output video file.</param> /// <returns></returns> public VideoInfo Mute(VideoInfo source, FileInfo output) { FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output); FFMpegHelper.ConversionSizeExceptionCheck(source); FFMpegHelper.ExtensionExceptionCheck(output, source.Extension); var args = ArgumentsStringifier.Input(source) + ArgumentsStringifier.Copy() + ArgumentsStringifier.Disable(Channel.Audio) + ArgumentsStringifier.Output(output); if (!RunProcess(args, output)) { throw new FFMpegException(FFMpegExceptionType.Operation, "Could not mute the requested video."); } return(new VideoInfo(output)); }
/// <summary> /// Adds audio to a video file. /// </summary> /// <param name="source">Source video file.</param> /// <param name="audio">Source audio file.</param> /// <param name="output">Output video file.</param> /// <param name="stopAtShortest">Indicates if the encoding should stop at the shortest input file.</param> /// <returns>Success state</returns> public VideoInfo ReplaceAudio(VideoInfo source, FileInfo audio, FileInfo output, bool stopAtShortest = false) { FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output); FFMpegHelper.InputsExistExceptionCheck(audio); FFMpegHelper.ConversionSizeExceptionCheck(source); FFMpegHelper.ExtensionExceptionCheck(output, source.Extension); var args = ArgumentsStringifier.Input(source) + ArgumentsStringifier.Input(audio) + ArgumentsStringifier.Copy(Channel.Video) + ArgumentsStringifier.Audio(AudioCodec.Aac, AudioQuality.Hd) + ArgumentsStringifier.FinalizeAtShortestInput(stopAtShortest) + ArgumentsStringifier.Output(output); if (!RunProcess(args, output)) { throw new FFMpegException(FFMpegExceptionType.Operation, "Could not replace the video audio."); } return(new VideoInfo(output)); }
/// <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 VideoInfo Convert( VideoInfo source, FileInfo output, VideoType type = VideoType.Mp4, Speed speed = Speed.SuperFast, VideoSize size = VideoSize.Original, AudioQuality audioQuality = AudioQuality.Normal, bool multithreaded = false) { FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output); FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.ForType(type)); FFMpegHelper.ConversionSizeExceptionCheck(source); string args = ""; var scale = VideoSize.Original == size ? 1 : (double)source.Height / (int)size; var outputSize = new Size( (int)(source.Width / scale), (int)(source.Height / scale) ); if (outputSize.Width % 2 != 0) { outputSize.Width += 1; } switch (type) { case VideoType.Mp4: args = ArgumentsStringifier.Input(source) + ArgumentsStringifier.Threads(multithreaded) + ArgumentsStringifier.Scale(outputSize) + ArgumentsStringifier.Video(VideoCodec.LibX264, 2400) + ArgumentsStringifier.Speed(speed) + ArgumentsStringifier.Audio(AudioCodec.Aac, audioQuality) + ArgumentsStringifier.Output(output); break; case VideoType.Ogv: args = ArgumentsStringifier.Input(source) + ArgumentsStringifier.Threads(multithreaded) + ArgumentsStringifier.Scale(outputSize) + ArgumentsStringifier.Video(VideoCodec.LibTheora, 2400) + ArgumentsStringifier.Speed(16) + ArgumentsStringifier.Audio(AudioCodec.LibVorbis, audioQuality) + ArgumentsStringifier.Output(output); break; case VideoType.Ts: args = ArgumentsStringifier.Input(source) + ArgumentsStringifier.Copy() + ArgumentsStringifier.BitStreamFilter(Channel.Video, Filter.H264_Mp4ToAnnexB) + ArgumentsStringifier.ForceFormat(VideoCodec.MpegTs) + ArgumentsStringifier.Output(output); break; } if (!RunProcess(args, output)) { throw new FFMpegException(FFMpegExceptionType.Conversion, $"The video could not be converted to {Enum.GetName(typeof(VideoType), type)}"); } return(new VideoInfo(output)); }