Bläddra i källkod

update media source methods

Luke Pulverenti 7 år sedan
förälder
incheckning
db315c4e32
31 ändrade filer med 235 tillägg och 247 borttagningar
  1. 2 2
      Emby.Dlna/Didl/DidlBuilder.cs
  2. 1 1
      Emby.Dlna/PlayTo/PlayToController.cs
  3. 3 22
      Emby.Server.Implementations/Data/SqliteItemRepository.cs
  4. 1 1
      Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
  5. 2 2
      Emby.Server.Implementations/Dto/DtoService.cs
  6. 3 0
      Emby.Server.Implementations/Emby.Server.Implementations.csproj
  7. 7 8
      Emby.Server.Implementations/Library/MediaSourceManager.cs
  8. 2 2
      Emby.Server.Implementations/LiveTv/LiveTvManager.cs
  9. 1 2
      Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
  10. 1 0
      Emby.Server.Implementations/Localization/Ratings/es.txt
  11. 1 0
      Emby.Server.Implementations/Localization/Ratings/ro.txt
  12. 13 9
      Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
  13. 20 2
      MediaBrowser.Controller/Entities/Audio/Audio.cs
  14. 0 9
      MediaBrowser.Controller/Entities/IHasId.cs
  15. 1 1
      MediaBrowser.Controller/Entities/IHasImages.cs
  16. 3 1
      MediaBrowser.Controller/Entities/IHasMediaSources.cs
  17. 1 0
      MediaBrowser.Controller/Entities/IHasMetadata.cs
  18. 5 2
      MediaBrowser.Controller/Entities/IHasUserData.cs
  19. 46 20
      MediaBrowser.Controller/Entities/Video.cs
  20. 4 4
      MediaBrowser.Controller/Library/IMediaSourceManager.cs
  21. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
  22. 6 1
      MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
  23. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
  24. 0 1
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  25. 24 4
      MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
  26. 1 1
      MediaBrowser.Controller/Persistence/IItemRepository.cs
  27. 0 2
      MediaBrowser.Model/Dto/MediaSourceInfo.cs
  28. 1 3
      MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
  29. 29 49
      MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
  30. 48 90
      MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
  31. 5 4
      MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs

+ 2 - 2
Emby.Dlna/Didl/DidlBuilder.cs

@@ -193,7 +193,7 @@ namespace Emby.Dlna.Didl
         {
             if (streamInfo == null)
             {
-                var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user).ToList();
+                var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user);
 
                 streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions
                 {
@@ -508,7 +508,7 @@ namespace Emby.Dlna.Didl
 
             if (streamInfo == null)
             {
-                var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user).ToList();
+                var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user);
 
                 streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions
                 {

+ 1 - 1
Emby.Dlna/PlayTo/PlayToController.cs

@@ -503,7 +503,7 @@ namespace Emby.Dlna.PlayTo
 
             var hasMediaSources = item as IHasMediaSources;
             var mediaSources = hasMediaSources != null
-                ? (_mediaSourceManager.GetStaticMediaSources(hasMediaSources, true, user)).ToList()
+                ? (_mediaSourceManager.GetStaticMediaSources(hasMediaSources, true, user))
                 : new List<MediaSourceInfo>();
 
             var playlistItem = GetPlaylistItem(item, mediaSources, profile, _session.DeviceId, mediaSourceId, audioStreamIndex, subtitleStreamIndex);

+ 3 - 22
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -113,7 +113,7 @@ namespace Emby.Server.Implementations.Data
         {
             get
             {
-                return true;
+                return false;
             }
         }
 
@@ -1972,20 +1972,7 @@ namespace Emby.Server.Implementations.Data
         /// <returns>Task{IEnumerable{ItemReview}}.</returns>
         public IEnumerable<ItemReview> GetCriticReviews(Guid itemId)
         {
-            try
-            {
-                var path = Path.Combine(_criticReviewsPath, itemId + ".json");
-
-                return _jsonSerializer.DeserializeFromFile<List<ItemReview>>(path);
-            }
-            catch (FileNotFoundException)
-            {
-                return new List<ItemReview>();
-            }
-            catch (IOException)
-            {
-                return new List<ItemReview>();
-            }
+            return new List<ItemReview>();
         }
 
         private readonly Task _cachedTask = Task.FromResult(true);
@@ -1997,12 +1984,6 @@ namespace Emby.Server.Implementations.Data
         /// <returns>Task.</returns>
         public Task SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
         {
-            _fileSystem.CreateDirectory(_criticReviewsPath);
-
-            var path = Path.Combine(_criticReviewsPath, itemId + ".json");
-
-            _jsonSerializer.SerializeToFile(criticReviews.ToList(), path);
-
             return _cachedTask;
         }
 
@@ -5610,7 +5591,7 @@ namespace Emby.Server.Implementations.Data
             return item;
         }
 
-        public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
+        public List<MediaStream> GetMediaStreams(MediaStreamQuery query)
         {
             CheckDisposed();
 

+ 1 - 1
Emby.Server.Implementations/Data/SqliteUserDataRepository.cs

@@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.Data
         {
             get
             {
-                return true;
+                return false;
             }
         }
 

+ 2 - 2
Emby.Server.Implementations/Dto/DtoService.cs

@@ -359,11 +359,11 @@ namespace Emby.Server.Implementations.Dto
                 {
                     if (user == null)
                     {
-                        dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true).ToList();
+                        dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true);
                     }
                     else
                     {
-                        dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user).ToList();
+                        dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user);
                     }
                 }
             }

+ 3 - 0
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -413,6 +413,9 @@
   <ItemGroup>
     <EmbeddedResource Include="Localization\Ratings\es.txt" />
   </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Localization\Ratings\ro.txt" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 7 - 8
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -49,10 +49,9 @@ namespace Emby.Server.Implementations.Library
             _providers = providers.ToArray();
         }
 
-        public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
+        public List<MediaStream> GetMediaStreams(MediaStreamQuery query)
         {
-            var list = _itemRepo.GetMediaStreams(query)
-                .ToList();
+            var list = _itemRepo.GetMediaStreams(query);
 
             foreach (var stream in list)
             {
@@ -77,7 +76,7 @@ namespace Emby.Server.Implementations.Library
             return false;
         }
 
-        public IEnumerable<MediaStream> GetMediaStreams(string mediaSourceId)
+        public List<MediaStream> GetMediaStreams(string mediaSourceId)
         {
             var list = GetMediaStreams(new MediaStreamQuery
             {
@@ -87,7 +86,7 @@ namespace Emby.Server.Implementations.Library
             return GetMediaStreamsForItem(list);
         }
 
-        public IEnumerable<MediaStream> GetMediaStreams(Guid itemId)
+        public List<MediaStream> GetMediaStreams(Guid itemId)
         {
             var list = GetMediaStreams(new MediaStreamQuery
             {
@@ -97,7 +96,7 @@ namespace Emby.Server.Implementations.Library
             return GetMediaStreamsForItem(list);
         }
 
-        private IEnumerable<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams)
+        private List<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams)
         {
             var list = streams.ToList();
 
@@ -253,7 +252,7 @@ namespace Emby.Server.Implementations.Library
             return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));
         }
 
-        public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null)
+        public List<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null)
         {
             if (item == null)
             {
@@ -265,7 +264,7 @@ namespace Emby.Server.Implementations.Library
                 return item.GetMediaSources(enablePathSubstitution);
             }
 
-            var sources = item.GetMediaSources(enablePathSubstitution).ToList();
+            var sources = item.GetMediaSources(enablePathSubstitution);
 
             if (user != null)
             {

+ 2 - 2
Emby.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1957,7 +1957,7 @@ namespace Emby.Server.Implementations.LiveTv
 
             if (dto.MediaSources == null)
             {
-                dto.MediaSources = recording.GetMediaSources(true).ToList();
+                dto.MediaSources = recording.GetMediaSources(true);
             }
 
             if (dto.MediaStreams == null)
@@ -2365,7 +2365,7 @@ namespace Emby.Server.Implementations.LiveTv
 
                 if (addMediaSources)
                 {
-                    dto.MediaSources = channel.GetMediaSources(true).ToList();
+                    dto.MediaSources = channel.GetMediaSources(true);
                 }
 
                 if (addCurrentProgram)

+ 1 - 2
Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs

@@ -78,8 +78,7 @@ namespace Emby.Server.Implementations.LiveTv
             {
                 var hasMediaSources = (IHasMediaSources)item;
 
-                sources = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false)
-                   .ToList();
+                sources = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false);
 
                 forceRequireOpening = true;
             }

+ 1 - 0
Emby.Server.Implementations/Localization/Ratings/es.txt

@@ -1,4 +1,5 @@
 ES-A,1
+ES-APTA,1
 ES-7,3
 ES-12,6
 ES-16,8

+ 1 - 0
Emby.Server.Implementations/Localization/Ratings/ro.txt

@@ -0,0 +1 @@
+RO-AG,1

+ 13 - 9
Emby.Server.Implementations/MediaEncoder/EncodingManager.cs

@@ -29,9 +29,9 @@ namespace Emby.Server.Implementations.MediaEncoder
         private readonly IChapterManager _chapterManager;
         private readonly ILibraryManager _libraryManager;
 
-        public EncodingManager(IFileSystem fileSystem, 
-            ILogger logger, 
-            IMediaEncoder encoder, 
+        public EncodingManager(IFileSystem fileSystem,
+            ILogger logger,
+            IMediaEncoder encoder,
             IChapterManager chapterManager, ILibraryManager libraryManager)
         {
             _fileSystem = fileSystem;
@@ -121,12 +121,16 @@ namespace Emby.Server.Implementations.MediaEncoder
                         {
                             continue;
                         }
+
+                        List<string> playableStreamFileNames = null;
                         if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd)
                         {
-                            if (video.PlayableStreamFileNames.Count != 1)
-                            {
-                                continue;
-                            }
+                            continue;
+                        }
+
+                        if (playableStreamFileNames == null)
+                        {
+                            playableStreamFileNames = new List<string>();
                         }
 
                         try
@@ -136,7 +140,7 @@ namespace Emby.Server.Implementations.MediaEncoder
 
                             var protocol = MediaProtocol.File;
 
-                            var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames);
+                            var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, playableStreamFileNames);
 
                             _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
 
@@ -151,7 +155,7 @@ namespace Emby.Server.Implementations.MediaEncoder
                             }
                             catch
                             {
-                                
+
                             }
 
                             chapter.ImagePath = path;

+ 20 - 2
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -9,6 +9,7 @@ using System.Globalization;
 using System.Linq;
 using System.Threading;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Serialization;
 
 namespace MediaBrowser.Controller.Entities.Audio
@@ -193,6 +194,23 @@ namespace MediaBrowser.Controller.Entities.Audio
             return base.GetBlockUnratedType();
         }
 
+        public List<MediaStream> GetMediaStreams()
+        {
+            return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
+            {
+                ItemId = Id
+            });
+        }
+
+        public List<MediaStream> GetMediaStreams(MediaStreamType type)
+        {
+            return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
+            {
+                ItemId = Id,
+                Type = type
+            });
+        }
+
         public SongInfo GetLookupInfo()
         {
             var info = GetItemLookupInfo<SongInfo>();
@@ -204,7 +222,7 @@ namespace MediaBrowser.Controller.Entities.Audio
             return info;
         }
 
-        public virtual IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
+        public virtual List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
         {
             if (SourceType == SourceType.Channel)
             {
@@ -248,7 +266,7 @@ namespace MediaBrowser.Controller.Entities.Audio
             {
                 Id = i.Id.ToString("N"),
                 Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File,
-                MediaStreams = MediaSourceManager.GetMediaStreams(i.Id).ToList(),
+                MediaStreams = MediaSourceManager.GetMediaStreams(i.Id),
                 Name = i.Name,
                 Path = enablePathSubstituion ? GetMappedPath(i, i.Path, locationType) : i.Path,
                 RunTimeTicks = i.RunTimeTicks,

+ 0 - 9
MediaBrowser.Controller/Entities/IHasId.cs

@@ -1,9 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Entities
-{
-    public interface IHasId
-    {
-        Guid Id { get; }
-    }
-}

+ 1 - 1
MediaBrowser.Controller/Entities/IHasImages.cs

@@ -10,7 +10,7 @@ using MediaBrowser.Model.IO;
 
 namespace MediaBrowser.Controller.Entities
 {
-    public interface IHasImages : IHasProviderIds, IHasId
+    public interface IHasImages : IHasProviderIds, IHasUserData
     {
         /// <summary>
         /// Gets the name.

+ 3 - 1
MediaBrowser.Controller/Entities/IHasMediaSources.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Model.Dto;
 using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -10,6 +11,7 @@ namespace MediaBrowser.Controller.Entities
         /// </summary>
         /// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
         /// <returns>Task{IEnumerable{MediaSourceInfo}}.</returns>
-        IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
+        List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
+        List<MediaStream> GetMediaStreams();
     }
 }

+ 1 - 0
MediaBrowser.Controller/Entities/IHasMetadata.cs

@@ -65,5 +65,6 @@ namespace MediaBrowser.Controller.Entities
         int InheritedParentalRatingValue { get; set; }
         List<string> GetInheritedTags();
         List<string> InheritedTags { get; set; }
+        long? RunTimeTicks { get; set; }
     }
 }

+ 5 - 2
MediaBrowser.Controller/Entities/IHasUserData.cs

@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Threading.Tasks;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Querying;
@@ -8,7 +9,7 @@ namespace MediaBrowser.Controller.Entities
     /// <summary>
     /// Interface IHasUserData
     /// </summary>
-    public interface IHasUserData : IHasId
+    public interface IHasUserData
     {
         List<string> GetUserDataKeys();
 
@@ -20,5 +21,7 @@ namespace MediaBrowser.Controller.Entities
         bool EnableRememberingTrackSelections { get; }
 
         bool SupportsPlayedStatus { get; }
+
+        Guid Id { get; }
     }
 }

+ 46 - 20
MediaBrowser.Controller/Entities/Video.cs

@@ -148,11 +148,6 @@ namespace MediaBrowser.Controller.Entities
         /// <value>The video3 D format.</value>
         public Video3DFormat? Video3DFormat { get; set; }
 
-        /// <summary>
-        /// If the video is a folder-rip, this will hold the file list for the largest playlist
-        /// </summary>
-        public List<string> PlayableStreamFileNames { get; set; }
-
         /// <summary>
         /// Gets the playable stream files.
         /// </summary>
@@ -162,6 +157,11 @@ namespace MediaBrowser.Controller.Entities
             return GetPlayableStreamFiles(Path);
         }
 
+        public List<string> GetPlayableStreamFileNames()
+        {
+            return GetPlayableStreamFiles().Select(System.IO.Path.GetFileName).ToList(); ;
+        }
+
         /// <summary>
         /// Gets or sets the aspect ratio.
         /// </summary>
@@ -170,7 +170,6 @@ namespace MediaBrowser.Controller.Entities
 
         public Video()
         {
-            PlayableStreamFileNames = new List<string>();
             AdditionalParts = new List<string>();
             LocalAlternateVersions = new List<string>();
             SubtitleFiles = new List<string>();
@@ -395,11 +394,45 @@ namespace MediaBrowser.Controller.Entities
         {
             var allFiles = FileSystem.GetFilePaths(rootPath, true).ToList();
 
-            return PlayableStreamFileNames.Select(name => allFiles.FirstOrDefault(f => string.Equals(System.IO.Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase)))
+            var videoType = VideoType;
+
+            if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.BluRay)
+            {
+                videoType = VideoType.BluRay;
+            }
+            else if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.Dvd)
+            {
+                videoType = VideoType.Dvd;
+            }
+
+            return QueryPlayableStreamFiles(rootPath, videoType).Select(name => allFiles.FirstOrDefault(f => string.Equals(System.IO.Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase)))
                 .Where(f => !string.IsNullOrEmpty(f))
                 .ToList();
         }
 
+        public static List<string> QueryPlayableStreamFiles(string rootPath, VideoType videoType)
+        {
+            if (videoType == VideoType.Dvd)
+            {
+                return FileSystem.GetFiles(rootPath, new[] { ".vob" }, false, true)
+                    .OrderByDescending(i => i.Length)
+                    .ThenBy(i => i.FullName)
+                    .Take(1)
+                    .Select(i => i.FullName)
+                    .ToList();
+            }
+            if (videoType == VideoType.BluRay)
+            {
+                return FileSystem.GetFiles(rootPath, new[] { ".m2ts" }, false, true)
+                    .OrderByDescending(i => i.Length)
+                    .ThenBy(i => i.FullName)
+                    .Take(1)
+                    .Select(i => i.FullName)
+                    .ToList();
+            }
+            return new List<string>();
+        }
+
         /// <summary>
         /// Gets a value indicating whether [is3 D].
         /// </summary>
@@ -505,17 +538,12 @@ namespace MediaBrowser.Controller.Entities
             return base.GetDeletePaths();
         }
 
-        public IEnumerable<MediaStream> GetMediaStreams()
+        public List<MediaStream> GetMediaStreams()
         {
-            var mediaSource = GetMediaSources(false)
-                .FirstOrDefault();
-
-            if (mediaSource == null)
+            return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
             {
-                return new List<MediaStream>();
-            }
-
-            return mediaSource.MediaStreams;
+                ItemId = Id
+            });
         }
 
         public virtual MediaStream GetDefaultVideoStream()
@@ -563,7 +591,7 @@ namespace MediaBrowser.Controller.Entities
             return list;
         }
 
-        public virtual IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
+        public virtual List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
         {
             if (SourceType == SourceType.Channel)
             {
@@ -610,8 +638,7 @@ namespace MediaBrowser.Controller.Entities
                 throw new ArgumentNullException("media");
             }
 
-            var mediaStreams = MediaSourceManager.GetMediaStreams(media.Id)
-                .ToList();
+            var mediaStreams = MediaSourceManager.GetMediaStreams(media.Id);
 
             var locationType = media.LocationType;
 
@@ -630,7 +657,6 @@ namespace MediaBrowser.Controller.Entities
                 Size = media.Size,
                 Timestamp = media.Timestamp,
                 Type = type,
-                PlayableStreamFileNames = media.PlayableStreamFileNames.ToList(),
                 SupportsDirectStream = media.VideoType == VideoType.VideoFile,
                 IsRemote = media.IsShortcut
             };

+ 4 - 4
MediaBrowser.Controller/Library/IMediaSourceManager.cs

@@ -24,19 +24,19 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// <param name="itemId">The item identifier.</param>
         /// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
-        IEnumerable<MediaStream> GetMediaStreams(Guid itemId);
+        List<MediaStream> GetMediaStreams(Guid itemId);
         /// <summary>
         /// Gets the media streams.
         /// </summary>
         /// <param name="mediaSourceId">The media source identifier.</param>
         /// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
-        IEnumerable<MediaStream> GetMediaStreams(string mediaSourceId);
+        List<MediaStream> GetMediaStreams(string mediaSourceId);
         /// <summary>
         /// Gets the media streams.
         /// </summary>
         /// <param name="query">The query.</param>
         /// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
-        IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query);
+        List<MediaStream> GetMediaStreams(MediaStreamQuery query);
 
         /// <summary>
         /// Gets the playack media sources.
@@ -56,7 +56,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
         /// <param name="user">The user.</param>
         /// <returns>IEnumerable&lt;MediaSourceInfo&gt;.</returns>
-        IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null);
+        List<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null);
 
         /// <summary>
         /// Gets the static media source.

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs

@@ -151,9 +151,9 @@ namespace MediaBrowser.Controller.LiveTv
             return user.Policy.EnableLiveTvManagement;
         }
 
-        public override IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
+        public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
         {
-            var list = base.GetMediaSources(enablePathSubstitution).ToList();
+            var list = base.GetMediaSources(enablePathSubstitution);
 
             foreach (var mediaSource in list)
             {

+ 6 - 1
MediaBrowser.Controller/LiveTv/LiveTvChannel.cs

@@ -122,7 +122,7 @@ namespace MediaBrowser.Controller.LiveTv
             return new List<BaseItem>();
         }
 
-        public IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
+        public List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
         {
             var list = new List<MediaSourceInfo>();
 
@@ -144,6 +144,11 @@ namespace MediaBrowser.Controller.LiveTv
             return list;
         }
 
+        public List<MediaStream> GetMediaStreams()
+        {
+            return new List<MediaStream>();
+        }
+
         protected override string GetInternalMetadataPath(string basePath)
         {
             return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"), "metadata");

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs

@@ -150,9 +150,9 @@ namespace MediaBrowser.Controller.LiveTv
             return user.Policy.EnableLiveTvManagement;
         }
 
-        public override IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
+        public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
         {
-            var list = base.GetMediaSources(enablePathSubstitution).ToList();
+            var list = base.GetMediaSources(enablePathSubstitution);
 
             foreach (var mediaSource in list)
             {

+ 0 - 1
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -99,7 +99,6 @@
     <Compile Include="Entities\GameSystem.cs" />
     <Compile Include="Entities\IHasAspectRatio.cs" />
     <Compile Include="Entities\IHasDisplayOrder.cs" />
-    <Compile Include="Entities\IHasId.cs" />
     <Compile Include="Entities\IHasImages.cs" />
     <Compile Include="Entities\IHasMediaSources.cs" />
     <Compile Include="Entities\IHasProgramAttributes.cs" />

+ 24 - 4
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -4,6 +4,7 @@ using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Threading;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dto;
@@ -1671,14 +1672,33 @@ namespace MediaBrowser.Controller.MediaEncoding
             state.RunTimeTicks = mediaSource.RunTimeTicks;
             state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders;
 
+            state.IsoType = mediaSource.IsoType;
+
             if (mediaSource.VideoType.HasValue)
             {
                 state.VideoType = mediaSource.VideoType.Value;
-            }
-
-            state.IsoType = mediaSource.IsoType;
 
-            state.PlayableStreamFileNames = mediaSource.PlayableStreamFileNames.ToList();
+                if (mediaSource.VideoType.Value == VideoType.BluRay || mediaSource.VideoType.Value == VideoType.Dvd)
+                {
+                    state.PlayableStreamFileNames = Video.QueryPlayableStreamFiles(state.MediaPath, mediaSource.VideoType.Value);
+                }
+                else if (mediaSource.VideoType.Value == VideoType.Iso && state.IsoType == IsoType.BluRay)
+                {
+                    state.PlayableStreamFileNames = Video.QueryPlayableStreamFiles(state.MediaPath, VideoType.BluRay);
+                }
+                else if (mediaSource.VideoType.Value == VideoType.Iso && state.IsoType == IsoType.Dvd)
+                {
+                    state.PlayableStreamFileNames = Video.QueryPlayableStreamFiles(state.MediaPath, VideoType.Dvd);
+                }
+                else
+                {
+                    state.PlayableStreamFileNames = new List<string>();
+                }
+            }
+            else
+            {
+                state.PlayableStreamFileNames = new List<string>();
+            }
 
             if (mediaSource.Timestamp.HasValue)
             {

+ 1 - 1
MediaBrowser.Controller/Persistence/IItemRepository.cs

@@ -89,7 +89,7 @@ namespace MediaBrowser.Controller.Persistence
         /// </summary>
         /// <param name="query">The query.</param>
         /// <returns>IEnumerable{MediaStream}.</returns>
-        IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query);
+        List<MediaStream> GetMediaStreams(MediaStreamQuery query);
 
         /// <summary>
         /// Saves the media streams.

+ 0 - 2
MediaBrowser.Model/Dto/MediaSourceInfo.cs

@@ -53,7 +53,6 @@ namespace MediaBrowser.Model.Dto
         public Video3DFormat? Video3DFormat { get; set; }
 
         public List<MediaStream> MediaStreams { get; set; }
-        public List<string> PlayableStreamFileNames { get; set; }
 
         public List<string> Formats { get; set; }
 
@@ -73,7 +72,6 @@ namespace MediaBrowser.Model.Dto
             Formats = new List<string>();
             MediaStreams = new List<MediaStream>();
             RequiredHttpHeaders = new Dictionary<string, string>();
-            PlayableStreamFileNames = new List<string>();
             SupportsTranscoding = true;
             SupportsDirectStream = true;
             SupportsDirectPlay = true;

+ 1 - 3
MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs

@@ -41,9 +41,7 @@ namespace MediaBrowser.Providers.MediaInfo
             var audio = (Audio)item;
 
             var imageStreams =
-                audio.GetMediaSources(false)
-                    .Take(1)
-                    .SelectMany(i => i.MediaStreams)
+                audio.GetMediaStreams(MediaStreamType.EmbeddedImage)
                     .Where(i => i.Type == MediaStreamType.EmbeddedImage)
                     .ToList();
 

+ 29 - 49
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -80,35 +80,45 @@ namespace MediaBrowser.Providers.MediaInfo
 
             try
             {
-                if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
-                {
-                    var inputPath = isoMount != null ? isoMount.MountedPath : item.Path;
+                List<string> streamFileNames = null;
 
-                    blurayDiscInfo = GetBDInfo(inputPath);
+                if (item.VideoType == VideoType.Iso)
+                {
+                    item.IsoType = DetermineIsoType(isoMount);
                 }
 
-                OnPreFetch(item, isoMount, blurayDiscInfo);
-
-                // If we didn't find any satisfying the min length, just take them all
                 if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
                 {
-                    if (item.PlayableStreamFileNames.Count == 0)
+                    streamFileNames = FetchFromDvdLib(item, isoMount);
+
+                    if (streamFileNames.Count == 0)
                     {
                         _logger.Error("No playable vobs found in dvd structure, skipping ffprobe.");
                         return ItemUpdateType.MetadataImport;
                     }
                 }
 
-                if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
+                else if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
                 {
-                    if (item.PlayableStreamFileNames.Count == 0)
+                    var inputPath = isoMount != null ? isoMount.MountedPath : item.Path;
+
+                    blurayDiscInfo = GetBDInfo(inputPath);
+
+                    streamFileNames = blurayDiscInfo.Files;
+
+                    if (streamFileNames.Count == 0)
                     {
                         _logger.Error("No playable vobs found in bluray structure, skipping ffprobe.");
                         return ItemUpdateType.MetadataImport;
                     }
                 }
 
-                var result = await GetMediaInfo(item, isoMount, cancellationToken).ConfigureAwait(false);
+                if (streamFileNames == null)
+                {
+                    streamFileNames = new List<string>();
+                }
+
+                var result = await GetMediaInfo(item, isoMount, streamFileNames, cancellationToken).ConfigureAwait(false);
 
                 cancellationToken.ThrowIfCancellationRequested();
 
@@ -126,10 +136,9 @@ namespace MediaBrowser.Providers.MediaInfo
             return ItemUpdateType.MetadataImport;
         }
 
-        private const string SchemaVersion = "6";
-
-        private async Task<Model.MediaInfo.MediaInfo> GetMediaInfo(Video item,
+        private Task<Model.MediaInfo.MediaInfo> GetMediaInfo(Video item,
             IIsoMount isoMount,
+            List<string> streamFileNames,
             CancellationToken cancellationToken)
         {
             cancellationToken.ThrowIfCancellationRequested();
@@ -138,9 +147,9 @@ namespace MediaBrowser.Providers.MediaInfo
                 ? MediaProtocol.Http
                 : MediaProtocol.File;
 
-            var result = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
+            return _mediaEncoder.GetMediaInfo(new MediaInfoRequest
             {
-                PlayableStreamFileNames = item.PlayableStreamFileNames,
+                PlayableStreamFileNames = streamFileNames,
                 MountedIso = isoMount,
                 ExtractChapters = true,
                 VideoType = item.VideoType,
@@ -148,12 +157,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 InputPath = item.Path,
                 Protocol = protocol
 
-            }, cancellationToken).ConfigureAwait(false);
-
-            //Directory.CreateDirectory(_fileSystem.GetDirectoryName(cachePath));
-            //_json.SerializeToFile(result, cachePath);
-
-            return result;
+            }, cancellationToken);
         }
 
         protected async Task Fetch(Video video,
@@ -266,7 +270,7 @@ namespace MediaBrowser.Providers.MediaInfo
         {
             var video = (Video)item;
 
-            video.PlayableStreamFileNames = blurayInfo.Files.ToList();
+            //video.PlayableStreamFileNames = blurayInfo.Files.ToList();
 
             // Use BD Info if it has multiple m2ts. Otherwise, treat it like a video file and rely more on ffprobe output
             if (blurayInfo.Files.Count > 1)
@@ -559,31 +563,7 @@ namespace MediaBrowser.Providers.MediaInfo
             }
         }
 
-        /// <summary>
-        /// Called when [pre fetch].
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="mount">The mount.</param>
-        /// <param name="blurayDiscInfo">The bluray disc information.</param>
-        private void OnPreFetch(Video item, IIsoMount mount, BlurayDiscInfo blurayDiscInfo)
-        {
-            if (item.VideoType == VideoType.Iso)
-            {
-                item.IsoType = DetermineIsoType(mount);
-            }
-
-            if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
-            {
-                FetchFromDvdLib(item, mount);
-            }
-
-            if (blurayDiscInfo != null)
-            {
-                item.PlayableStreamFileNames = blurayDiscInfo.Files.ToList();
-            }
-        }
-
-        private void FetchFromDvdLib(Video item, IIsoMount mount)
+        private List<string> FetchFromDvdLib(Video item, IIsoMount mount)
         {
             var path = mount == null ? item.Path : mount.MountedPath;
             var dvd = new Dvd(path, _fileSystem);
@@ -598,7 +578,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 item.RunTimeTicks = GetRuntime(primaryTitle);
             }
 
-            item.PlayableStreamFileNames = GetPrimaryPlaylistVobFiles(item, mount, titleNumber)
+            return GetPrimaryPlaylistVobFiles(item, mount, titleNumber)
                 .Select(Path.GetFileName)
                 .ToList();
         }

+ 48 - 90
MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs

@@ -18,44 +18,17 @@ namespace MediaBrowser.Providers.MediaInfo
 {
     public class VideoImageProvider : IDynamicImageProvider, IHasItemChangeMonitor, IHasOrder
     {
-        private readonly IIsoManager _isoManager;
         private readonly IMediaEncoder _mediaEncoder;
-        private readonly IServerConfigurationManager _config;
-        private readonly ILibraryManager _libraryManager;
         private readonly ILogger _logger;
         private readonly IFileSystem _fileSystem;
 
-        public VideoImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config, ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem)
+        public VideoImageProvider(IMediaEncoder mediaEncoder, ILogger logger, IFileSystem fileSystem)
         {
-            _isoManager = isoManager;
             _mediaEncoder = mediaEncoder;
-            _config = config;
-            _libraryManager = libraryManager;
             _logger = logger;
             _fileSystem = fileSystem;
         }
 
-        /// <summary>
-        /// The null mount task result
-        /// </summary>
-        protected readonly Task<IIsoMount> NullMountTaskResult = Task.FromResult<IIsoMount>(null);
-
-        /// <summary>
-        /// Mounts the iso if needed.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task{IIsoMount}.</returns>
-        protected Task<IIsoMount> MountIsoIfNeeded(Video item, CancellationToken cancellationToken)
-        {
-            if (item.VideoType == VideoType.Iso)
-            {
-                return _isoManager.Mount(item.Path, cancellationToken);
-            }
-
-            return NullMountTaskResult;
-        }
-
         public IEnumerable<ImageType> GetSupportedImages(IHasImages item)
         {
             return new List<ImageType> { ImageType.Primary };
@@ -71,8 +44,8 @@ namespace MediaBrowser.Providers.MediaInfo
                 return Task.FromResult(new DynamicImageResponse { HasImage = false });
             }
 
-            // Can't extract from iso's if we weren't unable to determine iso type
-            if (video.VideoType == VideoType.Iso && !video.IsoType.HasValue)
+            // No support for this
+            if (video.VideoType == VideoType.Iso)
             {
                 return Task.FromResult(new DynamicImageResponse { HasImage = false });
             }
@@ -89,81 +62,66 @@ namespace MediaBrowser.Providers.MediaInfo
 
         public async Task<DynamicImageResponse> GetVideoImage(Video item, CancellationToken cancellationToken)
         {
-            var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);
-
-            try
-            {
-                var protocol = item.LocationType == LocationType.Remote
-                    ? MediaProtocol.Http
-                    : MediaProtocol.File;
+            var protocol = item.LocationType == LocationType.Remote
+                ? MediaProtocol.Http
+                : MediaProtocol.File;
 
-                var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, item.Path, protocol, isoMount, item.PlayableStreamFileNames);
+            var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, item.Path, protocol, null, item.GetPlayableStreamFileNames());
 
-                var mediaStreams =
-                    item.GetMediaSources(false)
-                        .Take(1)
-                        .SelectMany(i => i.MediaStreams)
-                        .ToList();
+            var mediaStreams =
+                item.GetMediaStreams();
 
-                var imageStreams =
-                    mediaStreams
-                        .Where(i => i.Type == MediaStreamType.EmbeddedImage)
-                        .ToList();
+            var imageStreams =
+                mediaStreams
+                    .Where(i => i.Type == MediaStreamType.EmbeddedImage)
+                    .ToList();
 
-                var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ??
-                    imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1) ??
-                    imageStreams.FirstOrDefault();
+            var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ??
+                imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1) ??
+                imageStreams.FirstOrDefault();
 
-                string extractedImagePath;
+            string extractedImagePath;
 
-                if (imageStream != null)
+            if (imageStream != null)
+            {
+                // Instead of using the raw stream index, we need to use nth video/embedded image stream
+                var videoIndex = -1;
+                foreach (var mediaStream in mediaStreams)
                 {
-                    // Instead of using the raw stream index, we need to use nth video/embedded image stream
-                    var videoIndex = -1;
-                    foreach (var mediaStream in mediaStreams)
+                    if (mediaStream.Type == MediaStreamType.Video ||
+                        mediaStream.Type == MediaStreamType.EmbeddedImage)
                     {
-                        if (mediaStream.Type == MediaStreamType.Video ||
-                            mediaStream.Type == MediaStreamType.EmbeddedImage)
-                        {
-                            videoIndex++;
-                        }
-                        if (mediaStream == imageStream)
-                        {
-                            break;
-                        }
+                        videoIndex++;
+                    }
+                    if (mediaStream == imageStream)
+                    {
+                        break;
                     }
-
-                    extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, imageStream, videoIndex, cancellationToken).ConfigureAwait(false);
                 }
-                else
-                {
-                    // If we know the duration, grab it from 10% into the video. Otherwise just 10 seconds in.
-                    // Always use 10 seconds for dvd because our duration could be out of whack
-                    var imageOffset = item.VideoType != VideoType.Dvd && item.RunTimeTicks.HasValue &&
-                                      item.RunTimeTicks.Value > 0
-                                          ? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1))
-                                          : TimeSpan.FromSeconds(10);
 
-                    var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
+                extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, imageStream, videoIndex, cancellationToken).ConfigureAwait(false);
+            }
+            else
+            {
+                // If we know the duration, grab it from 10% into the video. Otherwise just 10 seconds in.
+                // Always use 10 seconds for dvd because our duration could be out of whack
+                var imageOffset = item.VideoType != VideoType.Dvd && item.RunTimeTicks.HasValue &&
+                                  item.RunTimeTicks.Value > 0
+                                      ? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1))
+                                      : TimeSpan.FromSeconds(10);
 
-                    extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoStream, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
-                }
+                var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
 
-                return new DynamicImageResponse
-                {
-                    Format = ImageFormat.Jpg,
-                    HasImage = true,
-                    Path = extractedImagePath,
-                    Protocol = MediaProtocol.File
-                };
+                extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoStream, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
             }
-            finally
+
+            return new DynamicImageResponse
             {
-                if (isoMount != null)
-                {
-                    isoMount.Dispose();
-                }
-            }
+                Format = ImageFormat.Jpg,
+                HasImage = true,
+                Path = extractedImagePath,
+                Protocol = MediaProtocol.File
+            };
         }
 
         public string Name

+ 5 - 4
MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs

@@ -300,9 +300,9 @@ namespace MediaBrowser.XbmcMetadata.Savers
             writer.WriteStartElement("fileinfo");
             writer.WriteStartElement("streamdetails");
 
-            var mediaSource = item.GetMediaSources(false).First();
+            var mediaStreams = item.GetMediaStreams();
 
-            foreach (var stream in mediaSource.MediaStreams)
+            foreach (var stream in mediaStreams)
             {
                 writer.WriteStartElement(stream.Type.ToString().ToLower());
 
@@ -378,9 +378,10 @@ namespace MediaBrowser.XbmcMetadata.Savers
 
                 if (stream.Type == MediaStreamType.Video)
                 {
-                    if (mediaSource.RunTimeTicks.HasValue)
+                    var runtimeTicks = ((IHasMetadata) item).RunTimeTicks;
+                    if (runtimeTicks.HasValue)
                     {
-                        var timespan = TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value);
+                        var timespan = TimeSpan.FromTicks(runtimeTicks.Value);
 
                         writer.WriteElementString("duration", Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture));
                         writer.WriteElementString("durationinseconds", Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture));