diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 8bab285613..137487cef2 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -55,3 +55,4 @@
- [jordy1955] (https://github.com/jordy1955)
- [JoshFink] (https://github.com/JoshFink)
- [Detector1](https://github.com/Detector1)
+ - [BlackIce013](https://github.com/blackice013)
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index fc98e2a734..f5bf14cf96 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -146,9 +146,9 @@ namespace MediaBrowser.Api.Playback.Hls
builder.AppendLine(playlistUrl);
// Low bitrate stream
- builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=64000");
- playlistUrl = "hls/" + Path.GetFileName(firstPlaylist).Replace(".m3u8", "-low/stream.m3u8");
- builder.AppendLine(playlistUrl);
+ //builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=64000");
+ //playlistUrl = "hls/" + Path.GetFileName(firstPlaylist).Replace(".m3u8", "-low/stream.m3u8");
+ //builder.AppendLine(playlistUrl);
return builder.ToString();
}
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index 5e0bfca971..d06941bb81 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -172,6 +172,9 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string AdjacentTo { get; set; }
+ [ApiMember(Name = "MinIndexNumber", Description = "Optional filter index number.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? MinIndexNumber { get; set; }
+
///
/// Gets the order by.
///
@@ -511,6 +514,12 @@ namespace MediaBrowser.Api.UserLibrary
items = items.Where(i => i.Id == previousId || i.Id == nextId);
}
+ // Min index number
+ if (request.MinIndexNumber.HasValue)
+ {
+ items = items.Where(i => i.IndexNumber.HasValue && i.IndexNumber.Value >= request.MinIndexNumber.Value);
+ }
+
// Min official rating
if (!string.IsNullOrEmpty(request.MinOfficialRating))
{
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index a6c53b4a42..de25651ed7 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session;
@@ -325,7 +326,7 @@ namespace MediaBrowser.Api.UserLibrary
/// Class GetSpecialFeatures
///
[Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET")]
- [Api(Description = "Gets special features for a movie")]
+ [Api(Description = "Gets special features for an item")]
public class GetSpecialFeatures : IReturn>
{
///
@@ -404,16 +405,40 @@ namespace MediaBrowser.Api.UserLibrary
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
- var movie = (Movie)item;
-
var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository, _itemRepo);
- var tasks = movie.SpecialFeatureIds
- .Select(_itemRepo.RetrieveItem)
- .OrderBy(i => i.SortName)
- .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user, movie));
+ var movie = item as Movie;
- return Task.WhenAll(tasks);
+ // Get them from the db
+ if (movie != null)
+ {
+ // Avoid implicitly captured closure
+ var movie1 = movie;
+
+ var tasks = movie.SpecialFeatureIds
+ .Select(_itemRepo.RetrieveItem)
+ .OrderBy(i => i.SortName)
+ .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user, movie1));
+
+ return Task.WhenAll(tasks);
+ }
+
+ var series = item as Series;
+
+ // Get them from the child tree
+ if (series != null)
+ {
+ var tasks = series
+ .RecursiveChildren
+ .OfType()
+ .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
+ .OrderBy(i => i.SortName)
+ .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user));
+
+ return Task.WhenAll(tasks);
+ }
+
+ throw new ArgumentException("The item does not support special features");
}
///
@@ -589,7 +614,7 @@ namespace MediaBrowser.Api.UserLibrary
return DtoBuilder.GetUserItemDataDto(data);
}
-
+
///
/// Posts the specified request.
///
diff --git a/MediaBrowser.Controller/Dto/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs
index b2b858b6da..f762c7cc6b 100644
--- a/MediaBrowser.Controller/Dto/DtoBuilder.cs
+++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs
@@ -104,35 +104,11 @@ namespace MediaBrowser.Controller.Dto
if (fields.Contains(ItemFields.SoundtrackIds))
{
- var series = item as Series;
-
- if (series != null)
- {
- AttachSoundtrackIds(dto, series, user);
- }
-
- var movie = item as Movie;
-
- if (movie != null)
- {
- AttachSoundtrackIds(dto, movie, user);
- }
-
- var album = item as MusicAlbum;
-
- if (album != null)
- {
- AttachSoundtrackIds(dto, album, user);
- }
-
- var game = item as Game;
-
- if (game != null)
- {
- AttachSoundtrackIds(dto, game, user);
- }
+ dto.SoundtrackIds = item.SoundtrackIds
+ .Select(i => i.ToString("N"))
+ .ToArray();
}
-
+
// Make sure all the tasks we kicked off have completed.
if (tasks.Count > 0)
{
@@ -142,132 +118,6 @@ namespace MediaBrowser.Controller.Dto
return dto;
}
- private void AttachSoundtrackIds(BaseItemDto dto, Movie item, User user)
- {
- var tmdb = item.GetProviderId(MetadataProviders.Tmdb);
-
- if (string.IsNullOrEmpty(tmdb))
- {
- return;
- }
-
- var recursiveChildren = user == null
- ? _libraryManager.RootFolder.RecursiveChildren
- : user.RootFolder.GetRecursiveChildren(user);
-
- dto.SoundtrackIds = recursiveChildren
- .Where(i =>
- {
- if (!string.IsNullOrEmpty(tmdb) &&
- string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) &&
- i is MusicAlbum)
- {
- return true;
- }
- return false;
- })
- .Select(GetClientItemId)
- .ToArray();
- }
-
- private void AttachSoundtrackIds(BaseItemDto dto, Series item, User user)
- {
- var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
-
- if (string.IsNullOrEmpty(tvdb))
- {
- return;
- }
-
- var recursiveChildren = user == null
- ? _libraryManager.RootFolder.RecursiveChildren
- : user.RootFolder.GetRecursiveChildren(user);
-
- dto.SoundtrackIds = recursiveChildren
- .Where(i =>
- {
- if (!string.IsNullOrEmpty(tvdb) &&
- string.Equals(tvdb, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase) &&
- i is MusicAlbum)
- {
- return true;
- }
- return false;
- })
- .Select(GetClientItemId)
- .ToArray();
- }
-
- private void AttachSoundtrackIds(BaseItemDto dto, Game item, User user)
- {
- var gamesdb = item.GetProviderId(MetadataProviders.Gamesdb);
-
- if (string.IsNullOrEmpty(gamesdb))
- {
- return;
- }
-
- var recursiveChildren = user == null
- ? _libraryManager.RootFolder.RecursiveChildren
- : user.RootFolder.GetRecursiveChildren(user);
-
- dto.SoundtrackIds = recursiveChildren
- .Where(i =>
- {
- if (!string.IsNullOrEmpty(gamesdb) &&
- string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase) &&
- i is MusicAlbum)
- {
- return true;
- }
- return false;
- })
- .Select(GetClientItemId)
- .ToArray();
- }
-
- private void AttachSoundtrackIds(BaseItemDto dto, MusicAlbum item, User user)
- {
- var tmdb = item.GetProviderId(MetadataProviders.Tmdb);
- var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
- var gamesdb = item.GetProviderId(MetadataProviders.Gamesdb);
-
- if (string.IsNullOrEmpty(tmdb) && string.IsNullOrEmpty(tvdb) && string.IsNullOrEmpty(gamesdb))
- {
- return;
- }
-
- var recursiveChildren = user == null
- ? _libraryManager.RootFolder.RecursiveChildren
- : user.RootFolder.GetRecursiveChildren(user);
-
- dto.SoundtrackIds = recursiveChildren
- .Where(i =>
- {
- if (!string.IsNullOrEmpty(tmdb) &&
- string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) &&
- i is Movie)
- {
- return true;
- }
- if (!string.IsNullOrEmpty(tvdb) &&
- string.Equals(tvdb, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase) &&
- i is Series)
- {
- return true;
- }
- if (!string.IsNullOrEmpty(gamesdb) &&
- string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase) &&
- i is Game)
- {
- return true;
- }
- return false;
- })
- .Select(GetClientItemId)
- .ToArray();
- }
-
///
/// Attaches the user specific info.
///
@@ -682,6 +532,10 @@ namespace MediaBrowser.Controller.Dto
dto.AirDays = series.AirDays;
dto.AirTime = series.AirTime;
dto.Status = series.Status;
+
+ dto.SpecialFeatureCount = series.SpecialFeatureIds.Count;
+
+ dto.SeasonCount = series.SeasonCount;
}
if (episode != null)
@@ -716,6 +570,18 @@ namespace MediaBrowser.Controller.Dto
{
SetMusicVideoProperties(dto, musicVideo);
}
+
+ var book = item as Book;
+
+ if (book != null)
+ {
+ SetBookProperties(dto, book);
+ }
+ }
+
+ private void SetBookProperties(BaseItemDto dto, Book item)
+ {
+ dto.SeriesName = item.SeriesName;
}
private void SetMusicVideoProperties(BaseItemDto dto, MusicVideo item)
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 3c8c2411ec..e756d22113 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -23,6 +23,11 @@ namespace MediaBrowser.Controller.Entities
///
public abstract class BaseItem : IHasProviderIds
{
+ ///
+ /// MusicAlbums in the library that are the soundtrack for this item
+ ///
+ public List SoundtrackIds { get; set; }
+
protected BaseItem()
{
Genres = new List();
@@ -38,6 +43,7 @@ namespace MediaBrowser.Controller.Entities
Tags = new List();
ThemeSongIds = new List();
ThemeVideoIds = new List();
+ SoundtrackIds = new List();
LocalTrailerIds = new List();
LockedFields = new List();
}
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
new file mode 100644
index 0000000000..20df731a78
--- /dev/null
+++ b/MediaBrowser.Controller/Entities/Book.cs
@@ -0,0 +1,35 @@
+
+namespace MediaBrowser.Controller.Entities
+{
+ public class Book : BaseItem
+ {
+ public override string MediaType
+ {
+ get
+ {
+ return Model.Entities.MediaType.Book;
+ }
+ }
+
+ public string SeriesName { get; set; }
+
+ ///
+ ///
+ ///
+ public override string MetaLocation
+ {
+ get
+ {
+ return System.IO.Path.GetDirectoryName(Path);
+ }
+ }
+
+ protected override bool UseParentPathToCreateResolveArgs
+ {
+ get
+ {
+ return !IsInMixedFolder;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 2458e56193..1e4d56e1a5 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -13,9 +13,15 @@ namespace MediaBrowser.Controller.Entities.TV
///
public class Series : Folder
{
+ public List SpecialFeatureIds { get; set; }
+
+ public int SeasonCount { get; set; }
+
public Series()
{
AirDays = new List();
+
+ SpecialFeatureIds = new List();
}
///
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index bbc73d0ad7..e0e8b78e19 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -72,6 +72,7 @@
Properties\SharedVersion.cs
+
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index fa9ed2536a..b843465dfc 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -138,6 +138,8 @@ namespace MediaBrowser.Model.Dto
/// The production year.
public int? ProductionYear { get; set; }
+ public int? SeasonCount { get; set; }
+
///
/// Gets or sets the players supported by a game.
///
diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs
index 18b263960a..fe9848513d 100644
--- a/MediaBrowser.Model/Querying/ItemQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemQuery.cs
@@ -176,6 +176,8 @@ namespace MediaBrowser.Model.Querying
/// The max official rating.
public string MaxOfficialRating { get; set; }
+ public int? MinIndexNumber { get; set; }
+
///
/// Initializes a new instance of the class.
///
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 28e6173789..9d07394944 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -81,6 +81,7 @@
+
@@ -106,6 +107,7 @@
+
diff --git a/MediaBrowser.Providers/Movies/MovieXmlParser.cs b/MediaBrowser.Providers/Movies/MovieXmlParser.cs
index a265419554..7361be04f5 100644
--- a/MediaBrowser.Providers/Movies/MovieXmlParser.cs
+++ b/MediaBrowser.Providers/Movies/MovieXmlParser.cs
@@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Movies
{
case "Chapters":
- _chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None);
+ //_chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None);
break;
default:
diff --git a/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs
new file mode 100644
index 0000000000..18868d3eae
--- /dev/null
+++ b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs
@@ -0,0 +1,159 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.Music
+{
+ public class SoundtrackPostScanTask : ILibraryPostScanTask
+ {
+ private readonly ILibraryManager _libraryManager;
+
+ public SoundtrackPostScanTask(ILibraryManager libraryManager)
+ {
+ _libraryManager = libraryManager;
+ }
+
+ public Task Run(IProgress progress, CancellationToken cancellationToken)
+ {
+ return Task.Run(() => RunInternal(progress, cancellationToken));
+ }
+
+ private void RunInternal(IProgress progress, CancellationToken cancellationToken)
+ {
+ var allItems = _libraryManager.RootFolder
+ .RecursiveChildren
+ .ToList();
+
+ var musicAlbums = allItems
+ .OfType()
+ .ToList();
+
+ AttachMovieSoundtracks(allItems, musicAlbums, cancellationToken);
+
+ progress.Report(25);
+
+ AttachTvSoundtracks(allItems, musicAlbums, cancellationToken);
+
+ progress.Report(50);
+
+ AttachGameSoundtracks(allItems, musicAlbums, cancellationToken);
+
+ progress.Report(75);
+
+ AttachAlbumLinks(allItems, musicAlbums, cancellationToken);
+
+ progress.Report(100);
+ }
+
+ private void AttachMovieSoundtracks(IEnumerable allItems, List allAlbums, CancellationToken cancellationToken)
+ {
+ foreach (var movie in allItems
+ .Where(i => (i is Movie) || (i is Trailer)))
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var tmdbId = movie.GetProviderId(MetadataProviders.Tmdb);
+
+ if (string.IsNullOrEmpty(tmdbId))
+ {
+ movie.SoundtrackIds = new List();
+ continue;
+ }
+
+ movie.SoundtrackIds = allAlbums
+ .Where(i => string.Equals(tmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase))
+ .Select(i => i.Id)
+ .ToList();
+ }
+ }
+
+ private void AttachTvSoundtracks(IEnumerable allItems, List allAlbums, CancellationToken cancellationToken)
+ {
+ foreach (var series in allItems.OfType())
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var tvdbId = series.GetProviderId(MetadataProviders.Tvdb);
+
+ if (string.IsNullOrEmpty(tvdbId))
+ {
+ series.SoundtrackIds = new List();
+ continue;
+ }
+
+ series.SoundtrackIds = allAlbums
+ .Where(i => string.Equals(tvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase))
+ .Select(i => i.Id)
+ .ToList();
+ }
+ }
+
+ private void AttachGameSoundtracks(IEnumerable allItems, List allAlbums, CancellationToken cancellationToken)
+ {
+ foreach (var game in allItems.OfType())
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var gamesdb = game.GetProviderId(MetadataProviders.Gamesdb);
+
+ if (string.IsNullOrEmpty(gamesdb))
+ {
+ game.SoundtrackIds = new List();
+ continue;
+ }
+
+ game.SoundtrackIds = allAlbums
+ .Where(i => string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase))
+ .Select(i => i.Id)
+ .ToList();
+ }
+ }
+
+ private void AttachAlbumLinks(List allItems, IEnumerable allAlbums, CancellationToken cancellationToken)
+ {
+ foreach (var album in allAlbums)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var tmdb = album.GetProviderId(MetadataProviders.Tmdb);
+ var tvdb = album.GetProviderId(MetadataProviders.Tvdb);
+ var gamesdb = album.GetProviderId(MetadataProviders.Gamesdb);
+
+ if (string.IsNullOrEmpty(tmdb) && string.IsNullOrEmpty(tvdb) && string.IsNullOrEmpty(gamesdb))
+ {
+ album.SoundtrackIds = new List();
+ continue;
+ }
+
+ album.SoundtrackIds = allItems.
+ Where(i =>
+ {
+ if (!string.IsNullOrEmpty(tmdb) && string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) && i is Movie)
+ {
+ return true;
+ }
+ if (!string.IsNullOrEmpty(tmdb) && string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) && i is Trailer)
+ {
+ return true;
+ }
+ if (!string.IsNullOrEmpty(tvdb) && string.Equals(tvdb, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase) && i is Series)
+ {
+ return true;
+ }
+
+ return !string.IsNullOrEmpty(gamesdb) && string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase) && i is Game;
+ })
+ .Select(i => i.Id)
+ .ToList();
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
index b36f7966b6..d90cb94c29 100644
--- a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
@@ -81,8 +81,7 @@ namespace MediaBrowser.Providers.Savers
}
XmlSaverHelpers.AddCommonNodes(item, builder);
- XmlSaverHelpers.AddMediaInfo(episode, builder);
- XmlSaverHelpers.AddChapters((Video)item, builder, _itemRepository);
+ XmlSaverHelpers.AddMediaInfo(episode, builder, _itemRepository);
builder.Append("");
diff --git a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
index 154b4ab601..2402bcd7f5 100644
--- a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
@@ -97,9 +97,7 @@ namespace MediaBrowser.Providers.Savers
var video = (Video)item;
- XmlSaverHelpers.AddMediaInfo(video, builder);
-
- XmlSaverHelpers.AddChapters(video, builder, _itemRepository);
+ XmlSaverHelpers.AddMediaInfo(video, builder, _itemRepository);
builder.Append("");
diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
index edeea611a3..0ec4df0918 100644
--- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
@@ -451,9 +451,11 @@ namespace MediaBrowser.Providers.Savers
///
/// The item.
/// The builder.
- public static void AddMediaInfo(T item, StringBuilder builder)
+ public static void AddMediaInfo(T item, StringBuilder builder, IItemRepository itemRepository)
where T : BaseItem, IHasMediaStreams
{
+ var video = item as Video;
+
builder.Append("");
foreach (var stream in item.MediaStreams)
@@ -526,8 +528,6 @@ namespace MediaBrowser.Providers.Savers
builder.Append("" + Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture) + "");
}
- var video = item as Video;
-
if (video != null && video.Video3DFormat.HasValue)
{
switch (video.Video3DFormat.Value)
@@ -552,6 +552,11 @@ namespace MediaBrowser.Providers.Savers
}
builder.Append("");
+
+ if (video != null)
+ {
+ AddChapters(video, builder, itemRepository);
+ }
}
}
}
diff --git a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs
index 7920273007..837c7f4b9a 100644
--- a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs
+++ b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs
@@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.TV
{
case "Chapters":
- _chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None);
+ //_chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None);
break;
case "Episode":
diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
new file mode 100644
index 0000000000..a781551dee
--- /dev/null
+++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
@@ -0,0 +1,64 @@
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.TV
+{
+ class SeriesPostScanTask : ILibraryPostScanTask
+ {
+ ///
+ /// The _library manager
+ ///
+ private readonly ILibraryManager _libraryManager;
+
+ public SeriesPostScanTask(ILibraryManager libraryManager)
+ {
+ _libraryManager = libraryManager;
+ }
+
+ public Task Run(IProgress progress, CancellationToken cancellationToken)
+ {
+ return Task.Run(() => RunInternal(progress, cancellationToken));
+ }
+
+ private void RunInternal(IProgress progress, CancellationToken cancellationToken)
+ {
+ var seriesList = _libraryManager.RootFolder
+ .RecursiveChildren
+ .OfType()
+ .ToList();
+
+ var numComplete = 0;
+
+ foreach (var series in seriesList)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var episodes = series.RecursiveChildren
+ .OfType()
+ .ToList();
+
+ series.SpecialFeatureIds = episodes
+ .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
+ .Select(i => i.Id)
+ .ToList();
+
+ series.SeasonCount = episodes
+ .Select(i => i.ParentIndexNumber ?? 0)
+ .Where(i => i != 0)
+ .Distinct()
+ .Count();
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= seriesList.Count;
+ percent *= 100;
+
+ progress.Report(percent);
+ }
+ }
+ }
+}
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 156b69094e..fa21b23c0d 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.188
+ 3.0.189
MediaBrowser.Common.Internal
Luke
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.
Copyright © Media Browser 2013
-
+
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index e1e4adcb11..b2e257760d 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.188
+ 3.0.189
MediaBrowser.Common
Media Browser Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 3038388665..87e32a24d5 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.188
+ 3.0.189
Media Browser.Server.Core
Media Browser Team
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains core components required to build plugins for Media Browser Server.
Copyright © Media Browser 2013
-
+