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: [PATCH] Switched all i/o to win32 methods and added protobuf serialization for ffprobe caching --- .../MediaBrowser.Common.csproj | 4 + .../Serialization/ProtobufSerializer.cs | 38 ++++++++ MediaBrowser.Common/UI/BaseApplication.cs | 5 ++ MediaBrowser.Common/packages.config | 1 + .../Events/ItemResolveEventArgs.cs | 86 ++++++++----------- MediaBrowser.Controller/FFMpeg/FFProbe.cs | 40 +++++---- .../FFMpeg/FFProbeResult.cs | 59 ++++++++++++- MediaBrowser.Controller/IO/FileData.cs | 84 ++++++++++++------ MediaBrowser.Controller/Kernel.cs | 6 +- .../Library/ItemController.cs | 71 ++++++--------- .../MediaBrowser.Controller.csproj | 4 + .../Providers/FolderProviderFromXml.cs | 7 +- .../Providers/LocalTrailerProvider.cs | 19 ++-- .../Providers/VideoInfoProvider.cs | 4 + .../Resolvers/BaseItemResolver.cs | 18 ++-- .../Resolvers/VideoResolver.cs | 2 +- MediaBrowser.Controller/packages.config | 1 + .../Providers/MovieProviderFromXml.cs | 7 +- .../Resolvers/MovieResolver.cs | 38 ++++---- .../Providers/SeriesProviderFromXml.cs | 7 +- MediaBrowser.TV/Resolvers/SeriesResolver.cs | 4 +- MediaBrowser.TV/TVUtils.cs | 4 +- 22 files changed, 309 insertions(+), 200 deletions(-) create mode 100644 MediaBrowser.Common/Serialization/ProtobufSerializer.cs diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 7c736affb4..c38847b5c1 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -33,6 +33,9 @@ + + ..\packages\protobuf-net.2.0.0.480\lib\net40\protobuf-net.dll + False ..\packages\ServiceStack.Text.3.9.5\lib\net35\ServiceStack.Text.dll @@ -89,6 +92,7 @@ + diff --git a/MediaBrowser.Common/Serialization/ProtobufSerializer.cs b/MediaBrowser.Common/Serialization/ProtobufSerializer.cs new file mode 100644 index 0000000000..9737c9b59d --- /dev/null +++ b/MediaBrowser.Common/Serialization/ProtobufSerializer.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; + +namespace MediaBrowser.Common.Serialization +{ + public static class ProtobufSerializer + { + public static void SerializeToStream(T obj, Stream stream) + { + ProtoBuf.Serializer.Serialize(stream, obj); + } + + public static T DeserializeFromStream(Stream stream) + { + return ProtoBuf.Serializer.Deserialize(stream); + } + + public static void SerializeToFile(T obj, string file) + { + using (Stream stream = File.Open(file, FileMode.Create)) + { + SerializeToStream(obj, stream); + } + } + + public static T DeserializeFromFile(string file) + { + using (Stream stream = File.OpenRead(file)) + { + return DeserializeFromStream(stream); + } + } + } +} diff --git a/MediaBrowser.Common/UI/BaseApplication.cs b/MediaBrowser.Common/UI/BaseApplication.cs index 27c64f4519..b526781dfe 100644 --- a/MediaBrowser.Common/UI/BaseApplication.cs +++ b/MediaBrowser.Common/UI/BaseApplication.cs @@ -48,6 +48,11 @@ namespace MediaBrowser.Common.UI } catch (Exception ex) { + if (Logger.LoggerInstance != null) + { + Logger.LogException(ex); + } + MessageBox.Show("There was an error launching Media Browser: " + ex.Message); splash.Close(); diff --git a/MediaBrowser.Common/packages.config b/MediaBrowser.Common/packages.config index 6d863a76a8..a4e0c98174 100644 --- a/MediaBrowser.Common/packages.config +++ b/MediaBrowser.Common/packages.config @@ -1,5 +1,6 @@  + diff --git a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs b/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs index 72eebc5f66..7251e3ec9e 100644 --- a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs +++ b/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs @@ -10,70 +10,47 @@ namespace MediaBrowser.Controller.Events /// public class ItemResolveEventArgs : PreBeginResolveEventArgs { - public LazyFileInfo[] FileSystemChildren { get; set; } + public WIN32_FIND_DATA[] FileSystemChildren { get; set; } - public LazyFileInfo? GetFileSystemEntry(string path, bool? isFolder = null) + public WIN32_FIND_DATA? GetFileSystemEntry(string path) { for (int i = 0; i < FileSystemChildren.Length; i++) { - LazyFileInfo entry = FileSystemChildren[i]; + WIN32_FIND_DATA entry = FileSystemChildren[i]; if (entry.Path.Equals(path, StringComparison.OrdinalIgnoreCase)) { - if (isFolder.HasValue) - { - if (isFolder.Value && !entry.FileInfo.IsDirectory) - { - continue; - } - else if (!isFolder.Value && entry.FileInfo.IsDirectory) - { - continue; - } - } - return entry; } } - + return null; } - public LazyFileInfo? GetFileSystemEntryByName(string name, bool? isFolder = null) + public bool ContainsFile(string name) { for (int i = 0; i < FileSystemChildren.Length; i++) { - LazyFileInfo entry = FileSystemChildren[i]; - - if (System.IO.Path.GetFileName(entry.Path).Equals(name, StringComparison.OrdinalIgnoreCase)) + if (System.IO.Path.GetFileName(FileSystemChildren[i].Path).Equals(name, StringComparison.OrdinalIgnoreCase)) { - if (isFolder.HasValue) - { - if (isFolder.Value && !entry.FileInfo.IsDirectory) - { - continue; - } - else if (!isFolder.Value && entry.FileInfo.IsDirectory) - { - continue; - } - } - - return entry; + return true; } } - return null; - } - - public bool ContainsFile(string name) - { - return GetFileSystemEntryByName(name, false) != null; + return false; } public bool ContainsFolder(string name) { - return GetFileSystemEntryByName(name, true) != null; + for (int i = 0; i < FileSystemChildren.Length; i++) + { + if (System.IO.Path.GetFileName(FileSystemChildren[i].Path).Equals(name, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; } } @@ -88,21 +65,15 @@ namespace MediaBrowser.Controller.Events public bool Cancel { get; set; } - public LazyFileInfo File { get; set; } + public WIN32_FIND_DATA FileInfo { get; set; } - public string Path - { - get - { - return File.Path; - } - } + public string Path { get; set; } public bool IsDirectory { get { - return File.FileInfo.dwFileAttributes.HasFlag(FileAttributes.Directory); + return FileInfo.dwFileAttributes.HasFlag(FileAttributes.Directory); } } @@ -133,5 +104,22 @@ namespace MediaBrowser.Controller.Events return vf.CollectionType; } } + + public bool IsHidden + { + get + { + return FileInfo.IsHidden; + } + } + + public bool IsSystemFile + { + get + { + return FileInfo.IsSystemFile; + } + } + } } 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; } } } diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs index 98332c7949..eca166ead4 100644 --- a/MediaBrowser.Controller/IO/FileData.cs +++ b/MediaBrowser.Controller/IO/FileData.cs @@ -2,6 +2,11 @@ using System.IO; using System.Runtime.InteropServices; +using System.Runtime.ConstrainedExecution; +using Microsoft.Win32.SafeHandles; +using System.Collections.Generic; +using System.Linq; + namespace MediaBrowser.Controller.IO { public static class FileData @@ -16,16 +21,67 @@ namespace MediaBrowser.Controller.IO if (handle == IntPtr.Zero) throw new IOException("FindFirstFile failed"); FindClose(handle); + + data.Path = fileName; return data; } - [DllImport("kernel32")] + public static IEnumerable GetFileSystemEntries(string path, string searchPattern) + { + string lpFileName = Path.Combine(path, searchPattern); + + WIN32_FIND_DATA lpFindFileData; + var handle = FindFirstFile(lpFileName, out lpFindFileData); + + if (handle == IntPtr.Zero) + { + int hr = Marshal.GetLastWin32Error(); + if (hr != 2 && hr != 0x12) + { + throw new IOException("GetFileSystemEntries failed"); + } + yield break; + } + + if (IsValid(lpFindFileData.cFileName)) + { + yield return lpFindFileData; + } + + while (FindNextFile(handle, out lpFindFileData) != IntPtr.Zero) + { + if (IsValid(lpFindFileData.cFileName)) + { + lpFindFileData.Path = Path.Combine(path, lpFindFileData.cFileName); + yield return lpFindFileData; + } + } + + FindClose(handle); + } + + private static bool IsValid(string cFileName) + { + if (cFileName.Equals(".", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + if (cFileName.Equals("..", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + return true; + } + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr FindFirstFile(string fileName, out WIN32_FIND_DATA data); + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA data); + [DllImport("kernel32")] private static extern bool FindClose(IntPtr hFindFile); - - } [StructLayout(LayoutKind.Sequential)] @@ -107,30 +163,8 @@ namespace MediaBrowser.Controller.IO highBits = highBits << 32; return DateTime.FromFileTime(highBits + (long)filetime.dwLowDateTime); } - } - public struct LazyFileInfo - { public string Path { get; set; } - - private WIN32_FIND_DATA? _FileInfo { get; set; } - - public WIN32_FIND_DATA FileInfo - { - get - { - if (_FileInfo == null) - { - _FileInfo = FileData.GetFileData(Path); - } - - return _FileInfo.Value; - } - set - { - _FileInfo = value; - } - } } } diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index fa2baafbcf..356e9e1e2f 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -69,7 +69,7 @@ namespace MediaBrowser.Controller public async override Task Init(IProgress progress) { ExtractFFMpeg(); - + await base.Init(progress).ConfigureAwait(false); progress.Report(new TaskProgress() { Description = "Loading Users", PercentComplete = 15 }); @@ -91,7 +91,7 @@ namespace MediaBrowser.Controller // Sort the providers by priority MetadataProviders = MetadataProviders.OrderBy(e => e.Priority); - + // Initialize the metadata providers Parallel.ForEach(MetadataProviders, provider => { @@ -106,7 +106,7 @@ namespace MediaBrowser.Controller /// void ItemController_PreBeginResolvePath(object sender, PreBeginResolveEventArgs e) { - if (e.File.FileInfo.IsHidden || e.File.FileInfo.IsSystemFile) + if (e.IsHidden || e.IsSystemFile) { // Ignore hidden files and folders e.Cancel = true; diff --git a/MediaBrowser.Controller/Library/ItemController.cs b/MediaBrowser.Controller/Library/ItemController.cs index f182f43f01..94fcf1f441 100644 --- a/MediaBrowser.Controller/Library/ItemController.cs +++ b/MediaBrowser.Controller/Library/ItemController.cs @@ -19,15 +19,8 @@ namespace MediaBrowser.Controller.Library /// This gives listeners a chance to cancel the operation and cause the path to be ignored. /// public event EventHandler PreBeginResolvePath; - private bool OnPreBeginResolvePath(Folder parent, string path, WIN32_FIND_DATA fileData) + private bool OnPreBeginResolvePath(PreBeginResolveEventArgs args) { - PreBeginResolveEventArgs args = new PreBeginResolveEventArgs() - { - Parent = parent, - File = new LazyFileInfo() { Path = path, FileInfo = fileData }, - Cancel = false - }; - if (PreBeginResolvePath != null) { PreBeginResolvePath(this, args); @@ -76,35 +69,35 @@ namespace MediaBrowser.Controller.Library /// public async Task GetItem(string path, Folder parent = null, WIN32_FIND_DATA? fileInfo = null) { - WIN32_FIND_DATA fileData = fileInfo ?? FileData.GetFileData(path); + ItemResolveEventArgs args = new ItemResolveEventArgs() + { + FileInfo = fileInfo ?? FileData.GetFileData(path), + Parent = parent, + Cancel = false, + Path = path + }; - if (!OnPreBeginResolvePath(parent, path, fileData)) + if (!OnPreBeginResolvePath(args)) { return null; } - LazyFileInfo[] fileSystemChildren; + WIN32_FIND_DATA[] fileSystemChildren; // Gather child folder and files - if (fileData.IsDirectory) + if (args.IsDirectory) { - fileSystemChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly)); + fileSystemChildren = FileData.GetFileSystemEntries(path, "*").ToArray(); bool isVirtualFolder = parent != null && parent.IsRoot; fileSystemChildren = FilterChildFileSystemEntries(fileSystemChildren, isVirtualFolder); } else { - fileSystemChildren = new LazyFileInfo[] { }; + fileSystemChildren = new WIN32_FIND_DATA[] { }; } - ItemResolveEventArgs args = new ItemResolveEventArgs() - { - File = new LazyFileInfo() { Path = path, FileInfo = fileData }, - FileSystemChildren = fileSystemChildren, - Parent = parent, - Cancel = false - }; + args.FileSystemChildren = fileSystemChildren; // Fire BeginResolvePath to see if anyone wants to cancel this operation if (!OnBeginResolvePath(args)) @@ -136,7 +129,7 @@ namespace MediaBrowser.Controller.Library /// /// Finds child BaseItems for a given Folder /// - private Task[] GetChildren(Folder folder, LazyFileInfo[] fileSystemChildren) + private Task[] GetChildren(Folder folder, WIN32_FIND_DATA[] fileSystemChildren) { Task[] tasks = new Task[fileSystemChildren.Length]; @@ -144,7 +137,7 @@ namespace MediaBrowser.Controller.Library { var child = fileSystemChildren[i]; - tasks[i] = GetItem(child.Path, folder, child.FileInfo); + tasks[i] = GetItem(child.Path, folder, child); } return tasks; @@ -153,14 +146,14 @@ namespace MediaBrowser.Controller.Library /// /// Transforms shortcuts into their actual paths /// - private LazyFileInfo[] FilterChildFileSystemEntries(LazyFileInfo[] fileSystemChildren, bool flattenShortcuts) + private WIN32_FIND_DATA[] FilterChildFileSystemEntries(WIN32_FIND_DATA[] fileSystemChildren, bool flattenShortcuts) { - LazyFileInfo[] returnArray = new LazyFileInfo[fileSystemChildren.Length]; - List resolvedShortcuts = new List(); + WIN32_FIND_DATA[] returnArray = new WIN32_FIND_DATA[fileSystemChildren.Length]; + List resolvedShortcuts = new List(); for (int i = 0; i < fileSystemChildren.Length; i++) { - LazyFileInfo file = fileSystemChildren[i]; + WIN32_FIND_DATA file = fileSystemChildren[i]; // If it's a shortcut, resolve it if (Shortcut.IsShortcut(file.Path)) @@ -176,18 +169,18 @@ namespace MediaBrowser.Controller.Library if (flattenShortcuts) { returnArray[i] = file; - LazyFileInfo[] newChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(newPath, "*", SearchOption.TopDirectoryOnly)); + WIN32_FIND_DATA[] newChildren = FileData.GetFileSystemEntries(newPath, "*").ToArray(); resolvedShortcuts.AddRange(FilterChildFileSystemEntries(newChildren, false)); } else { - returnArray[i] = new LazyFileInfo() { Path = newPath, FileInfo = newPathData }; + returnArray[i] = newPathData; } } else { - returnArray[i] = new LazyFileInfo() { Path = newPath, FileInfo = newPathData }; + returnArray[i] = newPathData; } } else @@ -286,26 +279,12 @@ namespace MediaBrowser.Controller.Library item.DateModified = Directory.GetLastAccessTime(path); ItemResolveEventArgs args = new ItemResolveEventArgs(); - args.File = new LazyFileInfo() { Path = path }; - args.FileSystemChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly)); + args.FileInfo = FileData.GetFileData(path); + args.FileSystemChildren = FileData.GetFileSystemEntries(path, "*").ToArray(); await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false); return item; } - - private LazyFileInfo[] ConvertFileSystemEntries(string[] files) - { - LazyFileInfo[] items = new LazyFileInfo[files.Length]; - - for (int i = 0; i < files.Length; i++) - { - string file = files[i]; - - items[i] = new LazyFileInfo() { Path = file }; - } - - return items; - } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index a4b7dbc765..41bd42040e 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -30,6 +30,10 @@ 4 + + False + ..\packages\protobuf-net.2.0.0.480\lib\net40\protobuf-net.dll + diff --git a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs index 2249fb6a50..f0c95e4f78 100644 --- a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs +++ b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs @@ -1,4 +1,5 @@ using System.ComponentModel.Composition; +using System.IO; using System.Threading.Tasks; using MediaBrowser.Controller.Events; using MediaBrowser.Controller.Xml; @@ -21,11 +22,9 @@ namespace MediaBrowser.Controller.Providers public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) { - var metadataFile = args.GetFileSystemEntryByName("folder.xml"); - - if (metadataFile.HasValue) + if (args.ContainsFile("folder.xml")) { - return Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Path); }); + return Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, Path.Combine(args.Path, "folder.xml")); }); } return Task.FromResult(null); diff --git a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs index 18ca261dca..536294c7b2 100644 --- a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs +++ b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs @@ -3,6 +3,7 @@ using System.ComponentModel.Composition; using System.IO; using System.Threading.Tasks; using MediaBrowser.Controller.Events; +using MediaBrowser.Controller.IO; using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Providers @@ -22,27 +23,21 @@ namespace MediaBrowser.Controller.Providers public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) { - var trailerPath = args.GetFileSystemEntryByName("trailers", true); - - if (trailerPath.HasValue) + if (args.ContainsFolder("trailers")) { - string[] allFiles = Directory.GetFileSystemEntries(trailerPath.Value.Path, "*", SearchOption.TopDirectoryOnly); - - List