diff --git a/MediaBrowser.Controller/FFMpeg/FFProbe.cs b/MediaBrowser.Controller/FFMpeg/FFProbe.cs index 1a0685a7a6..1a207f2211 100644 --- a/MediaBrowser.Controller/FFMpeg/FFProbe.cs +++ b/MediaBrowser.Controller/FFMpeg/FFProbe.cs @@ -13,48 +13,61 @@ namespace MediaBrowser.Controller.FFMpeg /// public static class FFProbe { - public async static Task 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 JsonSerializer.DeserializeFromStream(stream); - } + return JsvSerializer.DeserializeFromFile(path); } - public async static Task Run(Video item, string outputCachePath) + private static void CacheResult(FFProbeResult result, string outputCachePath) + { + Task.Run(() => + { + JsvSerializer.SerializeToFile(result, 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(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"); + } } } diff --git a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs b/MediaBrowser.Controller/Providers/AudioInfoProvider.cs index 72e9d1e4cd..6c0eb93a6d 100644 --- a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs +++ b/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; + await Task.Run(() => + { + 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)); - - return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); + Fetch(audio, FFProbe.Run(audio)); + }); } private void Fetch(Audio audio, FFProbeResult data) diff --git a/MediaBrowser.Controller/Providers/VideoInfoProvider.cs b/MediaBrowser.Controller/Providers/VideoInfoProvider.cs index f7a6c3b048..8145654331 100644 --- a/MediaBrowser.Controller/Providers/VideoInfoProvider.cs +++ b/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; - } + Video video = item as Video; - if (CanSkip(video)) - { - return; - } + if (video.VideoType != VideoType.VideoFile) + { + // Not supported yet + return; + } - Fetch(video, await FFProbe.Run(video, GetFFProbeOutputPath(video)).ConfigureAwait(false)); - } + if (CanSkip(video)) + { + return; + } - private string GetFFProbeOutputPath(Video item) - { - string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1)); - - return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); + Fetch(video, FFProbe.Run(video)); + }); } private void Fetch(Video video, FFProbeResult data)