aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api')
-rw-r--r--MediaBrowser.Api/Images/ImageRequest.cs7
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs55
-rw-r--r--MediaBrowser.Api/Playback/Hls/MpegDashService.cs7
-rw-r--r--MediaBrowser.Api/System/SystemService.cs3
-rw-r--r--MediaBrowser.Api/UserService.cs69
5 files changed, 103 insertions, 38 deletions
diff --git a/MediaBrowser.Api/Images/ImageRequest.cs b/MediaBrowser.Api/Images/ImageRequest.cs
index 718d5f402..cdd348bb5 100644
--- a/MediaBrowser.Api/Images/ImageRequest.cs
+++ b/MediaBrowser.Api/Images/ImageRequest.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Model.Drawing;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Entities;
using ServiceStack;
namespace MediaBrowser.Api.Images
@@ -54,7 +53,7 @@ namespace MediaBrowser.Api.Images
public bool EnableImageEnhancers { get; set; }
[ApiMember(Name = "Format", Description = "Determines the output foramt of the image - original,gif,jpg,png", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
- public ImageOutputFormat Format { get; set; }
+ public string Format { get; set; }
[ApiMember(Name = "AddPlayedIndicator", Description = "Optional. Add a played indicator", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool AddPlayedIndicator { get; set; }
@@ -71,8 +70,6 @@ namespace MediaBrowser.Api.Images
public ImageRequest()
{
EnableImageEnhancers = true;
-
- Format = ImageOutputFormat.Original;
}
}
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index ca54249b3..7fc43e164 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -542,7 +542,8 @@ namespace MediaBrowser.Api.Images
}).ToList() : new List<IImageEnhancer>();
- var contentType = GetMimeType(request.Format, imageInfo.Path);
+ var format = GetOutputFormat(request, imageInfo, supportedImageEnhancers);
+ var contentType = GetMimeType(format, imageInfo.Path);
var cacheGuid = new Guid(_imageProcessor.GetImageCacheTag(item, imageInfo, supportedImageEnhancers));
@@ -562,6 +563,7 @@ namespace MediaBrowser.Api.Images
return GetImageResult(item,
request,
imageInfo,
+ format,
supportedImageEnhancers,
contentType,
cacheDuration,
@@ -573,6 +575,7 @@ namespace MediaBrowser.Api.Images
private async Task<object> GetImageResult(IHasImages item,
ImageRequest request,
ItemImageInfo image,
+ ImageOutputFormat format,
List<IImageEnhancer> enhancers,
string contentType,
TimeSpan? cacheDuration,
@@ -598,11 +601,11 @@ namespace MediaBrowser.Api.Images
MaxWidth = request.MaxWidth,
Quality = request.Quality,
Width = request.Width,
- OutputFormat = request.Format,
AddPlayedIndicator = request.AddPlayedIndicator,
PercentPlayed = request.PercentPlayed ?? 0,
UnplayedCount = request.UnplayedCount,
- BackgroundColor = request.BackgroundColor
+ BackgroundColor = request.BackgroundColor,
+ OutputFormat = format
};
var file = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);
@@ -617,6 +620,52 @@ namespace MediaBrowser.Api.Images
});
}
+ private ImageOutputFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, List<IImageEnhancer> enhancers)
+ {
+ if (!string.IsNullOrWhiteSpace(request.Format))
+ {
+ ImageOutputFormat format;
+ if (Enum.TryParse(request.Format, true, out format))
+ {
+ return format;
+ }
+ }
+
+ var serverFormats = _imageProcessor.GetSupportedImageOutputFormats();
+
+ var clientFormats = GetClientSupportedFormats();
+
+ if (serverFormats.Contains(ImageOutputFormat.Webp) &&
+ clientFormats.Contains(ImageOutputFormat.Webp))
+ {
+ return ImageOutputFormat.Webp;
+ }
+
+ if (enhancers.Count > 0)
+ {
+ return ImageOutputFormat.Png;
+ }
+
+ if (string.Equals(Path.GetExtension(image.Path), ".jpg", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(Path.GetExtension(image.Path), ".jpeg", StringComparison.OrdinalIgnoreCase))
+ {
+ return ImageOutputFormat.Jpg;
+ }
+
+ // We can't predict if there will be transparency or not, so play it safe
+ return ImageOutputFormat.Png;
+ }
+
+ private ImageOutputFormat[] GetClientSupportedFormats()
+ {
+ if (Request.AcceptTypes.Contains("image/webp", StringComparer.OrdinalIgnoreCase))
+ {
+ return new[] { ImageOutputFormat.Webp, ImageOutputFormat.Jpg, ImageOutputFormat.Png };
+ }
+
+ return new[] { ImageOutputFormat.Jpg, ImageOutputFormat.Png };
+ }
+
private string GetMimeType(ImageOutputFormat format, string path)
{
if (format == ImageOutputFormat.Bmp)
diff --git a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs
index 7135d9b84..3c1f07c5f 100644
--- a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs
+++ b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs
@@ -598,6 +598,8 @@ namespace MediaBrowser.Api.Playback.Hls
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;
+ args += " -r 24 -g 24";
+
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
@@ -615,6 +617,9 @@ namespace MediaBrowser.Api.Playback.Hls
protected override string GetCommandLineArguments(string outputPath, string transcodingJobId, StreamState state, bool isEncoding)
{
+ // test url http://192.168.1.2:8096/mediabrowser/videos/233e8905d559a8f230db9bffd2ac9d6d/master.mpd?mediasourceid=233e8905d559a8f230db9bffd2ac9d6d&videocodec=h264&audiocodec=aac&maxwidth=1280&videobitrate=500000&audiobitrate=128000&profile=baseline&level=3
+ // Good info on i-frames http://blog.streamroot.io/encode-multi-bitrate-videos-mpeg-dash-mse-based-media-players/
+
var threads = GetNumberOfThreads(state, false);
var inputModifier = GetInputModifier(state);
@@ -624,7 +629,7 @@ namespace MediaBrowser.Api.Playback.Hls
var segmentFilename = Path.GetFileNameWithoutExtension(outputPath) + "%03d" + GetSegmentFileExtension(state);
- var args = string.Format("{0} -i {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header {5} -f ssegment -segment_time {6} -segment_format_options movflags=+faststart -segment_list_size {8} -segment_list \"{9}\" {10}",
+ var args = string.Format("{0} -i {1} -map_metadata -1 -threads {2} {3} {4} -copyts {5} -f ssegment -segment_time {6} -segment_list_size {8} -segment_list \"{9}\" {10}",
inputModifier,
GetInputArgument(transcodingJobId, state),
threads,
diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs
index aa01e1b65..3b8eb7b6f 100644
--- a/MediaBrowser.Api/System/SystemService.cs
+++ b/MediaBrowser.Api/System/SystemService.cs
@@ -44,9 +44,10 @@ namespace MediaBrowser.Api.System
/// This is currently not authenticated because the uninstaller needs to be able to shutdown the server.
/// </summary>
[Route("/System/Shutdown", "POST", Summary = "Shuts down the application")]
- [Authenticated(AllowLocal = true)]
public class ShutdownApplication
{
+ // TODO: This is not currently authenticated due to uninstaller
+ // Improve later
}
[Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")]
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 19bfb821f..9bd85426d 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -12,6 +12,7 @@ using ServiceStack;
using ServiceStack.Text.Controller;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -175,6 +176,20 @@ namespace MediaBrowser.Api
public string Name { get; set; }
}
+ [Route("/Users/ForgotPassword", "POST", Summary = "Initiates the forgot password process for a local user")]
+ public class ForgotPassword : IReturn<ForgotPasswordResult>
+ {
+ [ApiMember(Name = "EnteredUsername", IsRequired = false, DataType = "string", ParameterType = "body", Verb = "POST")]
+ public string EnteredUsername { get; set; }
+ }
+
+ [Route("/Users/ForgotPassword/Pin", "POST", Summary = "Redeems a forgot password pin")]
+ public class ForgotPasswordPin : IReturn<PinRedeemResult>
+ {
+ [ApiMember(Name = "Pin", IsRequired = false, DataType = "string", ParameterType = "body", Verb = "POST")]
+ public string Pin { get; set; }
+ }
+
/// <summary>
/// Class UsersService
/// </summary>
@@ -217,35 +232,16 @@ namespace MediaBrowser.Api
});
}
- var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);
- var isDashboard = string.Equals(authInfo.Client, "Dashboard", StringComparison.OrdinalIgnoreCase);
-
- if (Request.IsLocal && isDashboard)
+ // TODO: Uncomment once clients can handle an empty user list (and below)
+ //if (Request.IsLocal || IsInLocalNetwork(Request.RemoteIp))
{
- var users = _userManager.Users
- .Where(i => !i.Configuration.IsDisabled && !(i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest))
- .ToList();
-
- return ToOptimizedResult(users);
+ return Get(new GetUsers
+ {
+ IsHidden = false,
+ IsDisabled = false
+ });
}
- // TODO: Uncomment this once all clients can handle an empty user list.
- return Get(new GetUsers
- {
- IsHidden = false,
- IsDisabled = false
- });
-
- //// TODO: Add or is authenticated
- //if (Request.IsLocal || IsInLocalNetwork(Request.RemoteIp))
- //{
- // return Get(new GetUsers
- // {
- // IsHidden = false,
- // IsDisabled = false
- // });
- //}
-
//// Return empty when external
//return ToOptimizedResult(new List<UserDto>());
}
@@ -379,7 +375,7 @@ namespace MediaBrowser.Api
RemoteEndPoint = Request.RemoteIp,
Username = request.Username
- }, Request.IsLocal).ConfigureAwait(false);
+ }).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@@ -419,7 +415,7 @@ namespace MediaBrowser.Api
await _userManager.ChangePassword(user, request.NewPassword).ConfigureAwait(false);
}
}
-
+
/// <summary>
/// Posts the specified request.
/// </summary>
@@ -510,5 +506,22 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
+
+ /// <summary>
+ /// Posts the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>System.Object.</returns>
+ public object Post(ForgotPassword request)
+ {
+ var isLocal = Request.IsLocal || _networkManager.IsInLocalNetwork(Request.RemoteIp);
+
+ return _userManager.StartForgotPasswordProcess(request.EnteredUsername, isLocal);
+ }
+
+ public object Post(ForgotPasswordPin request)
+ {
+ return _userManager.RedeemPasswordResetPin(request.Pin);
+ }
}
}