public static Guid ComputeOverlay(string sourceFilePath) { FileContainer fileContainer = FileContainer.NewOverlayContainer(sourceFilePath); var processStartInfo = new ProcessStartInfo(); processStartInfo.WorkingDirectory = TempFileManager.GetTempDirectory(); processStartInfo.UseShellExecute = false; processStartInfo.ErrorDialog = false; processStartInfo.CreateNoWindow = true; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; string oldFilePath = fileContainer.SourceFileItem.FilePath; string outputFilePath = null; try { LogManager.AddOverlayMessage("SourceFileName " + Path.GetFileName(oldFilePath), "Start Crop"); // resize + crop source image outputFilePath = Path.ChangeExtension(TempFileManager.GetNewTempFilePath(), ".png"); processStartInfo.FileName = Path.Combine(FrontSettings.ImageMagickPath, "convert"); processStartInfo.Arguments = $"{Path.GetFileName(fileContainer.SourceFileItem.FilePath)} -resize \"{_finalWidth}x{_finalHeight}^\" -gravity Center -crop {_finalWidth}x{_finalHeight}+0+0 {Path.GetFileName(outputFilePath)}"; StartProcess(processStartInfo, 5000); fileContainer.SourceFileItem.FilePath = outputFilePath; LogManager.AddOverlayMessage("OutputFileName " + Path.GetFileName(outputFilePath), "End Crop"); IpfsDaemon.Queue(fileContainer.SourceFileItem); } catch (Exception ex) { TempFileManager.SafeDeleteTempFile(outputFilePath); LogManager.AddOverlayMessage(ex.ToString(), "Exception"); return(fileContainer.ProgressToken); } finally { TempFileManager.SafeDeleteTempFile(oldFilePath); } try { LogManager.AddOverlayMessage("SourceFileName " + Path.GetFileName(fileContainer.SourceFileItem.FilePath), "Start Overlay"); // watermark source image outputFilePath = Path.ChangeExtension(TempFileManager.GetNewTempFilePath(), ".png"); processStartInfo.FileName = Path.Combine(FrontSettings.ImageMagickPath, "composite"); processStartInfo.Arguments = $"-gravity NorthEast {_overlayImagePath} {Path.GetFileName(fileContainer.SourceFileItem.FilePath)} {Path.GetFileName(outputFilePath)}"; StartProcess(processStartInfo, 5000); fileContainer.OverlayFileItem.FilePath = outputFilePath; LogManager.AddOverlayMessage("OutputFileName " + Path.GetFileName(outputFilePath), "End Overlay"); IpfsDaemon.Queue(fileContainer.OverlayFileItem); } catch (Exception ex) { TempFileManager.SafeDeleteTempFile(outputFilePath); LogManager.AddOverlayMessage(ex.ToString(), "Exception"); return(fileContainer.ProgressToken); } return(fileContainer.ProgressToken); }
public void StartProcess(string arguments, int timeout) { var processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = "ffmpeg"; processStartInfo.RedirectStandardError = true; processStartInfo.WorkingDirectory = TempFileManager.GetTempDirectory(); processStartInfo.UseShellExecute = false; processStartInfo.ErrorDialog = false; processStartInfo.CreateNoWindow = true; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; processStartInfo.Arguments = arguments; if (_fileItem.TypeFile == TypeFile.SpriteVideo) { LogManager.AddSpriteMessage(processStartInfo.FileName + " " + processStartInfo.Arguments, "Launch command"); } else { LogManager.AddEncodingMessage(processStartInfo.FileName + " " + processStartInfo.Arguments, "Launch command"); } using (Process process = Process.Start(processStartInfo)) { process.ErrorDataReceived += new DataReceivedEventHandler(ErrorDataReceived); process.BeginErrorReadLine(); bool success = process.WaitForExit(timeout); if (!success) { throw new InvalidOperationException("Timeout : Le fichier n'a pas pu être encodé dans le temps imparti."); } if (process.ExitCode != 0) { throw new InvalidOperationException($"Le fichier n'a pas pu être encodé, erreur {process.ExitCode}."); } } }
public static void Add(FileItem fileItem) { try { currentFileItem = fileItem; LogManager.AddIpfsMessage(LogLevel.Information, "FileName " + Path.GetFileName(currentFileItem.OutputFilePath), "Start"); currentFileItem.IpfsHash = null; currentFileItem.IpfsProcess.StartProcessDateTime(); // Send to ipfs and return hash from ipfs var processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = "ipfs"; processStartInfo.Arguments = $"add {Path.GetFileName(currentFileItem.OutputFilePath)}"; if (IpfsSettings.Instance.VideoAndSpriteTrickleDag) { if (currentFileItem.TypeFile == TypeFile.SourceVideo || currentFileItem.TypeFile == TypeFile.EncodedVideo || currentFileItem.TypeFile == TypeFile.SpriteVideo) { processStartInfo.Arguments = $"add -t {Path.GetFileName(currentFileItem.OutputFilePath)}"; } } processStartInfo.RedirectStandardOutput = true; processStartInfo.RedirectStandardError = true; processStartInfo.WorkingDirectory = TempFileManager.GetTempDirectory(); processStartInfo.UseShellExecute = false; processStartInfo.ErrorDialog = false; processStartInfo.CreateNoWindow = true; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; LogManager.AddIpfsMessage(LogLevel.Information, processStartInfo.FileName + " " + processStartInfo.Arguments, "Launch command"); using (Process process = Process.Start(processStartInfo)) { process.OutputDataReceived += new DataReceivedEventHandler(OutputDataReceived); process.ErrorDataReceived += new DataReceivedEventHandler(ErrorDataReceived); process.BeginOutputReadLine(); process.BeginErrorReadLine(); bool success = process.WaitForExit(IpfsSettings.Instance.IpfsTimeout * 1000); if (!success) { throw new InvalidOperationException("Timeout : Le fichier n'a pas pu être envoyé à ipfs dans le temps imparti."); } if (process.ExitCode != 0) { throw new InvalidOperationException($"Le fichier n'a pas pu être envoyé à ipfs, erreur {process.ExitCode}."); } } currentFileItem.IpfsProcess.EndProcessDateTime(); LogManager.AddIpfsMessage(LogLevel.Information, "Hash " + currentFileItem.IpfsHash + " / FileSize " + currentFileItem.FileSize, "End"); } catch (Exception ex) { string message = "FileSize " + currentFileItem.FileSize + " / Progress " + currentFileItem.IpfsProcess.Progress; currentFileItem.IpfsProcess.SetErrorMessage("Exception non gérée", message, ex); } }
public static bool Encode(FileItem fileItem) { string newEncodedFilePath = null; try { currentFileItem = fileItem; currentFileItem.EncodeProgress = "0.00%"; FileItem sourceFile = currentFileItem.FileContainer.SourceFileItem; string sourceFilePath = sourceFile.FilePath; newEncodedFilePath = Path.ChangeExtension(TempFileManager.GetNewTempFilePath(), ".mp4"); LogManager.AddEncodingMessage("FileName " + Path.GetFileName(newEncodedFilePath), "Start"); VideoSize videoSize = currentFileItem.VideoSize; Debug.WriteLine(Path.GetFileName(sourceFilePath) + " / " + videoSize); var processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = "ffmpeg"; processStartInfo.RedirectStandardError = true; processStartInfo.WorkingDirectory = TempFileManager.GetTempDirectory(); processStartInfo.UseShellExecute = false; processStartInfo.ErrorDialog = false; processStartInfo.CreateNoWindow = true; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; // Récupérer la durée totale de la vidéo et sa résolution if (!sourceFile.VideoDuration.HasValue) { string imageOutput = Path.ChangeExtension(sourceFilePath, ".jpeg"); processStartInfo.Arguments = $"-y -i {Path.GetFileName(sourceFilePath)} -vf fps=1 -vframes 1 {Path.GetFileName(imageOutput)}"; StartProcess(processStartInfo, VideoSettings.EncodeGetOneImageTimeout); using (Image image = Image.FromFile(imageOutput)) { sourceFile.VideoWidth = image.Width; sourceFile.VideoHeight = image.Height; } TempFileManager.SafeDeleteTempFile(imageOutput); } // Si durée totale de vidéo, largeur hauteur non récupéré, on ne peut pas continuer if ((sourceFile.VideoDuration ?? 0) <= 0) { return(false); } if ((sourceFile.VideoHeight ?? 0) <= 0) { return(false); } if ((sourceFile.VideoHeight ?? 0) <= 0) { return(false); } int duration = sourceFile.VideoDuration.Value; // Désactivation encoding et sprite si dépassement de la durée maximale if (duration > VideoSettings.MaxVideoDurationForEncoding) { currentFileItem.EncodeErrorMessage = "Disable because duration reach the max limit."; currentFileItem.FileContainer.EncodedFileItems.Clear(); currentFileItem.FileContainer.DeleteSpriteVideo(); return(false); } switch (currentFileItem.TypeFile) { case TypeFile.SpriteVideo: { int nbImages = VideoSettings.NbSpriteImages; int heightSprite = VideoSettings.HeightSpriteImages; // Calculer nb image/s // si < 100s de vidéo -> 1 image/s // sinon (nb secondes de la vidéo / 100) image/s string frameRate = "1"; if (duration > nbImages) { frameRate = $"{nbImages}/{duration}"; //frameRate = inverse de image/s } int spriteWidth = GetWidth(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, heightSprite); string sizeImageMax = $"scale={spriteWidth}:{heightSprite}"; // Extract frameRate image/s de la video string pattern = GetPattern(newEncodedFilePath); processStartInfo.Arguments = $"-y -i {Path.GetFileName(sourceFilePath)} -r {frameRate} -vf \"{sizeImageMax}\" -f image2 {pattern}"; StartProcess(processStartInfo, VideoSettings.EncodeGetImagesTimeout); break; } case TypeFile.EncodedVideo: { string size; switch (videoSize) { case VideoSize.F360p: { Tuple <int, int> finalSize = GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 640, 360); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } case VideoSize.F480p: { Tuple <int, int> finalSize = GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 854, 480); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } case VideoSize.F720p: { Tuple <int, int> finalSize = GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 1280, 720); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } case VideoSize.F1080p: { Tuple <int, int> finalSize = GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 1920, 1080); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } default: throw new InvalidOperationException("Format non reconnu."); } string formatEncode = "libx264"; if (VideoSettings.GpuEncodeMode) { string maxRate = string.Empty; formatEncode = "h264_nvenc"; switch (videoSize) { case VideoSize.F360p: maxRate = "200k"; break; case VideoSize.F480p: maxRate = "500k"; break; case VideoSize.F720p: maxRate = "1000k"; break; case VideoSize.F1080p: maxRate = "1600k"; break; default: throw new InvalidOperationException("Format non reconnu."); } processStartInfo.Arguments = $"-y -i {Path.GetFileName(sourceFilePath)} -vcodec {formatEncode} -vf \"scale={size},format=yuv420p\" -b:v {maxRate} -maxrate {maxRate} -bufsize {maxRate} -acodec aac {Path.GetFileName(newEncodedFilePath)}"; } else { processStartInfo.Arguments = $"-y -i {Path.GetFileName(sourceFilePath)} -vcodec {formatEncode} -vf \"scale={size},format=yuv420p\" -acodec aac {Path.GetFileName(newEncodedFilePath)}"; } StartProcess(processStartInfo, VideoSettings.EncodeTimeout); break; } default: throw new InvalidOperationException("type non prévu"); } currentFileItem.FilePath = newEncodedFilePath; currentFileItem.EncodeProgress = "100.00%"; switch (currentFileItem.TypeFile) { case TypeFile.SpriteVideo: LogManager.AddEncodingMessage("Video Duration " + duration + " / SourceVideoFileSize " + currentFileItem.FileContainer.SourceFileItem.FileSize, "End Extract Images"); break; case TypeFile.EncodedVideo: LogManager.AddEncodingMessage("Video Duration " + duration + " / FileSize " + currentFileItem.FileSize + " / Format " + videoSize, "End Encoding"); break; default: throw new InvalidOperationException("type non prévu"); } return(true); } catch (Exception ex) { LogManager.AddEncodingMessage("Video Duration " + currentFileItem.VideoDuration + " / FileSize " + currentFileItem.FileSize + " / Progress " + currentFileItem.EncodeProgress + " / Exception : " + ex, "Exception"); currentFileItem.EncodeErrorMessage = ex.Message; TempFileManager.SafeDeleteTempFile(newEncodedFilePath); if (currentFileItem.VideoSize != VideoSize.Source) { TempFileManager.SafeDeleteTempFile(currentFileItem.FilePath); } if (currentFileItem.TypeFile == TypeFile.SpriteVideo) { string[] files = EncodeManager.GetListImageFrom(newEncodedFilePath); // récupération des images TempFileManager.SafeDeleteTempFiles(files); // suppression des images } return(false); } }