aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2017-04-20 23:49:50 -0400
committerGitHub <noreply@github.com>2017-04-20 23:49:50 -0400
commitf525f5a89e68248a81ab7cfdfa044fbe45e51863 (patch)
treef029e380a0867d6e8db7895e63d9a69e0cfd426f /MediaBrowser.Api
parent5dca8cb077fb544628f62939bbda292d8c91b637 (diff)
parentb9fe720e736abacc57ffb846e4ce6644bc110f61 (diff)
Merge pull request #2591 from MediaBrowser/beta
Beta
Diffstat (limited to 'MediaBrowser.Api')
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs32
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj1
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs2
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs12
-rw-r--r--MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs1
-rw-r--r--MediaBrowser.Api/Playback/Hls/VideoHlsService.cs48
-rw-r--r--MediaBrowser.Api/Playback/MediaInfoService.cs2
-rw-r--r--MediaBrowser.Api/Playback/StreamRequest.cs1
-rw-r--r--MediaBrowser.Api/Playback/StreamState.cs12
-rw-r--r--MediaBrowser.Api/SuggestionsService.cs94
-rw-r--r--MediaBrowser.Api/TvShowsService.cs24
-rw-r--r--MediaBrowser.Api/UserLibrary/PlaystateService.cs10
-rw-r--r--MediaBrowser.Api/UserLibrary/UserViewsService.cs39
13 files changed, 155 insertions, 123 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index 37ab123667..a59ab33a97 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -16,6 +16,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.IO;
@@ -425,18 +426,6 @@ namespace MediaBrowser.Api
{
job.ChangeKillTimerIfStarted();
}
-
- if (!string.IsNullOrWhiteSpace(job.LiveStreamId))
- {
- try
- {
- await _mediaSourceManager.PingLiveStream(job.LiveStreamId, CancellationToken.None).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error closing live stream", ex);
- }
- }
}
/// <summary>
@@ -829,23 +818,4 @@ namespace MediaBrowser.Api
}
}
}
-
- /// <summary>
- /// Enum TranscodingJobType
- /// </summary>
- public enum TranscodingJobType
- {
- /// <summary>
- /// The progressive
- /// </summary>
- Progressive,
- /// <summary>
- /// The HLS
- /// </summary>
- Hls,
- /// <summary>
- /// The dash
- /// </summary>
- Dash
- }
}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index c2c8d1102b..0785b904ae 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -134,6 +134,7 @@
<Compile Include="SearchService.cs" />
<Compile Include="Session\SessionsService.cs" />
<Compile Include="SimilarItemsHelper.cs" />
+ <Compile Include="SuggestionsService.cs" />
<Compile Include="System\ActivityLogService.cs" />
<Compile Include="System\ActivityLogWebSocketListener.cs" />
<Compile Include="System\SystemService.cs" />
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 480508e6ff..699c4bbb2f 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -169,7 +169,7 @@ namespace MediaBrowser.Api.Playback
{
OpenToken = state.MediaSource.OpenToken
- }, false, cancellationTokenSource.Token).ConfigureAwait(false);
+ }, cancellationTokenSource.Token).ConfigureAwait(false);
EncodingHelper.AttachMediaSourceInfo(state, liveStreamResponse.MediaSource, state.RequestedUrl);
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index bd4442a590..038d762456 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -826,6 +826,11 @@ namespace MediaBrowser.Api.Playback.Hls
args += " -ab " + bitrate.Value.ToString(UsCulture);
}
+ if (state.OutputAudioSampleRate.HasValue)
+ {
+ args += " -ar " + state.OutputAudioSampleRate.Value.ToString(UsCulture);
+ }
+
args += " " + EncodingHelper.GetAudioFilterParam(state, ApiEntryPoint.Instance.GetEncodingOptions(), true);
return args;
@@ -890,6 +895,11 @@ namespace MediaBrowser.Api.Playback.Hls
args += " -copyts";
}
+ if (!string.IsNullOrEmpty(state.OutputVideoSync))
+ {
+ args += " -vsync " + state.OutputVideoSync;
+ }
+
return args;
}
@@ -932,7 +942,7 @@ namespace MediaBrowser.Api.Playback.Hls
}
var videoCodec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions());
- var breakOnNonKeyFrames = state.Request.BreakOnNonKeyFrames && string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase);
+ var breakOnNonKeyFrames = state.EnableBreakOnNonKeyFrames(videoCodec);
var breakOnNonKeyFramesArg = breakOnNonKeyFrames ? " -break_non_keyframes 1" : "";
diff --git a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
index 03291670b5..ae049a83a4 100644
--- a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
+++ b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services;
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index 8b828ddfe8..a813d7a872 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -6,10 +6,7 @@ using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
using System;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Services;
@@ -60,6 +57,11 @@ namespace MediaBrowser.Api.Playback.Hls
args += " -ab " + bitrate.Value.ToString(UsCulture);
}
+ if (state.OutputAudioSampleRate.HasValue)
+ {
+ args += " -ar " + state.OutputAudioSampleRate.Value.ToString(UsCulture);
+ }
+
args += " " + EncodingHelper.GetAudioFilterParam(state, ApiEntryPoint.Instance.GetEncodingOptions(), true);
return args;
@@ -85,36 +87,42 @@ namespace MediaBrowser.Api.Playback.Hls
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{
// if h264_mp4toannexb is ever added, do not use it for live tv
- if (state.VideoStream != null && EncodingHelper.IsH264(state.VideoStream) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
+ if (state.VideoStream != null && EncodingHelper.IsH264(state.VideoStream) &&
+ !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
{
args += " -bsf:v h264_mp4toannexb";
}
- args += " -flags -global_header";
- return args;
}
+ else
+ {
+ var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
+ state.SegmentLength.ToString(UsCulture));
- var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
- state.SegmentLength.ToString(UsCulture));
+ var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
- var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
+ var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
+ args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultH264Preset()) + keyFrameArg;
- var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
- args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultH264Preset()) + keyFrameArg;
+ // Add resolution params, if specified
+ if (!hasGraphicalSubs)
+ {
+ args += EncodingHelper.GetOutputSizeParam(state, codec);
+ }
- // Add resolution params, if specified
- if (!hasGraphicalSubs)
- {
- args += EncodingHelper.GetOutputSizeParam(state, codec);
+ // This is for internal graphical subs
+ if (hasGraphicalSubs)
+ {
+ args += EncodingHelper.GetGraphicalSubtitleParam(state, codec);
+ }
}
- // This is for internal graphical subs
- if (hasGraphicalSubs)
+ args += " -flags -global_header";
+
+ if (!string.IsNullOrEmpty(state.OutputVideoSync))
{
- args += EncodingHelper.GetGraphicalSubtitleParam(state, codec);
+ args += " -vsync " + state.OutputVideoSync;
}
- args += " -flags -global_header";
-
return args;
}
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index 0ee0dab300..fcd18bfe47 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -109,7 +109,7 @@ namespace MediaBrowser.Api.Playback
{
var authInfo = _authContext.GetAuthorizationInfo(Request);
- var result = await _mediaSourceManager.OpenLiveStream(request, true, CancellationToken.None).ConfigureAwait(false);
+ var result = await _mediaSourceManager.OpenLiveStream(request, CancellationToken.None).ConfigureAwait(false);
var profile = request.DeviceProfile;
if (profile == null)
diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs
index d02b4bae63..176b68f375 100644
--- a/MediaBrowser.Api/Playback/StreamRequest.cs
+++ b/MediaBrowser.Api/Playback/StreamRequest.cs
@@ -42,7 +42,6 @@ namespace MediaBrowser.Api.Playback
public int? SegmentLength { get; set; }
public int? MinSegments { get; set; }
- public bool BreakOnNonKeyFrames { get; set; }
}
public class VideoStreamRequest : StreamRequest
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index 2f5f6227a9..7f146466d4 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -104,14 +104,6 @@ namespace MediaBrowser.Api.Playback
}
}
- public bool IsSegmentedLiveStream
- {
- get
- {
- return TranscodingType != TranscodingJobType.Progressive && !RunTimeTicks.HasValue;
- }
- }
-
public int HlsListSize
{
get
@@ -121,14 +113,12 @@ namespace MediaBrowser.Api.Playback
}
public string UserAgent { get; set; }
- public TranscodingJobType TranscodingType { get; set; }
public StreamState(IMediaSourceManager mediaSourceManager, ILogger logger, TranscodingJobType transcodingType)
- : base(logger)
+ : base(logger, transcodingType)
{
_mediaSourceManager = mediaSourceManager;
_logger = logger;
- TranscodingType = transcodingType;
}
public string MimeType { get; set; }
diff --git a/MediaBrowser.Api/SuggestionsService.cs b/MediaBrowser.Api/SuggestionsService.cs
new file mode 100644
index 0000000000..99411ffdcb
--- /dev/null
+++ b/MediaBrowser.Api/SuggestionsService.cs
@@ -0,0 +1,94 @@
+using MediaBrowser.Controller.Dto;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Services;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Library;
+
+namespace MediaBrowser.Api
+{
+ [Route("/Users/{UserId}/Suggestions", "GET", Summary = "Gets items based on a query.")]
+ public class GetSuggestedItems : IReturn<QueryResult<BaseItem>>
+ {
+ public string MediaType { get; set; }
+ public string Type { get; set; }
+ public string UserId { get; set; }
+ public bool EnableTotalRecordCount { get; set; }
+ public int? StartIndex { get; set; }
+ public int? Limit { get; set; }
+
+ public string[] GetMediaTypes()
+ {
+ return (MediaType ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+
+ public string[] GetIncludeItemTypes()
+ {
+ return (Type ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+ }
+
+ public class SuggestionsService : BaseApiService
+ {
+ private readonly IDtoService _dtoService;
+ private readonly IAuthorizationContext _authContext;
+ private readonly IUserManager _userManager;
+ private readonly ILibraryManager _libraryManager;
+
+ public SuggestionsService(IDtoService dtoService, IAuthorizationContext authContext, IUserManager userManager, ILibraryManager libraryManager)
+ {
+ _dtoService = dtoService;
+ _authContext = authContext;
+ _userManager = userManager;
+ _libraryManager = libraryManager;
+ }
+
+ public async Task<object> Get(GetSuggestedItems request)
+ {
+ var result = await GetResultItems(request).ConfigureAwait(false);
+
+ return ToOptimizedResult(result);
+ }
+
+ private async Task<QueryResult<BaseItemDto>> GetResultItems(GetSuggestedItems request)
+ {
+ var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+
+ var dtoOptions = GetDtoOptions(_authContext, request);
+ var result = GetItems(request, user, dtoOptions);
+
+ var dtoList = await _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user).ConfigureAwait(false);
+
+ if (dtoList == null)
+ {
+ throw new InvalidOperationException("GetBaseItemDtos returned null");
+ }
+
+ return new QueryResult<BaseItemDto>
+ {
+ TotalRecordCount = result.TotalRecordCount,
+ Items = dtoList.ToArray()
+ };
+ }
+
+ private QueryResult<BaseItem> GetItems(GetSuggestedItems request, User user, DtoOptions dtoOptions)
+ {
+ return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
+ {
+ SortBy = new string[] { ItemSortBy.Random },
+ MediaTypes = request.GetMediaTypes(),
+ IncludeItemTypes = request.GetIncludeItemTypes(),
+ IsVirtualItem = false,
+ StartIndex = request.StartIndex,
+ Limit = request.Limit,
+ DtoOptions = dtoOptions,
+ EnableTotalRecordCount = request.EnableTotalRecordCount,
+ Recursive = true
+ });
+ }
+ }
+}
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index 43fe74d5fb..126f1c7539 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -199,7 +199,6 @@ namespace MediaBrowser.Api
[ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? EnableUserData { get; set; }
-
}
[Route("/Shows/{Id}/Seasons", "GET", Summary = "Gets seasons for a tv series")]
@@ -245,7 +244,6 @@ namespace MediaBrowser.Api
[ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? EnableUserData { get; set; }
-
}
/// <summary>
@@ -427,11 +425,11 @@ namespace MediaBrowser.Api
{
var user = _userManager.GetUserById(request.UserId);
- var series = _libraryManager.GetItemById(request.Id) as Series;
+ var series = GetSeries(request.Id, user);
if (series == null)
{
- throw new ResourceNotFoundException("No series exists with Id " + request.Id);
+ throw new ResourceNotFoundException("Series not found");
}
var seasons = (await series.GetItems(new InternalItemsQuery(user)
@@ -455,6 +453,16 @@ namespace MediaBrowser.Api
};
}
+ private Series GetSeries(string seriesId, User user)
+ {
+ if (!string.IsNullOrWhiteSpace(seriesId))
+ {
+ return _libraryManager.GetItemById(seriesId) as Series;
+ }
+
+ return null;
+ }
+
public async Task<object> Get(GetEpisodes request)
{
var user = _userManager.GetUserById(request.UserId);
@@ -474,11 +482,11 @@ namespace MediaBrowser.Api
}
else if (request.Season.HasValue)
{
- var series = _libraryManager.GetItemById(request.Id) as Series;
+ var series = GetSeries(request.Id, user);
if (series == null)
{
- throw new ResourceNotFoundException("No series exists with Id " + request.Id);
+ throw new ResourceNotFoundException("Series not found");
}
var season = series.GetSeasons(user).FirstOrDefault(i => i.IndexNumber == request.Season.Value);
@@ -494,11 +502,11 @@ namespace MediaBrowser.Api
}
else
{
- var series = _libraryManager.GetItemById(request.Id) as Series;
+ var series = GetSeries(request.Id, user);
if (series == null)
{
- throw new ResourceNotFoundException("No series exists with Id " + request.Id);
+ throw new ResourceNotFoundException("Series not found");
}
episodes = series.GetEpisodes(user);
diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs
index 504dd29a73..c4cc90955e 100644
--- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs
+++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs
@@ -109,13 +109,6 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "CanSeek", Description = "Indicates if the client can seek", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
public bool CanSeek { get; set; }
- /// <summary>
- /// Gets or sets the id.
- /// </summary>
- /// <value>The id.</value>
- [ApiMember(Name = "QueueableMediaTypes", Description = "A list of media types that can be queued from this item, comma delimited. Audio,Video,Book,Game", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]
- public string QueueableMediaTypes { get; set; }
-
[ApiMember(Name = "AudioStreamIndex", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "POST")]
public int? AudioStreamIndex { get; set; }
@@ -292,13 +285,10 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="request">The request.</param>
public void Post(OnPlaybackStart request)
{
- var queueableMediaTypes = request.QueueableMediaTypes ?? string.Empty;
-
Post(new ReportPlaybackStart
{
CanSeek = request.CanSeek,
ItemId = request.Id,
- QueueableMediaTypes = queueableMediaTypes.Split(',').ToList(),
MediaSourceId = request.MediaSourceId,
AudioStreamIndex = request.AudioStreamIndex,
SubtitleStreamIndex = request.SubtitleStreamIndex,
diff --git a/MediaBrowser.Api/UserLibrary/UserViewsService.cs b/MediaBrowser.Api/UserLibrary/UserViewsService.cs
index 715745a7dc..89953c2bd8 100644
--- a/MediaBrowser.Api/UserLibrary/UserViewsService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserViewsService.cs
@@ -31,17 +31,6 @@ namespace MediaBrowser.Api.UserLibrary
public string PresetViews { get; set; }
}
- [Route("/Users/{UserId}/SpecialViewOptions", "GET")]
- public class GetSpecialViewOptions : IReturn<List<SpecialViewOption>>
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
- }
-
[Route("/Users/{UserId}/GroupingOptions", "GET")]
public class GetGroupingOptions : IReturn<List<SpecialViewOption>>
{
@@ -114,29 +103,6 @@ namespace MediaBrowser.Api.UserLibrary
return ToOptimizedResult(result);
}
- public async Task<object> Get(GetSpecialViewOptions request)
- {
- var user = _userManager.GetUserById(request.UserId);
-
- var views = user.RootFolder
- .GetChildren(user, true)
- .OfType<ICollectionFolder>()
- .Where(IsEligibleForSpecialView)
- .ToList();
-
- var list = views
- .Select(i => new SpecialViewOption
- {
- Name = i.Name,
- Id = i.Id.ToString("N")
-
- })
- .OrderBy(i => i.Name)
- .ToList();
-
- return ToOptimizedResult(list);
- }
-
public async Task<object> Get(GetGroupingOptions request)
{
var user = _userManager.GetUserById(request.UserId);
@@ -159,11 +125,6 @@ namespace MediaBrowser.Api.UserLibrary
return ToOptimizedResult(list);
}
-
- private bool IsEligibleForSpecialView(ICollectionFolder view)
- {
- return UserView.IsEligibleForEnhancedView(view.CollectionType);
- }
}
class SpecialViewOption