Switched FFProbe caching to use service stack's jsv serializer

pull/702/head
LukePulverenti Luke Pulverenti luke pulverenti 12 years ago
parent a3f08b02ca
commit b15c064bba

@ -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");
}
}
}

@ -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)

@ -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)

Loading…
Cancel
Save