aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-07-01 17:13:32 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-07-01 17:13:32 -0400
commit3bef6ead9cec4c33d43b6348ae4fc33c9b70316a (patch)
tree1c794728ddb74d046793dbde7fc590d6feee37f1
parent970504abdf237a2c404024c6978d5353ea915d03 (diff)
#514 - Support HLS seeking
-rw-r--r--MediaBrowser.Api/BaseApiService.cs9
-rw-r--r--MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs2
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs63
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs42
-rw-r--r--MediaBrowser.Api/Playback/Hls/VideoHlsService.cs13
-rw-r--r--MediaBrowser.Api/SearchService.cs4
-rw-r--r--MediaBrowser.Api/SimilarItemsHelper.cs4
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs27
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs12
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs7
-rw-r--r--MediaBrowser.Model/Configuration/UserConfiguration.cs2
-rw-r--r--MediaBrowser.Model/Dto/StudioDto.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Library/SearchEngine.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserViewManager.cs5
16 files changed, 110 insertions, 101 deletions
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 569e12530..f1d596213 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -159,7 +159,7 @@ namespace MediaBrowser.Api
return libraryManager.GetPerson(DeSlugPersonName(name, libraryManager));
}
- protected IList<BaseItem> GetAllLibraryItems(Guid? userId, IUserManager userManager, ILibraryManager libraryManager, string parentId = null)
+ protected IEnumerable<BaseItem> GetAllLibraryItems(Guid? userId, IUserManager userManager, ILibraryManager libraryManager, string parentId = null)
{
if (!string.IsNullOrEmpty(parentId))
{
@@ -169,7 +169,7 @@ namespace MediaBrowser.Api
{
var user = userManager.GetUserById(userId.Value);
- return folder.GetRecursiveChildren(user).ToList();
+ return folder.GetRecursiveChildren(user);
}
return folder.GetRecursiveChildren();
@@ -178,7 +178,7 @@ namespace MediaBrowser.Api
{
var user = userManager.GetUserById(userId.Value);
- return userManager.GetUserById(userId.Value).RootFolder.GetRecursiveChildren(user, null);
+ return userManager.GetUserById(userId.Value).RootFolder.GetRecursiveChildren(user);
}
return libraryManager.RootFolder.GetRecursiveChildren();
@@ -239,7 +239,8 @@ namespace MediaBrowser.Api
return name;
}
- return libraryManager.RootFolder.GetRecursiveChildren(i => i is Game)
+ return libraryManager.RootFolder.GetRecursiveChildren()
+ .OfType<Game>()
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
.FirstOrDefault(i =>
diff --git a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs
index 6acecd342..8bc867a2e 100644
--- a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs
+++ b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs
@@ -381,7 +381,7 @@ namespace MediaBrowser.Api.DefaultTheme
var currentUser1 = user;
var ownedEpisodes = series
- .SelectMany(i => i.GetRecursiveChildren(currentUser1, j => j.LocationType != LocationType.Virtual))
+ .SelectMany(i => i.GetRecursiveChildren(currentUser1).Where(j => j.LocationType != LocationType.Virtual))
.OfType<Episode>()
.ToList();
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 57c2244c7..fa78fa020 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -59,10 +59,11 @@ namespace MediaBrowser.Api.Playback.Hls
/// Processes the request.
/// </summary>
/// <param name="request">The request.</param>
+ /// <param name="isLive">if set to <c>true</c> [is live].</param>
/// <returns>System.Object.</returns>
- protected object ProcessRequest(StreamRequest request)
+ protected object ProcessRequest(StreamRequest request, bool isLive)
{
- return ProcessRequestAsync(request).Result;
+ return ProcessRequestAsync(request, isLive).Result;
}
private static readonly SemaphoreSlim FfmpegStartLock = new SemaphoreSlim(1, 1);
@@ -70,13 +71,12 @@ namespace MediaBrowser.Api.Playback.Hls
/// Processes the request async.
/// </summary>
/// <param name="request">The request.</param>
+ /// <param name="isLive">if set to <c>true</c> [is live].</param>
/// <returns>Task{System.Object}.</returns>
- /// <exception cref="ArgumentException">
- /// A video bitrate is required
+ /// <exception cref="ArgumentException">A video bitrate is required
/// or
- /// An audio bitrate is required
- /// </exception>
- private async Task<object> ProcessRequestAsync(StreamRequest request)
+ /// An audio bitrate is required</exception>
+ private async Task<object> ProcessRequestAsync(StreamRequest request, bool isLive)
{
var cancellationTokenSource = new CancellationTokenSource();
@@ -110,7 +110,8 @@ namespace MediaBrowser.Api.Playback.Hls
throw;
}
- await WaitForMinimumSegmentCount(playlist, GetSegmentWait(), cancellationTokenSource.Token).ConfigureAwait(false);
+ var waitCount = isLive ? 1 : GetSegmentWait();
+ await WaitForMinimumSegmentCount(playlist, waitCount, cancellationTokenSource.Token).ConfigureAwait(false);
}
}
finally
@@ -119,6 +120,22 @@ namespace MediaBrowser.Api.Playback.Hls
}
}
+ if (isLive)
+ {
+ //var file = request.PlaylistId + Path.GetExtension(Request.PathInfo);
+
+ //file = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, file);
+
+ try
+ {
+ return ResultFactory.GetStaticFileResult(Request, playlist, FileShare.ReadWrite);
+ }
+ finally
+ {
+ ApiEntryPoint.Instance.OnTranscodeEndRequest(playlist, TranscodingJobType.Hls);
+ }
+ }
+
var audioBitrate = state.OutputAudioBitrate ?? 0;
var videoBitrate = state.OutputVideoBitrate ?? 0;
@@ -188,16 +205,18 @@ namespace MediaBrowser.Api.Playback.Hls
protected async Task WaitForMinimumSegmentCount(string playlist, int segmentCount, CancellationToken cancellationToken)
{
- var count = 0;
+ Logger.Debug("Waiting for {0} segments in {1}", segmentCount, playlist);
- // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
- using (var fileStream = FileSystem.GetFileStream(playlist, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
+ while (true)
{
- using (var reader = new StreamReader(fileStream))
+ // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
+ using (var fileStream = FileSystem.GetFileStream(playlist, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
{
- while (true)
+ using (var reader = new StreamReader(fileStream))
{
- if (!reader.EndOfStream)
+ var count = 0;
+
+ while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync().ConfigureAwait(false);
@@ -206,11 +225,12 @@ namespace MediaBrowser.Api.Playback.Hls
count++;
if (count >= segmentCount)
{
+ Logger.Debug("Finished waiting for {0} segments in {1}", segmentCount, playlist);
return;
}
}
}
- await Task.Delay(25, cancellationToken).ConfigureAwait(false);
+ await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
}
}
@@ -229,7 +249,7 @@ namespace MediaBrowser.Api.Playback.Hls
var itsOffsetMs = hlsVideoRequest == null
? 0
- : ((GetHlsVideoStream)state.VideoRequest).TimeStampOffsetMs;
+ : hlsVideoRequest.TimeStampOffsetMs;
var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds.ToString(UsCulture));
@@ -240,7 +260,15 @@ namespace MediaBrowser.Api.Playback.Hls
// If isEncoding is true we're actually starting ffmpeg
var startNumberParam = isEncoding ? GetStartNumber(state).ToString(UsCulture) : "0";
- var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"",
+ var baseUrlParam = string.Empty;
+
+ if (state.Request is GetLiveHlsStream)
+ {
+ baseUrlParam = string.Format(" -hls_base_url \"{0}/\"",
+ "hls/" + Path.GetFileNameWithoutExtension(outputPath));
+ }
+
+ var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9}{10} -y \"{11}\"",
itsOffset,
inputModifier,
GetInputArgument(state),
@@ -251,6 +279,7 @@ namespace MediaBrowser.Api.Playback.Hls
state.SegmentLength.ToString(UsCulture),
startNumberParam,
state.HlsListSize.ToString(UsCulture),
+ baseUrlParam,
outputPath
).Trim();
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index bde2c5694..5bb610686 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -22,11 +22,6 @@ namespace MediaBrowser.Api.Playback.Hls
[Api(Description = "Gets a video stream using HTTP live streaming.")]
public class GetMasterHlsVideoStream : VideoStreamRequest
{
- [ApiMember(Name = "BaselineStreamAudioBitRate", Description = "Optional. Specify the audio bitrate for the baseline stream.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
- public int? BaselineStreamAudioBitRate { get; set; }
-
- [ApiMember(Name = "AppendBaselineStream", Description = "Optional. Whether or not to include a baseline audio-only stream in the master playlist.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
- public bool AppendBaselineStream { get; set; }
}
[Route("/Videos/{Id}/main.m3u8", "GET")]
@@ -35,12 +30,6 @@ namespace MediaBrowser.Api.Playback.Hls
{
}
- [Route("/Videos/{Id}/baseline.m3u8", "GET")]
- [Api(Description = "Gets a video stream using HTTP live streaming.")]
- public class GetBaselineHlsVideoStream : VideoStreamRequest
- {
- }
-
/// <summary>
/// Class GetHlsVideoSegment
/// </summary>
@@ -73,16 +62,11 @@ namespace MediaBrowser.Api.Playback.Hls
public object Get(GetDynamicHlsVideoSegment request)
{
- if (string.Equals("baseline", request.PlaylistId, StringComparison.OrdinalIgnoreCase))
- {
- return GetDynamicSegment(request, false).Result;
- }
-
- return GetDynamicSegment(request, true).Result;
+ return GetDynamicSegment(request).Result;
}
private static readonly SemaphoreSlim FfmpegStartLock = new SemaphoreSlim(1, 1);
- private async Task<object> GetDynamicSegment(GetDynamicHlsVideoSegment request, bool isMain)
+ private async Task<object> GetDynamicSegment(GetDynamicHlsVideoSegment request)
{
if ((request.StartTimeTicks ?? 0) > 0)
{
@@ -322,7 +306,9 @@ namespace MediaBrowser.Api.Playback.Hls
var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex);
// Main stream
- var playlistUrl = "main.m3u8" + queryString;
+ var playlistUrl = (state.RunTimeTicks ?? 0) > 0 ? "main.m3u8" : "live.m3u8";
+ playlistUrl += queryString;
+
AppendPlaylist(builder, playlistUrl, totalBitrate);
if (state.VideoRequest.VideoBitRate.HasValue)
@@ -385,13 +371,6 @@ namespace MediaBrowser.Api.Playback.Hls
return result;
}
- public object Get(GetBaselineHlsVideoStream request)
- {
- var result = GetPlaylistAsync(request, "baseline").Result;
-
- return result;
- }
-
private async Task<object> GetPlaylistAsync(VideoStreamRequest request, string name)
{
var state = await GetState(request, CancellationToken.None).ConfigureAwait(false);
@@ -506,14 +485,6 @@ namespace MediaBrowser.Api.Playback.Hls
/// <returns>System.String.</returns>
protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding)
{
- var hlsVideoRequest = state.VideoRequest as GetHlsVideoStream;
-
- var itsOffsetMs = hlsVideoRequest == null
- ? 0
- : ((GetHlsVideoStream)state.VideoRequest).TimeStampOffsetMs;
-
- var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds.ToString(UsCulture));
-
var threads = GetNumberOfThreads(state, false);
var inputModifier = GetInputModifier(state);
@@ -521,8 +492,7 @@ namespace MediaBrowser.Api.Playback.Hls
// If isEncoding is true we're actually starting ffmpeg
var startNumberParam = isEncoding ? GetStartNumber(state).ToString(UsCulture) : "0";
- var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} -flags -global_header {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"",
- itsOffset,
+ var args = string.Format("{0} -i {1} -map_metadata -1 -threads {2} {3} {4} -flags -global_header {5} -hls_time {6} -start_number {7} -hls_list_size {8} -y \"{9}\"",
inputModifier,
GetInputArgument(state),
threads,
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index 1a925378b..28c0219fc 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -32,6 +32,12 @@ namespace MediaBrowser.Api.Playback.Hls
public int TimeStampOffsetMs { get; set; }
}
+ [Route("/Videos/{Id}/live.m3u8", "GET")]
+ [Api(Description = "Gets a video stream using HTTP live streaming.")]
+ public class GetLiveHlsStream : VideoStreamRequest
+ {
+ }
+
/// <summary>
/// Class GetHlsVideoSegment
/// </summary>
@@ -105,7 +111,12 @@ namespace MediaBrowser.Api.Playback.Hls
/// <returns>System.Object.</returns>
public object Get(GetHlsVideoStream request)
{
- return ProcessRequest(request);
+ return ProcessRequest(request, false);
+ }
+
+ public object Get(GetLiveHlsStream request)
+ {
+ return ProcessRequest(request, true);
}
/// <summary>
diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs
index 9fcbe39eb..e72edcc98 100644
--- a/MediaBrowser.Api/SearchService.cs
+++ b/MediaBrowser.Api/SearchService.cs
@@ -192,14 +192,14 @@ namespace MediaBrowser.Api
{
result.Series = season.Series.Name;
- result.EpisodeCount = season.GetRecursiveChildren(i => i is Episode).Count;
+ result.EpisodeCount = season.GetRecursiveChildren().Count(i => i is Episode);
}
var series = item as Series;
if (series != null)
{
- result.EpisodeCount = series.GetRecursiveChildren(i => i is Episode).Count;
+ result.EpisodeCount = series.GetRecursiveChildren().Count(i => i is Episode);
}
var album = item as MusicAlbum;
diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs
index 660b55f30..2da29928b 100644
--- a/MediaBrowser.Api/SimilarItemsHelper.cs
+++ b/MediaBrowser.Api/SimilarItemsHelper.cs
@@ -78,8 +78,8 @@ namespace MediaBrowser.Api
var fields = request.GetItemFields().ToList();
var inputItems = user == null
- ? libraryManager.RootFolder.GetRecursiveChildren(i => i.Id != item.Id)
- : user.RootFolder.GetRecursiveChildren(user, i => i.Id != item.Id);
+ ? libraryManager.RootFolder.GetRecursiveChildren().Where(i => i.Id != item.Id)
+ : user.RootFolder.GetRecursiveChildren(user).Where(i => i.Id != item.Id);
var items = GetSimilaritems(item, inputItems.Where(includeInSearch), getSimilarityScore)
.ToList();
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index 96bbd6dff..a1625d052 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -541,7 +541,8 @@ namespace MediaBrowser.Api.UserLibrary
if (series != null)
{
var dtos = series
- .GetRecursiveChildren(i => i is Episode && i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
+ .GetRecursiveChildren()
+ .Where(i => i is Episode && i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
.OrderBy(i =>
{
if (i.PremiereDate.HasValue)
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index c712d50af..52c414ae8 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -857,19 +857,6 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="System.ArgumentNullException"></exception>
public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true)
{
- return GetRecursiveChildren(user, null, includeLinkedChildren);
- }
-
- /// <summary>
- /// Gets the recursive children.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <param name="filter">The filter.</param>
- /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
- /// <returns>IList{BaseItem}.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public IList<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter, bool includeLinkedChildren = true)
- {
if (user == null)
{
throw new ArgumentNullException("user");
@@ -877,7 +864,7 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
- var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, true, filter);
+ var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, true, null);
return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list;
}
@@ -888,19 +875,9 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IList{BaseItem}.</returns>
public IList<BaseItem> GetRecursiveChildren()
{
- return GetRecursiveChildren(i => true);
- }
-
- /// <summary>
- /// Gets the recursive children.
- /// </summary>
- /// <param name="filter">The filter.</param>
- /// <returns>IEnumerable{BaseItem}.</returns>
- public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter)
- {
var list = new List<BaseItem>();
- AddChildrenToList(list, true, filter);
+ AddChildrenToList(list, true, null);
return list;
}
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index ce188554c..86099fdc0 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -18,11 +18,17 @@ namespace MediaBrowser.Controller.Entities
switch (ViewType)
{
case CollectionType.Games:
- return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren)).OfType<GameSystem>();
+ return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren))
+ .OfType<GameSystem>();
case CollectionType.BoxSets:
- return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren)).OfType<BoxSet>();
+ return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren))
+ .OfType<BoxSet>();
case CollectionType.TvShows:
- return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren)).OfType<Series>();
+ return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren))
+ .OfType<Series>();
+ case CollectionType.Trailers:
+ return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren))
+ .OfType<Trailer>();
default:
return mediaFolders.SelectMany(i => i.GetChildren(user, includeLinkedChildren));
}
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 4f008571c..33c6f980c 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -217,6 +217,7 @@ namespace MediaBrowser.Model.ApiClient
/// Gets the additional parts.
/// </summary>
/// <param name="itemId">The item identifier.</param>
+ /// <param name="userId">The user identifier.</param>
/// <returns>Task{BaseItemDto[]}.</returns>
Task<ItemsResult> GetAdditionalParts(string itemId, string userId);
@@ -242,6 +243,12 @@ namespace MediaBrowser.Model.ApiClient
Task<SessionInfoDto[]> GetClientSessionsAsync(SessionQuery query);
/// <summary>
+ /// Gets the client session asynchronous.
+ /// </summary>
+ /// <returns>Task{SessionInfoDto}.</returns>
+ Task<SessionInfoDto> GetCurrentSessionAsync();
+
+ /// <summary>
/// Gets the item counts async.
/// </summary>
/// <param name="query">The query.</param>
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 24a41863e..0834452fb 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -93,8 +93,6 @@ namespace MediaBrowser.Model.Configuration
BlockUnratedItems = new UnratedItem[] { };
ExcludeFoldersFromGrouping = new string[] { };
-
- DisplayCollectionsView = true;
}
}
}
diff --git a/MediaBrowser.Model/Dto/StudioDto.cs b/MediaBrowser.Model/Dto/StudioDto.cs
index 4f21784fd..a0027cc4e 100644
--- a/MediaBrowser.Model/Dto/StudioDto.cs
+++ b/MediaBrowser.Model/Dto/StudioDto.cs
@@ -1,5 +1,4 @@
-using System;
-using System.ComponentModel;
+using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.Serialization;
@@ -18,6 +17,12 @@ namespace MediaBrowser.Model.Dto
public string Name { get; set; }
/// <summary>
+ /// Gets or sets the identifier.
+ /// </summary>
+ /// <value>The identifier.</value>
+ public string Id { get; set; }
+
+ /// <summary>
/// Gets or sets the primary image tag.
/// </summary>
/// <value>The primary image tag.</value>
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index 7f63dac33..73216ca33 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -328,7 +328,8 @@ namespace MediaBrowser.Server.Implementations.Dto
if (!string.IsNullOrEmpty(item.Album))
{
var parentAlbum = _libraryManager.RootFolder
- .GetRecursiveChildren(i => i is MusicAlbum)
+ .GetRecursiveChildren()
+ .Where(i => i is MusicAlbum)
.FirstOrDefault(i => string.Equals(i.Name, item.Album, StringComparison.OrdinalIgnoreCase));
if (parentAlbum != null)
@@ -539,6 +540,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (dictionary.TryGetValue(studio, out entity))
{
+ studioDto.Id = entity.Id.ToString("N");
studioDto.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary);
}
@@ -1248,7 +1250,8 @@ namespace MediaBrowser.Server.Implementations.Dto
}
else
{
- children = folder.GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual);
+ children = folder.GetRecursiveChildren(user)
+ .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual);
}
// Loop through each recursive child
diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
index 4c65fad68..6faa72b81 100644
--- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
+++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
@@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
var user = _userManager.GetUserById(new Guid(query.UserId));
- inputItems = user.RootFolder.GetRecursiveChildren(user, null);
+ inputItems = user.RootFolder.GetRecursiveChildren(user, true);
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
index 24e4f0ef4..dd2978b17 100644
--- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
@@ -15,6 +15,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Server.Implementations.Library
{
@@ -84,7 +85,7 @@ namespace MediaBrowser.Server.Implementations.Library
if (user.Configuration.DisplayCollectionsView ||
recursiveChildren.OfType<BoxSet>().Any())
{
- list.Add(await GetUserView(CollectionType.BoxSets, user, "zzz_" + CollectionType.BoxSets, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.BoxSets, user, CollectionType.BoxSets, cancellationToken).ConfigureAwait(false));
}
if (query.IncludeExternalContent)
@@ -114,7 +115,7 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
- return list.OrderBy(i => i.SortName);
+ return _libraryManager.Sort(list, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).Cast<Folder>();
}
private Task<UserView> GetUserView(string type, User user, string sortName, CancellationToken cancellationToken)