public bool MediaConvertPCM_S16E(string input, string output, int sampleRate) { try { if (!FFmpegService.FFmpegExists) { throw new FFmpegNotFoundException(); } FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder(); fFmpegArgsBuilder.GlobalOptionArgs .OverwriteOutput() .SetThreadQueueSize(512); fFmpegArgsBuilder.SetInputFile(input); fFmpegArgsBuilder.SetOutputFile(output) //.SetAudioFormat(AudioFormat.s16le) .SetAudioCodec(FFmpegAudioCodec.pcm_s16le) .SetAudioFrequency(sampleRate) .SetAudioChannels(2) ; FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args); return(true); } catch { return(false); } }
public Stream ReadVideoFrame(TimeSpan seek, Size?size) { this.Dispose(); try { FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder(); fFmpegArgsBuilder.GlobalOptionArgs .SetThreadQueueSize(512) ; fFmpegArgsBuilder.SetInputFile(this.filePath) .SeekAccurate() .ReadByNativeFrame() .SetSeek(seek) ; var outputOptionArgs = fFmpegArgsBuilder.SetOutputImagePipe(videoPipeName) .SetPixFormat(Formats.FFmpegPixFormat.rgb24) .SetOutputVideoFrame(1) .SetVideoFormat(FFmpegVideoFormat.image2) .SetFramerate(this.FPS) ; if (size != null) { outputOptionArgs .SetVideoSize(size.Value); } this.ffmpegProcess = FFmpegService.StartFFmpegStandardOutput(fFmpegArgsBuilder.Args); return(this.ffmpegProcess.StandardOutput.BaseStream); } catch { } return(null); }
public bool MediaCut(string input, string output, TimeSpan start, TimeSpan?end = null) { try { if (!FFmpegService.FFmpegExists) { throw new FFmpegNotFoundException(); } FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder(); fFmpegArgsBuilder.GlobalOptionArgs .OverwriteOutput() .SetThreadQueueSize(512); var inputOptionArgs = fFmpegArgsBuilder.SetInputFile(input) .SetSeek(start); var outputOptionArgs = fFmpegArgsBuilder.SetOutputFile(input) ; if (end != null) { outputOptionArgs .SetSeekEnd(end.Value) .SetAudioCodec(Codecs.FFmpegAudioCodec.copy) .SetVideoCodec(Codecs.FFmpegVideoCodec.copy); } FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args); return(true); } catch { return(false); } }
/// <inheritdoc /> public void Dispose() { _ffMpegWriter.Dispose(); var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputFile(_tempFileName); var output = argsBuilder.AddOutputFile(_args.FileName) .AddArg(_args.VideoArgsProvider(_args.VideoQuality)) .SetFrameRate(_args.FrameRate); if (_args.AudioProvider != null) { output.AddArg(_args.AudioArgsProvider(_args.AudioQuality)); } output.AddArg(_args.OutputArgs); var process = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), _args.FileName); process.WaitForExit(); File.Delete(_tempFileName); }
public Task GenerateSubTitles( string filePath, string subtitleFinalPath, double seconds, int index, double subsDelayInSeconds, CancellationToken token) { try { _fileService.DeleteFilesInDirectory(Path.GetDirectoryName(subtitleFinalPath)); var builder = new FFmpegArgsBuilder(); builder.AddInputFile(filePath).BeQuiet().SetAutoConfirmChanges().TrySetSubTitleEncoding(FileFormatConstants.AllowedSubtitleFormats); builder.AddOutputFile(subtitleFinalPath) .Seek(Math.Floor(seconds)) .SetMap(index) .SetDelayInSeconds(subsDelayInSeconds) .SetFormat("webvtt"); string cmd = builder.GetArgs(); _logger.LogInformation($"{nameof(GenerateSubTitles)}: Generating subtitles for file = {filePath}. CMD = {cmd}"); return(Task.Run(() => { var process = new Process { EnableRaisingEvents = true, StartInfo = new ProcessStartInfo { FileName = _fileService.GetFFmpegPath(), UseShellExecute = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden } }; process.StartInfo.Arguments = cmd; process.Start(); process.WaitForExit(); if (process.ExitCode > 0) { _logger.LogError($"{nameof(GenerateSubTitles)}: Could not generate subs for file = {filePath}."); } else if (process.ExitCode < 0) { _logger.LogInformation($"{nameof(GenerateSubTitles)}: Process was killed for file = {filePath}"); } else { _logger.LogInformation($"{nameof(GenerateSubTitles)}: Subs where generated for file = {filePath}"); } }, token)); } catch (Exception e) { _logger.LogError(e, $"{nameof(GenerateSubTitles)}: Unknown error"); _telemetryService.TrackError(e); return(Task.CompletedTask); } }
public string GetThumbnail(string mrl) { if (!_fileService.IsLocalFile(mrl)) { _logger.LogWarning($"{nameof(GetThumbnail)}: Cant get thumbnail for file = {mrl}. Its not a local file"); return(null); } var filename = Path.GetFileName(mrl); var thumbnailPath = _fileService.GetFirstThumbnailFilePath(filename); if (File.Exists(thumbnailPath)) { return(thumbnailPath); } var builder = new FFmpegArgsBuilder(); builder.AddInputFile(mrl).BeQuiet().SetAutoConfirmChanges().DisableAudio(); var outputArgs = builder.AddOutputFile(thumbnailPath); if (!_fileService.IsMusicFile(mrl)) { outputArgs.WithVideoFilter(@"select=gt(scene\,0.4)") .SetVideoFrames(1) .WithVideoFilter("fps=1/60"); } try { string cmd = builder.GetArgs(); _logger.LogInformation($"{nameof(GetThumbnail)}: Generating first thumbnail for file = {mrl}. Cmd = {cmd}"); _checkGenerateThumbnailProcess = true; _generateThumbnailProcess.StartInfo.Arguments = cmd; _generateThumbnailProcess.Start(); _generateThumbnailProcess.WaitForExit(); if (_generateThumbnailProcess.ExitCode != 0) { _logger.LogWarning($"{nameof(GetThumbnail)}: Couldn't retrieve the first thumbnail for file = {mrl}."); return(null); } _logger.LogInformation($"{nameof(GetThumbnail)}: First thumbnail was successfully generated for file = {mrl}"); } catch (Exception ex) { _logger.LogError(ex, $"{nameof(GenerateThumbnails)}: Unknown error occurred"); _telemetryService.TrackError(ex); } finally { _checkGenerateThumbnailProcess = false; } return(thumbnailPath); }
/// <summary> /// 这个算法还没有完成 用来获取Duration还是可以的 /// </summary> /// <param name="filePath"></param> public void Open(string filePath) { FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder(); fFmpegArgsBuilder.SetInputFile(filePath); StreamReader streamReader = FFmpegService.StartFFmpegErrorStream(fFmpegArgsBuilder.Args); string line = string.Empty; line = streamReader.ReadToEnd(); string regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s"; string regexVideo = "Video: (.*?), (.*?), (\\d*x\\d*).*?, (.*?) kb/s, (.*?)[,\\s]"; string regexAudio = "Audio: (.*?), (.*?) Hz, (.*?), (.*?), (.*?) kb/s"; Regex regex; Match match; regex = new Regex(regexDuration); match = regex.Match(line); if (match.Groups.Count == 4) { if (TimeSpan.TryParse(match.Groups[1].Value, out TimeSpan timeSpan)) { this.Duration = timeSpan; } this.Bitrate = regex.Match(line).Groups[3].Value; } regex = new Regex(regexVideo); match = regex.Match(line); if (match.Groups.Count == 6) { this.VideoFormat = regex.Match(line).Groups[1].Value; this.PixFormat = regex.Match(line).Groups[2].Value; this.Width = int.Parse(regex.Match(line).Groups[3].Value.Split('x')[0]); this.Height = int.Parse(regex.Match(line).Groups[3].Value.Split('x')[1]); this.VideoBitrate = regex.Match(line).Groups[4].Value; if (double.TryParse(regex.Match(line).Groups[5].Value, out double framerate)) { this.Framerate = framerate; } } regex = new Regex(regexAudio); match = regex.Match(line); if (match.Groups.Count == 6) { this.AudioFormat = regex.Match(line).Groups[1].Value; if (int.TryParse(regex.Match(line).Groups[2].Value, out int audioFrequency)) { this.AudioFrequency = audioFrequency; } this.AudioBitrate = regex.Match(line).Groups[5].Value; } }
private void GenerateGif(string paletteFile) { var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputFile(_tempFileName); argsBuilder.AddInputFile(paletteFile); argsBuilder.AddOutputFile(_args.FileName) .AddArg("-lavfi paletteuse") .SetFrameRate(_args.FrameRate); var process = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), _args.FileName); process.WaitForExit(); }
public bool Open(string filePath) { try { FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder(); fFmpegArgsBuilder.GlobalOptionArgs .OverwriteOutput() .SetThreadQueueSize(512); fFmpegArgsBuilder.SetInputPipe(videoPipeName) .SetFramerate(this.VideoWriterArgs.FrameRate) .SetVideoFormat(FFmpegVideoFormat.rawvideo) .SetPixFormat(FFmpegPixFormat.rgb32) .SetVideoSize(this.VideoWriterArgs.Width, this.VideoWriterArgs.Height) ; var outputOptionArgs = fFmpegArgsBuilder.SetOutputFile(filePath) .SetFramerate(this.VideoWriterArgs.FrameRate) .SetFileLength(CommonWriterArgs.FileLength ?? 0, () => CommonWriterArgs.FileLength != null) .SetVideoSize((int)(this.VideoWriterArgs.Width * this.VideoWriterArgs.ScaleWidth), (int)(this.VideoWriterArgs.Height * this.VideoWriterArgs.ScaleHeight)) ; ((VideoCodecBase)this.VideoWriterArgs.VideoCodec).Apply(this.VideoWriterArgs, outputOptionArgs); var videoBufferSize = this.VideoWriterArgs.Width * this.VideoWriterArgs.Height * 4; this.videoPipeWrite = new PipeServerWrite(videoPipeName, videoBufferSize); if (this.Audioable) { fFmpegArgsBuilder.SetInputPipe(audioPipeName) .SetAudioFormat(FFmpegAudioFormat.s16le) .SetAudioCodec(FFmpegAudioCodec.pcm_s16le) .SetAudioFrequency(16000) .SetAudioChannels(2); outputOptionArgs .SetAudioFrequency(this.AudioWriterArgs.AudioFrequency) .SetAudioChannels(this.AudioWriterArgs.AudioChannels) ; ((AudioCodecBase)this.AudioWriterArgs.AudioCodec).Apply(this.AudioWriterArgs, outputOptionArgs); var audioBufferSize = (int)((1000.0 / this.VideoWriterArgs.FrameRate) * (44100 / 100.0) * 2 * 2 * 2); this.audioPipeWrite = new PipeServerWrite(audioPipeName, audioBufferSize); } this.ffmpegProcess = FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args); return(true); } catch (Exception ex) { return(false); } }
public FFmpegAudioWriter(string fileName, int audioQuality, FFmpegAudioArgsProvider audioArgsProvider, int frequency = 44100, int channels = 2) { var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddStdIn() .SetFormat("s16le") .SetAudioCodec("pcm_s16le") .SetAudioFrequency(frequency) .SetAudioChannels(channels) .DisableVideo(); argsBuilder.AddOutputFile(fileName) .AddArg(audioArgsProvider(audioQuality)); _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), fileName); _ffmpegIn = _ffmpegProcess.StandardInput.BaseStream; }
private string GenerateCmdForThumbnails(string mrl, string thumbnailPath, bool useHwAccel) { var builder = new FFmpegArgsBuilder(); var inputArgs = builder.AddInputFile(mrl).SetAutoConfirmChanges().DisableAudio(); var outputArgs = builder.AddOutputFile(thumbnailPath); if (useHwAccel) { //This might fail sometimes because the device does not support qsv or because the main display is not connected to the Intel GPU inputArgs.SetHwAccel(HwAccelDeviceType.Intel).SetVideoCodec(HwAccelDeviceType.Intel); outputArgs.SetVideoCodec("mjpeg_qsv").SetFilters($"fps=1/5,scale_qsv={ThumbnailScale}"); } else { outputArgs.SetFilters($"fps=1/5,scale={ThumbnailScale}"); } return(builder.GetArgs()); }
private string BuildAudioTranscodeCmd(string filePath, double seconds, int audioStreamIndex, bool audioNeedsTranscode) { var builder = new FFmpegArgsBuilder(); builder.AddInputFile(filePath).BeQuiet().SetAutoConfirmChanges().Seek(seconds); var outputArgs = builder.AddOutputPipe().SetMap(audioStreamIndex).SetPreset("ultrafast"); if (audioNeedsTranscode) { outputArgs.SetAudioCodec("aac").SetAudioBitrate(128); } else { outputArgs.SetAudioCodec("copy"); } //To generate an aac output you need to set adts outputArgs.SetAudioChannels(2).SetFormat("adts"); return(builder.GetArgs()); }
private string GeneratePalette() { var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputFile(_tempFileName); var tempFile = Path.GetTempFileName(); var paletteFile = Path.ChangeExtension(tempFile, "png"); File.Move(tempFile, paletteFile); argsBuilder.AddOutputFile(paletteFile) .AddArg("-vf palettegen") .SetFrameRate(_args.FrameRate) .AddArg("-y"); var process = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), paletteFile); process.WaitForExit(); return(paletteFile); }
public bool MediaConvertAuto(string input, string output) { try { if (!FFmpegService.FFmpegExists) { throw new FFmpegNotFoundException(); } FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder(); fFmpegArgsBuilder.GlobalOptionArgs .OverwriteOutput() .SetThreadQueueSize(512); fFmpegArgsBuilder.SetInputFile(input); fFmpegArgsBuilder.SetOutputFile(output); FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args); return(true); } catch { return(false); } }
private static string BuildVideoTranscodeCmd( TranscodeVideoFile options, double?from = null, double?to = null) { var builder = new FFmpegArgsBuilder(); var inputArgs = builder.AddInputFile(options.FilePath) .BeQuiet() .SetVSync(0) .SetAutoConfirmChanges() .SetHwAccel(options.HwAccelDeviceType) .SetVideoCodec(options.HwAccelDeviceType); var outputArgs = builder.AddOutputPipe() .SetPreset(options.HwAccelDeviceType) .AddArg("map_metadata", -1) .AddArg("map_chapters", -1); //for some reason the chromecast doesnt like chapters o.o if (options.VideoStreamIndex >= 0) { outputArgs.SetMap(options.VideoStreamIndex); } if (options.AudioStreamIndex >= 0) { outputArgs.SetMap(options.AudioStreamIndex); } if (options.Seconds > 0 && !from.HasValue && !to.HasValue) { inputArgs.Seek(options.Seconds); } if (from.HasValue) { outputArgs.Seek(from.Value); } if (to.HasValue) { outputArgs.To(to.Value); } if (options.ForceVideoTranscode) { outputArgs.SetVideoCodec(options.HwAccelDeviceType).SetProfileVideo("main").SetLevel(4).SetPixelFormat(options.HwAccelDeviceType); if (options.VideoScaleType != VideoScaleType.Original) { int videoScale = (int)options.VideoScaleType; switch (options.HwAccelDeviceType) { case HwAccelDeviceType.Intel: outputArgs.AddArg("global_quality", 25) .AddArg("look_ahead", 1) .SetFilters($"scale_qsv=trunc(oh*a/2)*2:{videoScale}"); break; case HwAccelDeviceType.Nvidia: string scale = options.VideoScaleType == VideoScaleType.Hd ? "1280x720" : "1920x1080"; if (scale != options.VideoWidthAndHeight && !string.IsNullOrWhiteSpace(options.VideoWidthAndHeight)) { inputArgs.AddArg("resize", scale); } break; case HwAccelDeviceType.None: outputArgs.SetFilters($"scale=trunc(oh*a/2)*2:{videoScale}"); break; case HwAccelDeviceType.AMD: break; default: throw new ArgumentOutOfRangeException(); } } } else { outputArgs.CopyVideoCodec(); } if (options.ForceAudioTranscode) { outputArgs.SetAudioCodec("aac").SetAudioBitrate(128).SetAudioChannels(2); } else { outputArgs.CopyAudioCodec(); } outputArgs.SetMovFlagToTheStart().SetFormat("mp4"); return(builder.GetArgs()); }
public IEnumerable <VideoFrameArgs> ReadVideoFrames(TimeSpan?seek = null, TimeSpan?seekEnd = null, Size?size = null, bool readByNativeFrame = true, CancellationToken?cancellationToken = null) { this.Dispose(); TimeSpan startSeek = seek ?? TimeSpan.FromSeconds(0); FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder(); fFmpegArgsBuilder.GlobalOptionArgs .SetThreadQueueSize(512) .SetNoStandardInput() ; var inputOptionArgs = fFmpegArgsBuilder.SetInputFile(this.filePath) .SeekAccurate() .SetSeek(startSeek) .ReadByNativeFrame(() => readByNativeFrame) ; var outputOptionArgs = fFmpegArgsBuilder.SetOutputImagePipe(videoPipeName) .SetVideoFormat(FFmpegVideoFormat.image2pipe) .SetVideoCodec(FFmpegVideoCodec.rawvideo) .SetPixFormat(Formats.FFmpegPixFormat.rgb24) .SetFramerate(this.FPS) .SetSeekEnd(seekEnd ?? TimeSpan.MinValue, () => seekEnd != null) .SetVideoSize(this.GetSize(size)) ; this.ffmpegProcess = FFmpegService.StartFFmpegStandardOutput(fFmpegArgsBuilder.Args); cancellationToken?.Register(() => { this.Dispose(); }); int frameIndex = (int)(startSeek.TotalMilliseconds / (1000.0 / this.FPS)); Size bitmapSize = this.GetSize(size); byte[] frameDataBuffer = new byte[bitmapSize.Width * bitmapSize.Height * 3]; byte[] buffer = new byte[32768]; //ffmpeg的缓冲区大小被限定在32k 32768 似乎没有办法修改? int read; int readed = 0; while ((read = this.ffmpegProcess.StandardOutput.BaseStream.Read(buffer, 0, Math.Min(buffer.Length, frameDataBuffer.Length - readed))) > 0) { if (cancellationToken?.IsCancellationRequested ?? false) { this.Dispose(); yield break; } Array.Copy(buffer, 0, frameDataBuffer, readed, read); readed += read; if (readed == frameDataBuffer.Length) { //对每一个像素的颜色进行转化 for (int i = 0; i < frameDataBuffer.Length; i += 3) { byte temp = frameDataBuffer[i + 2]; frameDataBuffer[i + 2] = frameDataBuffer[i]; frameDataBuffer[i] = temp; } yield return(new VideoFrameArgs(frameIndex++, frameDataBuffer)); readed = 0; } } }
/// <summary> /// Creates a new instance of <see cref="FFmpegWriter"/>. /// </summary> public FFmpegWriter(FFmpegVideoWriterArgs args) { var settings = ServiceProvider.Get <FFmpegSettings>(); _videoBuffer = new byte[args.ImageProvider.Width * args.ImageProvider.Height * 4]; Console.WriteLine($"Video Buffer Allocated: {_videoBuffer.Length}"); var videoPipeName = GetPipeName(); var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputPipe(videoPipeName) .AddArg("-thread_queue_size 512") .AddArg($"-framerate {args.FrameRate}") .SetFormat("rawvideo") .AddArg("-pix_fmt rgb32") .SetVideoSize(args.ImageProvider.Width, args.ImageProvider.Height); var output = argsBuilder.AddOutputFile(args.FileName) .AddArg(args.VideoArgsProvider(args.VideoQuality)) .SetFrameRate(args.FrameRate); if (settings.Resize) { var width = settings.ResizeWidth; var height = settings.ResizeHeight; if (width % 2 == 1) { ++width; } if (height % 2 == 1) { ++height; } output.AddArg($"-vf scale={width}:{height}"); } if (args.AudioProvider != null) { var audioPipeName = GetPipeName(); argsBuilder.AddInputPipe(audioPipeName) .AddArg("-thread_queue_size 512") .SetFormat("s16le") .SetAudioCodec("pcm_s16le") .SetAudioFrequency(args.Frequency) .SetAudioChannels(args.Channels); output.AddArg(args.AudioArgsProvider(args.AudioQuality)); // UpdatePeriod * Frequency * (Bytes per Second) * Channels * 2 var audioBufferSize = (int)((1000.0 / args.FrameRate) * 44.1 * 2 * 2 * 2); _audioPipe = new NamedPipeServerStream(audioPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, audioBufferSize); } _ffmpegIn = new NamedPipeServerStream(videoPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, _videoBuffer.Length); output.AddArg(args.OutputArgs); _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), args.FileName); }