SharpFF.cs 3.5 KB

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