SharpFF.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using log4net;
  9. namespace MovieBarcodeGenerator {
  10. public class SharpFF {
  11. public static string ffmpegPath { get; set; }
  12. private static log4net.ILog log = log4net.LogManager.GetLogger("SharpFF");
  13. public static void ExecuteCommand(string parameters) {
  14. if (String.IsNullOrEmpty(ffmpegPath) || !File.Exists(Path.Combine(ffmpegPath, "ffmpeg.exe"))) {
  15. log.FatalFormat("FFmpeg was not found at '{0}'.", ffmpegPath);
  16. throw new Exception("Path to ffmpeg not specified. Set ffmpeg path (excluding exe) before attempting to use SharpFF.");
  17. }
  18. log.DebugFormat("Calling ffmpeg at {0} with parameters {1}", ffmpegPath, parameters);
  19. Process p = new Process();
  20. p.StartInfo.FileName = Path.Combine(ffmpegPath, "ffmpeg");
  21. p.StartInfo.Arguments = parameters;
  22. p.StartInfo.UseShellExecute = false;
  23. p.Start();
  24. // this could potentially be speeded up by not waiting, but then we end up trying to delete files before ffmpeg
  25. // is actually finished
  26. p.WaitForExit();
  27. }
  28. public static decimal GetDuration(string videoPath) {
  29. string parameters = String.Format("-hide_banner -i \"{0}\"", videoPath);
  30. if (String.IsNullOrEmpty(ffmpegPath) || !File.Exists(Path.Combine(ffmpegPath, "ffmpeg.exe"))) {
  31. log.FatalFormat("FFmpeg was not found at '{0}'.", ffmpegPath);
  32. throw new Exception("Path to ffmpeg not specified. Set ffmpeg path (excluding exe) before attempting to use SharpFF.");
  33. }
  34. log.DebugFormat("Calling ffmpeg at {0} with parameters {1}", ffmpegPath, parameters);
  35. Process p = new Process();
  36. p.StartInfo.FileName = Path.Combine(ffmpegPath, "ffmpeg");
  37. p.StartInfo.Arguments = parameters;
  38. p.StartInfo.RedirectStandardError = true;
  39. p.StartInfo.UseShellExecute = false;
  40. p.Start();
  41. string stderr = p.StandardError.ReadToEnd();
  42. List<string> outLines = stderr.Split(System.Environment.NewLine[0])
  43. .Where(line => string.IsNullOrWhiteSpace(line) == false && string.IsNullOrEmpty(line.Trim()) == false)
  44. .Select(s => s.Trim()).ToList();
  45. foreach (var line in outLines) {
  46. if (line.StartsWith("Duration")) {
  47. string timecode = line.Split(' ')[1].Trim();
  48. return TimecodeToSeconds(timecode);
  49. }
  50. }
  51. p.WaitForExit();
  52. return 0.0M;
  53. }
  54. public static decimal TimecodeToSeconds(string timecode) {
  55. timecode = timecode.Replace(",", String.Empty);
  56. decimal totalSeconds = 0;
  57. string[] timeElements = timecode.Split(':');
  58. totalSeconds += Int32.Parse(timeElements[0]) * 3600;
  59. totalSeconds += Int32.Parse(timeElements[1]) * 60;
  60. totalSeconds += Math.Floor(decimal.Parse(timeElements[2]) * 100) / 100;
  61. return totalSeconds;
  62. }
  63. public static string SecondsToTimecode(object seconds) {
  64. decimal betterSeconds = System.Convert.ToDecimal(seconds);
  65. decimal hours = Math.Floor(betterSeconds / 3600);
  66. if (hours >= 1) {
  67. betterSeconds -= hours * 3600;
  68. }
  69. decimal minutes = Math.Floor(betterSeconds / 60);
  70. if (minutes >= 1) {
  71. betterSeconds -= minutes * 60;
  72. }
  73. return String.Format("{0:00}:{1:00}:{2:00.00}", hours, minutes, Math.Floor(betterSeconds * 100) / 100);
  74. }
  75. }
  76. }