From c80c8c1cfd594f2597e46b09d44360ade9f4fec2 Mon Sep 17 00:00:00 2001 From: LukePulverenti Luke Pulverenti luke pulverenti Date: Thu, 23 Aug 2012 01:45:26 -0400 Subject: Switched all i/o to win32 methods and added protobuf serialization for ffprobe caching --- MediaBrowser.Controller/FFMpeg/FFProbe.cs | 40 ++++++++++------- MediaBrowser.Controller/FFMpeg/FFProbeResult.cs | 59 ++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 19 deletions(-) (limited to 'MediaBrowser.Controller/FFMpeg') diff --git a/MediaBrowser.Controller/FFMpeg/FFProbe.cs b/MediaBrowser.Controller/FFMpeg/FFProbe.cs index eb0d77a998..83f70af3ad 100644 --- a/MediaBrowser.Controller/FFMpeg/FFProbe.cs +++ b/MediaBrowser.Controller/FFMpeg/FFProbe.cs @@ -23,6 +23,10 @@ namespace MediaBrowser.Controller.FFMpeg catch (FileNotFoundException) { } + catch (Exception ex) + { + Logger.LogException(ex); + } FFProbeResult result = Run(item.Path); @@ -34,15 +38,22 @@ namespace MediaBrowser.Controller.FFMpeg private static FFProbeResult GetCachedResult(string path) { - return JsvSerializer.DeserializeFromFile(path); + return ProtobufSerializer.DeserializeFromFile(path); } - private static void CacheResult(FFProbeResult result, string outputCachePath) + private static async void CacheResult(FFProbeResult result, string outputCachePath) { - Task.Run(() => + await Task.Run(() => { - JsvSerializer.SerializeToFile(result, outputCachePath); - }); + try + { + ProtobufSerializer.SerializeToFile(result, outputCachePath); + } + catch (Exception ex) + { + Logger.LogException(ex); + } + }).ConfigureAwait(false); } public static FFProbeResult Run(Video item) @@ -55,6 +66,10 @@ namespace MediaBrowser.Controller.FFMpeg catch (FileNotFoundException) { } + catch (Exception ex) + { + Logger.LogException(ex); + } FFProbeResult result = Run(item.Path); @@ -93,16 +108,7 @@ namespace MediaBrowser.Controller.FFMpeg // If we ever decide to disable the ffmpeg log then you must uncomment the below line. process.BeginErrorReadLine(); - FFProbeResult result = JsonSerializer.DeserializeFromStream(process.StandardOutput.BaseStream); - - process.WaitForExit(); - - if (process.ExitCode != 0) - { - Logger.LogInfo("FFProbe exited with code {0} for {1}", process.ExitCode, input); - } - - return result; + return JsonSerializer.DeserializeFromStream(process.StandardOutput.BaseStream); } catch (Exception ex) { @@ -129,14 +135,14 @@ namespace MediaBrowser.Controller.FFMpeg { string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1)); - return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".jsv"); + return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".pb"); } private static string GetFFProbeVideoCachePath(BaseEntity item) { string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1)); - return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".jsv"); + return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".pb"); } } } diff --git a/MediaBrowser.Controller/FFMpeg/FFProbeResult.cs b/MediaBrowser.Controller/FFMpeg/FFProbeResult.cs index 8b2a8687e9..db7c9dd3c5 100644 --- a/MediaBrowser.Controller/FFMpeg/FFProbeResult.cs +++ b/MediaBrowser.Controller/FFMpeg/FFProbeResult.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using ProtoBuf; namespace MediaBrowser.Controller.FFMpeg { @@ -7,9 +8,13 @@ namespace MediaBrowser.Controller.FFMpeg /// Sample output: /// http://stackoverflow.com/questions/7708373/get-ffmpeg-information-in-friendly-way /// + [ProtoContract] public class FFProbeResult { - public IEnumerable streams { get; set; } + [ProtoMember(1)] + public MediaStream[] streams { get; set; } + + [ProtoMember(2)] public MediaFormat format { get; set; } } @@ -18,47 +23,97 @@ namespace MediaBrowser.Controller.FFMpeg /// A number of properties are commented out to improve deserialization performance /// Enable them as needed. /// + [ProtoContract] public class MediaStream { + [ProtoMember(1)] public int index { get; set; } + + [ProtoMember(2)] public string profile { get; set; } + + [ProtoMember(3)] public string codec_name { get; set; } + + [ProtoMember(4)] public string codec_long_name { get; set; } + + [ProtoMember(5)] 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; } + + [ProtoMember(6)] public string sample_rate { get; set; } + + [ProtoMember(7)] public int channels { get; set; } + //public int bits_per_sample { get; set; } //public string r_frame_rate { get; set; } + + [ProtoMember(8)] public string avg_frame_rate { get; set; } + //public string time_base { get; set; } //public string start_time { get; set; } + + [ProtoMember(9)] public string duration { get; set; } + + [ProtoMember(10)] public string bit_rate { get; set; } + [ProtoMember(11)] public int width { get; set; } + + [ProtoMember(12)] public int height { get; set; } + //public int has_b_frames { get; set; } //public string sample_aspect_ratio { get; set; } + + [ProtoMember(13)] public string display_aspect_ratio { get; set; } + //public string pix_fmt { get; set; } //public int level { get; set; } - public Dictionary tags { get; set; } + + [ProtoMember(14)] + public Dictionary tags { get; set; } } + [ProtoContract] public class MediaFormat { + [ProtoMember(1)] public string filename { get; set; } + + [ProtoMember(2)] public int nb_streams { get; set; } + + [ProtoMember(3)] public string format_name { get; set; } + + [ProtoMember(4)] public string format_long_name { get; set; } + + [ProtoMember(5)] public string start_time { get; set; } + + [ProtoMember(6)] public string duration { get; set; } + + [ProtoMember(7)] public string size { get; set; } + + [ProtoMember(8)] public string bit_rate { get; set; } + + [ProtoMember(9)] public Dictionary tags { get; set; } } } -- cgit v1.2.3