using DownKyi.Core.Logging; using FFMpegCore; using FFMpegCore.Enums; namespace DownKyi.Core.FFmpeg; public static class FFmpegHelper { private const string Tag = "FFmpegHelper"; /// /// 合并音频和视频 /// /// 音频 /// 视频 /// public static bool MergeVideo(string audio, string video, string destVideo) { if (!File.Exists(audio) && !File.Exists(video)) return false; FFMpegArguments .FromFileInput(audio) .AddFileInput(video) .OutputToFile(destVideo, true, options => options .WithAudioCodec("copy") .WithVideoCodec("copy") .ForceFormat("mp4")) .ProcessSynchronously(); try { if (audio != null) { File.Delete(audio); } if (video != null) { File.Delete(video); } } catch (IOException e) { Console.WriteLine("MergeVideo()发生IO异常: {0}", e); LogManager.Error(Tag, e); } return true; } /// /// 去水印,非常消耗cpu资源 /// /// /// /// /// /// /// /// public static void Delogo(string video, string destVideo, int x, int y, int width, int height, Action action) { var arg = FFMpegArguments .FromFileInput(video) .OutputToFile( destVideo, true, option => option .WithCustomArgument($"-vf delogo=x={x}:y={y}:w={width}:h={height}:show=0 -hide_banner")) .NotifyOnOutput(action.Invoke) .NotifyOnError(action.Invoke) .ProcessSynchronously(); } /// /// 从一个视频中仅提取音频 /// /// 源视频 /// 目标音频 /// 输出信息 public static void ExtractAudio(string video, string audio, Action action) { FFMpegArguments .FromFileInput(video) .OutputToFile(audio, true, options => options .WithCustomArgument("-hide_banner") .WithAudioCodec("copy") .DisableChannel(Channel.Video) ) .NotifyOnOutput(action.Invoke) .NotifyOnError(action.Invoke) .ProcessSynchronously(); } /// /// 从一个视频中仅提取视频 /// /// 源视频 /// 目标视频 /// 输出信息 public static void ExtractVideo(string video, string destVideo, Action action) { FFMpegArguments.FromFileInput(video) .OutputToFile( destVideo, true, options => options .WithCustomArgument("-hide_banner") .WithVideoCodec("copy") .DisableChannel(Channel.Audio)) .NotifyOnOutput(action.Invoke) .NotifyOnError(action.Invoke) .ProcessSynchronously(); } }