2
0
Эх сурвалжийг харах

Switched FFProbe caching to use service stack's jsv serializer

LukePulverenti Luke Pulverenti luke pulverenti 13 жил өмнө
parent
commit
b15c064bba

+ 45 - 21
MediaBrowser.Controller/FFMpeg/FFProbe.cs

@@ -13,48 +13,61 @@ namespace MediaBrowser.Controller.FFMpeg
     /// </summary>
     public static class FFProbe
     {
-        public async static Task<FFProbeResult> Run(Audio item, string outputCachePath)
+        public static FFProbeResult Run(Audio item)
         {
             // Use try catch to avoid having to use File.Exists
             try
             {
-                return GetCachedResult(outputCachePath);
+                return GetCachedResult(GetFFProbeAudioCachePath(item));
             }
             catch (FileNotFoundException)
             {
             }
 
-            await Run(item.Path, outputCachePath).ConfigureAwait(false);
+            FFProbeResult result = Run(item.Path);
 
-            return GetCachedResult(item.Path);
+            // Fire and forget
+            CacheResult(result, GetFFProbeAudioCachePath(item));
+
+            return result;
         }
 
-        public static FFProbeResult GetCachedResult(string path)
+        private static FFProbeResult GetCachedResult(string path)
         {
-            using (FileStream stream = File.OpenRead(path))
+            return JsvSerializer.DeserializeFromFile<FFProbeResult>(path);
+        }
+
+        private static void CacheResult(FFProbeResult result, string outputCachePath)
+        {
+            Task.Run(() =>
             {
-                return JsonSerializer.DeserializeFromStream<FFProbeResult>(stream);
-            }
+                JsvSerializer.SerializeToFile<FFProbeResult>(result, outputCachePath);
+            });
         }
 
-        public async static Task<FFProbeResult> Run(Video item, string outputCachePath)
+        public static FFProbeResult Run(Video item)
         {
             // Use try catch to avoid having to use File.Exists
             try
             {
-                return GetCachedResult(outputCachePath);
+                return GetCachedResult(GetFFProbeVideoCachePath(item));
             }
             catch (FileNotFoundException)
             {
             }
 
-            await Run(item.Path, outputCachePath).ConfigureAwait(false);
+            FFProbeResult result = Run(item.Path);
 
-            return GetCachedResult(item.Path);
+            // Fire and forget
+            CacheResult(result, GetFFProbeVideoCachePath(item));
+
+            return result;
         }
 
-        private async static Task Run(string input, string output)
+        private static FFProbeResult Run(string input)
         {
+            MediaBrowser.Common.Logging.Logger.LogInfo(input);
+
             ProcessStartInfo startInfo = new ProcessStartInfo();
 
             startInfo.CreateNoWindow = true;
@@ -74,8 +87,6 @@ namespace MediaBrowser.Controller.FFMpeg
             Process process = new Process();
             process.StartInfo = startInfo;
 
-            FileStream stream = new FileStream(output, FileMode.Create);
-
             try
             {
                 process.Start();
@@ -84,23 +95,21 @@ namespace MediaBrowser.Controller.FFMpeg
                 // If we ever decide to disable the ffmpeg log then you must uncomment the below line.
                 process.BeginErrorReadLine();
 
-                await process.StandardOutput.BaseStream.CopyToAsync(stream).ConfigureAwait(false);
+                FFProbeResult result = JsonSerializer.DeserializeFromStream<FFProbeResult>(process.StandardOutput.BaseStream);
 
                 process.WaitForExit();
 
-                stream.Dispose();
-
                 if (process.ExitCode != 0)
                 {
                     Logger.LogInfo("FFProbe exited with code {0} for {1}", process.ExitCode, input);
                 }
+
+                return result;
             }
             catch (Exception ex)
             {
                 Logger.LogException(ex);
 
-                stream.Dispose();
-
                 // Hate having to do this
                 try
                 {
@@ -109,12 +118,27 @@ namespace MediaBrowser.Controller.FFMpeg
                 catch
                 {
                 }
-                File.Delete(output);
+
+                return null;
             }
             finally
             {
                 process.Dispose();
             }
         }
+
+        private static string GetFFProbeAudioCachePath(BaseEntity item)
+        {
+            string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1));
+
+            return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".jsv");
+        }
+
+        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");
+        }
     }
 }

+ 6 - 10
MediaBrowser.Controller/Providers/AudioInfoProvider.cs

@@ -23,18 +23,14 @@ namespace MediaBrowser.Controller.Providers
             get { return MetadataProviderPriority.First; }
         }
 
-        public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
+        public override async Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
         {
-            Audio audio = item as Audio;
-
-            Fetch(audio, await FFProbe.Run(audio, GetFFProbeOutputPath(item)).ConfigureAwait(false));
-        }
-
-        private string GetFFProbeOutputPath(BaseEntity item)
-        {
-            string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1));
+            await Task.Run(() =>
+            {
+                Audio audio = item as Audio;
 
-            return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
+                Fetch(audio, FFProbe.Run(audio));
+            });
         }
 
         private void Fetch(Audio audio, FFProbeResult data)

+ 14 - 19
MediaBrowser.Controller/Providers/VideoInfoProvider.cs

@@ -1,12 +1,11 @@
 using System;
+using System.Collections.Generic;
 using System.ComponentModel.Composition;
-using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Events;
 using MediaBrowser.Controller.FFMpeg;
 using MediaBrowser.Model.Entities;
-using System.Collections.Generic;
 
 namespace MediaBrowser.Controller.Providers
 {
@@ -27,27 +26,23 @@ namespace MediaBrowser.Controller.Providers
 
         public override async Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
         {
-            Video video = item as Video;
-
-            if (video.VideoType != VideoType.VideoFile)
+            await Task.Run(() =>
             {
-                // Not supported yet
-                return;
-            }
-
-            if (CanSkip(video))
-            {
-                return;
-            }
+                Video video = item as Video;
 
-            Fetch(video, await FFProbe.Run(video, GetFFProbeOutputPath(video)).ConfigureAwait(false));
-        }
+                if (video.VideoType != VideoType.VideoFile)
+                {
+                    // Not supported yet
+                    return;
+                }
 
-        private string GetFFProbeOutputPath(Video item)
-        {
-            string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1));
+                if (CanSkip(video))
+                {
+                    return;
+                }
 
-            return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
+                Fetch(video, FFProbe.Run(video));
+            });
         }
 
         private void Fetch(Video video, FFProbeResult data)