private static void Start() { for (int i = 0; i < VideoSettings.NbSpriteDaemon; i++) { Task daemon = Task.Run(() => { while (true) { FileItem fileItem = null; try { Thread.Sleep(1000); fileItem = null; if (!queueFileItems.TryDequeue(out fileItem)) { continue; } CurrentPositionInQueue++; // si le client a pas demandé le progress depuis plus de 20s, annuler l'opération if ((DateTime.UtcNow - fileItem.FileContainer.LastTimeProgressRequested).TotalSeconds > FrontSettings.MaxGetProgressCanceled) { fileItem.EncodeErrorMessage = "Canceled"; fileItem.EncodeProgress = null; fileItem.IpfsErrorMessage = "Canceled"; fileItem.IpfsProgress = null; LogManager.AddSpriteMessage("SourceFileName " + Path.GetFileName(fileItem.FileContainer.SourceFileItem.FilePath) + " car dernier getProgress a dépassé 20s", "Annulation"); fileItem.CleanFiles(); } else { // sprite creation video if (SpriteManager.Encode(fileItem)) { IpfsDaemon.Queue(fileItem); } } } catch (Exception ex) { LogManager.AddSpriteMessage(ex.ToString(), "Exception non gérée"); fileItem.EncodeErrorMessage = "Exception non gérée"; fileItem.CleanFiles(); } } }); daemons.Add(daemon); } }
private static void Start() { daemon = Task.Run(() => { while (true) { FileItem fileItem = null; try { Thread.Sleep(1000); fileItem = null; if (!queueFileItems.TryDequeue(out fileItem)) { continue; } CurrentPositionInQueue++; // Si le client a pas demandé le progress depuis moins de 20s, annuler l'opération if ((DateTime.UtcNow - fileItem.FileContainer.LastTimeProgressRequested).TotalSeconds > FrontSettings.MaxGetProgressCanceled) { fileItem.IpfsErrorMessage = "Canceled"; fileItem.IpfsProgress = null; LogManager.AddIpfsMessage("FileName " + Path.GetFileName(fileItem.FilePath) + " car dernier getProgress a dépassé 20s", "Annulation"); } else { // Ipfs add file IpfsAddManager.Add(fileItem); } } catch (Exception ex) { LogManager.AddIpfsMessage(ex.ToString(), "Exception non gérée"); fileItem.IpfsErrorMessage = "Exception non gérée"; } fileItem.CleanFiles(); } }); }
public static bool CheckAndAnalyseSource(FileItem fileItem, bool spriteMode) { FileItem sourceFile = fileItem.FileContainer.SourceFileItem; // Récupérer la durée totale de la vidéo et sa résolution if (!sourceFile.VideoDuration.HasValue) { lock (sourceFile) { if (!sourceFile.VideoDuration.HasValue) { string imageOutputPath = Path.ChangeExtension(TempFileManager.GetNewTempFilePath(), ".jpeg"); try { var ffmpegProcessManager = new FfmpegProcessManager(fileItem); string argumentsImage = $"-y -i {Path.GetFileName(sourceFile.FilePath)} -vf fps=1 -vframes 1 {Path.GetFileName(imageOutputPath)}"; ffmpegProcessManager.StartProcess(argumentsImage, VideoSettings.EncodeGetOneImageTimeout); using (Image image = Image.FromFile(imageOutputPath)) { sourceFile.VideoWidth = image.Width; sourceFile.VideoHeight = image.Height; } } catch (Exception ex) { Log(ex.ToString(), "Exception", spriteMode); sourceFile.VideoDuration = -1; //pour ne pas essayer de le recalculer sur une demande de video à encoder } TempFileManager.SafeDeleteTempFile(imageOutputPath); } } } // Si durée totale de vidéo, largeur hauteur non récupéré, on ne peut pas continuer if ((sourceFile.VideoDuration ?? 0) <= 0 || (sourceFile.VideoWidth ?? 0) <= 0 || (sourceFile.VideoHeight ?? 0) <= 0) { Log("Error while getting duration, height or width. FileName : " + Path.GetFileName(sourceFile.FilePath), "Error", spriteMode); fileItem.EncodeErrorMessage = "Error while getting duration, height or width."; fileItem.CleanFiles(); return(false); } int duration = sourceFile.VideoDuration.Value; Log("SourceVideoDuration " + duration + " / SourceVideoFileSize " + fileItem.FileContainer.SourceFileItem.FileSize, "Info source", spriteMode); // Désactivation encoding et sprite si dépassement de la durée maximale if (duration > VideoSettings.MaxVideoDurationForEncoding) { fileItem.EncodeErrorMessage = "Disable because duration reach the max limit."; if (spriteMode) { fileItem.FileContainer.DeleteSpriteVideo(); } else { fileItem.FileContainer.EncodedFileItems.Clear(); } fileItem.CleanFiles(); return(false); } return(true); }
public static void Add(FileItem fileItem) { try { currentFileItem = fileItem; LogManager.AddIpfsMessage("FileName " + Path.GetFileName(currentFileItem.FilePath), "Start"); currentFileItem.IpfsHash = null; currentFileItem.IpfsProgress = "0.00%"; // Send to ipfs and return hash from ipfs var processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = "ipfs"; processStartInfo.Arguments = $"add {Path.GetFileName(currentFileItem.FilePath)}"; if (IpfsSettings.VideoAndSpriteTrickleDag) { if (currentFileItem.TypeFile == TypeFile.SourceVideo || currentFileItem.TypeFile == TypeFile.EncodedVideo || currentFileItem.TypeFile == TypeFile.SpriteVideo) { processStartInfo.Arguments = $"add -t {Path.GetFileName(currentFileItem.FilePath)}"; } } 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(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.IpfsTimeout); 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.IpfsProgress = "100.00%"; LogManager.AddIpfsMessage("Hash " + currentFileItem.IpfsHash + " / FileSize " + currentFileItem.FileSize, "End"); } catch (Exception ex) { LogManager.AddIpfsMessage("FileSize " + currentFileItem.FileSize + " / Progress " + currentFileItem.IpfsProgress + " / Exception " + ex, "Exception"); currentFileItem.IpfsErrorMessage = "Exception"; currentFileItem.CleanFiles(); } }
public static bool Encode(FileItem fileItem) { string newEncodedFilePath = null; try { fileItem.EncodeProgress = "0.00%"; FileItem sourceFile = fileItem.FileContainer.SourceFileItem; string sourceFilePath = sourceFile.FilePath; VideoSize videoSize = fileItem.VideoSize; LogManager.AddEncodingMessage("SourceFilePath " + Path.GetFileName(sourceFilePath) + " -> " + videoSize, "Start"); // Récupérer la durée totale de la vidéo et sa résolution, autorisation encoding if (!VideoSourceManager.CheckAndAnalyseSource(fileItem, false)) { return(false); } string size; string maxRate = string.Empty; switch (videoSize) { case VideoSize.F360p: { maxRate = "200k"; Tuple <int, int> finalSize = SizeHelper.GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 640, 360); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } case VideoSize.F480p: { maxRate = "500k"; Tuple <int, int> finalSize = SizeHelper.GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 854, 480); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } case VideoSize.F720p: { maxRate = "1000k"; Tuple <int, int> finalSize = SizeHelper.GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 1280, 720); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } case VideoSize.F1080p: { maxRate = "1600k"; Tuple <int, int> finalSize = SizeHelper.GetSize(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, 1920, 1080); size = $"{finalSize.Item1}:{finalSize.Item2}"; break; } default: throw new InvalidOperationException("Format non reconnu."); } newEncodedFilePath = Path.ChangeExtension(TempFileManager.GetNewTempFilePath(), ".mp4"); string arguments; if (VideoSettings.GpuEncodeMode) { arguments = $"-y -hwaccel cuvid -vcodec h264_cuvid -vsync 0 -i {Path.GetFileName(sourceFilePath)} -vf \"scale_npp={size},format=yuv420p\" -b:v {maxRate} -maxrate {maxRate} -bufsize {maxRate} -vcodec h264_nvenc -acodec copy {Path.GetFileName(newEncodedFilePath)}"; } else { arguments = $"-y -i {Path.GetFileName(sourceFilePath)} -vf \"scale={size},format=yuv420p\" -vcodec libx264 -acodec aac {Path.GetFileName(newEncodedFilePath)}"; } var ffmpegProcessManager = new FfmpegProcessManager(fileItem); ffmpegProcessManager.StartProcess(arguments, VideoSettings.EncodeTimeout); fileItem.FilePath = newEncodedFilePath; LogManager.AddEncodingMessage("OutputFileName " + Path.GetFileName(newEncodedFilePath) + " / FileSize " + fileItem.FileSize + " / Format " + videoSize, "End Encoding"); fileItem.EncodeProgress = "100.00%"; return(true); } catch (Exception ex) { LogManager.AddEncodingMessage("Video Duration " + fileItem.VideoDuration + " / FileSize " + fileItem.FileSize + " / Progress " + fileItem.EncodeProgress + " / Exception : " + ex, "Exception"); fileItem.EncodeErrorMessage = "Exception"; TempFileManager.SafeDeleteTempFile(newEncodedFilePath); fileItem.CleanFiles(); return(false); } }
public static bool Encode(FileItem fileItem) { string newEncodedFilePath = null; try { fileItem.EncodeProgress = "0.00%"; FileItem sourceFile = fileItem.FileContainer.SourceFileItem; string sourceFilePath = sourceFile.FilePath; LogManager.AddSpriteMessage("SourceFilePath " + Path.GetFileName(sourceFilePath), "Start Sprite"); // Récupérer la durée totale de la vidéo et sa résolution, autorisation sprite creation if (!VideoSourceManager.CheckAndAnalyseSource(fileItem, false)) { return(false); } 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"; int duration = sourceFile.VideoDuration.Value; if (duration > nbImages) { frameRate = $"{nbImages}/{duration}"; //frameRate = inverse de image/s } int spriteWidth = SizeHelper.GetWidth(sourceFile.VideoWidth.Value, sourceFile.VideoHeight.Value, heightSprite); string sizeImageMax = $"scale={spriteWidth}:{heightSprite}"; newEncodedFilePath = Path.ChangeExtension(TempFileManager.GetNewTempFilePath(), ".sprite"); // Extract frameRate image/s de la video string pattern = GetPattern(newEncodedFilePath); string arguments = $"-y -i {Path.GetFileName(sourceFilePath)} -r {frameRate} -vf \"{sizeImageMax}\" -f image2 {pattern}"; var ffmpegProcessManager = new FfmpegProcessManager(fileItem); ffmpegProcessManager.StartProcess(arguments, VideoSettings.EncodeGetImagesTimeout); string[] files = GetListImageFrom(newEncodedFilePath); // récupération des images LogManager.AddSpriteMessage((files.Length - 1) + " images", "Start Combine images"); string outputFilePath = Path.ChangeExtension(TempFileManager.GetNewTempFilePath(), ".jpeg"); // nom du fichier sprite bool successSprite = CombineBitmap(files.Skip(files.Length - VideoSettings.NbSpriteImages).ToArray(), outputFilePath); // création du sprite TempFileManager.SafeDeleteTempFiles(files); // suppression des images if (successSprite) { newEncodedFilePath = outputFilePath; fileItem.FilePath = newEncodedFilePath; LogManager.AddSpriteMessage("OutputFileName " + Path.GetFileName(outputFilePath) + " / FileSize " + fileItem.FileSize, "End Sprite"); } else { LogManager.AddSpriteMessage("Error while combine images", "Error"); fileItem.EncodeErrorMessage = "Error creation sprite while combine images"; fileItem.CleanFiles(); return(false); } fileItem.EncodeProgress = "100.00%"; return(true); } catch (Exception ex) { LogManager.AddSpriteMessage("Video Duration " + fileItem.VideoDuration + " / FileSize " + fileItem.FileSize + " / Progress " + fileItem.EncodeProgress + " / Exception : " + ex, "Exception"); fileItem.EncodeErrorMessage = "Exception"; string[] files = GetListImageFrom(newEncodedFilePath); // récupération des images TempFileManager.SafeDeleteTempFiles(files); // suppression des images fileItem.CleanFiles(); return(false); } }