Browse Source

Added an ffprobe helper class

LukePulverenti Luke Pulverenti luke pulverenti 13 years ago
parent
commit
803ce0968e

+ 68 - 0
MediaBrowser.Controller/FFMpeg/FFProbe.cs

@@ -0,0 +1,68 @@
+using System;
+using System.Diagnostics;
+using MediaBrowser.Common.Logging;
+using MediaBrowser.Common.Serialization;
+
+namespace MediaBrowser.Controller.FFMpeg
+{
+    public static class FFProbe
+    {
+        public static FFProbeResult Run(string path)
+        {
+            ProcessStartInfo startInfo = new ProcessStartInfo();
+
+            startInfo.CreateNoWindow = true;
+
+            startInfo.UseShellExecute = false;
+
+            // Must consume both or ffmpeg may hang due to deadlocks. See comments below.
+            startInfo.RedirectStandardOutput = true;
+            startInfo.RedirectStandardError = true;
+
+            startInfo.FileName = Kernel.Instance.ApplicationPaths.FFProbePath;
+            startInfo.WorkingDirectory = Kernel.Instance.ApplicationPaths.FFMpegDirectory;
+            startInfo.Arguments = string.Format("\"{0}\" -v quiet -print_format json -show_streams -show_format", path);
+
+            Logger.LogInfo(startInfo.FileName + " " + startInfo.Arguments);
+
+            Process process = new Process();
+            process.StartInfo = startInfo;
+
+            try
+            {
+                process.Start();
+
+                // MUST read both stdout and stderr asynchronously or a deadlock may occurr
+                // If we ever decide to disable the ffmpeg log then you must uncomment the below line.
+                process.BeginErrorReadLine();
+
+                FFProbeResult result = JsonSerializer.DeserializeFromStream<FFProbeResult>(process.StandardOutput.BaseStream);
+
+                process.WaitForExit();
+
+                Logger.LogInfo("FFMpeg exited with code " + process.ExitCode);
+
+                return result;
+            }
+            catch (Exception ex)
+            {
+                Logger.LogException(ex);
+
+                // Hate having to do this
+                try
+                {
+                    process.Kill();
+                }
+                catch
+                {
+                }
+
+                return null;
+            }
+            finally
+            {
+                process.Dispose();
+            }
+        }
+    }
+}

+ 76 - 0
MediaBrowser.Controller/FFMpeg/FFProbeResult.cs

@@ -0,0 +1,76 @@
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.FFMpeg
+{
+    /// <summary>
+    /// Provides a class that we can use to deserialize the ffprobe json output
+    /// Sample output:
+    /// http://stackoverflow.com/questions/7708373/get-ffmpeg-information-in-friendly-way
+    /// </summary>
+    public class FFProbeResult
+    {
+        public IEnumerable<MediaStream> streams { get; set; }
+        public MediaFormat format { get; set; }
+    }
+
+    public class MediaStream
+    {
+        public int index { get; set; }
+        public string profile { get; set; }
+        public string codec_name { get; set; }
+        public string codec_long_name { get; set; }
+        public string codec_type { get; set; }
+        public string codec_time_base { get; set; }
+        public string codec_tag { get; set; }
+        public string codec_tag_string { get; set; }
+        public string sample_fmt { get; set; }
+        public string sample_rate { get; set; }
+        public int channels { get; set; }
+        public int bits_per_sample { get; set; }
+        public string r_frame_rate { get; set; }
+        public string avg_frame_rate { get; set; }
+        public string time_base { get; set; }
+        public string start_time { get; set; }
+        public string duration { get; set; }
+        public string bit_rate { get; set; }
+
+        public int width { get; set; }
+        public int height { get; set; }
+        public int has_b_frames { get; set; }
+        public string sample_aspect_ratio { get; set; }
+        public string display_aspect_ratio { get; set; }
+        public string pix_fmt { get; set; }
+        public int level { get; set; }
+        public MediaTags tags { get; set; }
+    }
+
+    public class MediaFormat
+    {
+        public string filename { get; set; }
+        public int nb_streams { get; set; }
+        public string format_name { get; set; }
+        public string format_long_name { get; set; }
+        public string start_time { get; set; }
+        public string duration { get; set; }
+        public string size { get; set; }
+        public string bit_rate { get; set; }
+        public MediaTags tags { get; set; }
+    }
+
+    public class MediaTags
+    {
+        public string title { get; set; }
+        public string comment { get; set; }
+        public string artist { get; set; }
+        public string album { get; set; }
+        public string album_artist { get; set; }
+        public string composer { get; set; }
+        public string copyright { get; set; }
+        public string publisher { get; set; }
+        public string track { get; set; }
+        public string disc { get; set; }
+        public string genre { get; set; }
+        public string date { get; set; }
+        public string language { get; set; }
+    }
+}

+ 0 - 1
MediaBrowser.Controller/Kernel.cs

@@ -5,7 +5,6 @@ using System.IO;
 using System.Linq;
 using System.Security.Cryptography;
 using System.Text;
-using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Kernel;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Events;

+ 2 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -52,6 +52,8 @@
     <Compile Include="Configuration\ServerApplicationPaths.cs" />
     <Compile Include="Configuration\ServerConfiguration.cs" />
     <Compile Include="Events\ItemResolveEventArgs.cs" />
+    <Compile Include="FFMpeg\FFProbe.cs" />
+    <Compile Include="FFMpeg\FFProbeResult.cs" />
     <Compile Include="IO\DirectoryWatchers.cs" />
     <Compile Include="IO\Shortcut.cs" />
     <Compile Include="Library\ItemController.cs" />