diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj
index dc410c321e..aa7dc5a153 100644
--- a/Emby.Drawing/Emby.Drawing.csproj
+++ b/Emby.Drawing/Emby.Drawing.csproj
@@ -80,7 +80,6 @@
-
diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
index cb60d1123e..3dbe7239dd 100644
--- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
+++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
@@ -111,7 +111,6 @@ namespace Emby.Drawing.ImageMagick
wand.CurrentImage.TrimImage(10);
wand.SaveImage(outputPath);
}
- SaveDelay();
}
public ImageSize GetImageSize(string path)
@@ -189,7 +188,6 @@ namespace Emby.Drawing.ImageMagick
}
}
}
- SaveDelay();
}
private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
@@ -284,25 +282,16 @@ namespace Emby.Drawing.ImageMagick
if (ratio >= 1.4)
{
- new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height, options.Text);
+ new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
}
else if (ratio >= .9)
{
- new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height, options.Text);
+ new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
}
else
{
- new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height, options.Text);
+ new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
}
-
- SaveDelay();
- }
-
- private void SaveDelay()
- {
- // For some reason the images are not always getting released right away
- //var task = Task.Delay(300);
- //Task.WaitAll(task);
}
public string Name
diff --git a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs b/Emby.Drawing/ImageMagick/StripCollageBuilder.cs
index c9e291a5e6..7bc144c11d 100644
--- a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs
+++ b/Emby.Drawing/ImageMagick/StripCollageBuilder.cs
@@ -9,140 +9,35 @@ namespace Emby.Drawing.ImageMagick
public class StripCollageBuilder
{
private readonly IApplicationPaths _appPaths;
- private readonly IFileSystem _fileSystem;
+ private readonly IFileSystem _fileSystem;
- public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem)
+ public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem)
{
_appPaths = appPaths;
- _fileSystem = fileSystem;
+ _fileSystem = fileSystem;
}
- public void BuildPosterCollage(List paths, string outputPath, int width, int height, string text)
+ public void BuildPosterCollage(List paths, string outputPath, int width, int height)
{
- if (!string.IsNullOrWhiteSpace(text))
+ using (var wand = BuildPosterCollageWand(paths, width, height))
{
- using (var wand = BuildPosterCollageWandWithText(paths, text, width, height))
- {
- wand.SaveImage(outputPath);
- }
- }
- else
- {
- using (var wand = BuildPosterCollageWand(paths, width, height))
- {
- wand.SaveImage(outputPath);
- }
+ wand.SaveImage(outputPath);
}
}
- public void BuildSquareCollage(List paths, string outputPath, int width, int height, string text)
+ public void BuildSquareCollage(List paths, string outputPath, int width, int height)
{
- if (!string.IsNullOrWhiteSpace(text))
+ using (var wand = BuildSquareCollageWand(paths, width, height))
{
- using (var wand = BuildSquareCollageWandWithText(paths, text, width, height))
- {
- wand.SaveImage(outputPath);
- }
- }
- else
- {
- using (var wand = BuildSquareCollageWand(paths, width, height))
- {
- wand.SaveImage(outputPath);
- }
+ wand.SaveImage(outputPath);
}
}
- public void BuildThumbCollage(List paths, string outputPath, int width, int height, string text)
+ public void BuildThumbCollage(List paths, string outputPath, int width, int height)
{
- if (!string.IsNullOrWhiteSpace(text))
+ using (var wand = BuildThumbCollageWand(paths, width, height))
{
- using (var wand = BuildThumbCollageWandWithText(paths, text, width, height))
- {
- wand.SaveImage(outputPath);
- }
- }
- else
- {
- using (var wand = BuildThumbCollageWand(paths, width, height))
- {
- wand.SaveImage(outputPath);
- }
- }
- }
-
- private MagickWand BuildThumbCollageWandWithText(List paths, string text, int width, int height)
- {
- var inputPaths = ImageHelpers.ProjectPaths(paths, 8);
- using (var wandImages = new MagickWand(inputPaths.ToArray()))
- {
- var wand = new MagickWand(width, height);
- wand.OpenImage("gradient:#111111-#111111");
- using (var draw = new DrawingWand())
- {
- using (var fcolor = new PixelWand(ColorName.White))
- {
- draw.FillColor = fcolor;
- draw.Font = MontserratLightFont;
- draw.FontSize = 60;
- draw.FontWeight = FontWeightType.LightStyle;
- draw.TextAntialias = true;
- }
-
- var fontMetrics = wand.QueryFontMetrics(draw, text);
- var textContainerY = Convert.ToInt32(height * .165);
- wand.CurrentImage.AnnotateImage(draw, (width - fontMetrics.TextWidth) / 2, textContainerY, 0.0, text);
-
- var iSlice = Convert.ToInt32(width * .1166666667);
- int iTrans = Convert.ToInt32(height * 0.2);
- int iHeight = Convert.ToInt32(height * 0.46296296296296296296296296296296);
- var horizontalImagePadding = Convert.ToInt32(width * 0.0125);
-
- foreach (var element in wandImages.ImageList)
- {
- int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
- element.Gravity = GravityType.CenterGravity;
- element.BackgroundColor = new PixelWand("none", 1);
- element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
- int ix = (int)Math.Abs((iWidth - iSlice) / 2);
- element.CropImage(iSlice, iHeight, ix, 0);
-
- element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
- }
-
- wandImages.SetFirstIterator();
- using (var wandList = wandImages.AppendImages())
- {
- wandList.CurrentImage.TrimImage(1);
- using (var mwr = wandList.CloneMagickWand())
- {
- using (var blackPixelWand = new PixelWand(ColorName.Black))
- {
- using (var greyPixelWand = new PixelWand(ColorName.Grey70))
- {
- mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
- mwr.CurrentImage.FlipImage();
-
- mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
- mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
-
- using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
- {
- mwg.OpenImage("gradient:black-none");
- var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
- mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.DstInCompositeOp, 0, verticalSpacing);
-
- wandList.AddImage(mwr);
- int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
- wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * 0.26851851851851851851851851851852));
- }
- }
- }
- }
- }
- }
-
- return wand;
+ wand.SaveImage(outputPath);
}
}
@@ -211,81 +106,6 @@ namespace Emby.Drawing.ImageMagick
}
}
- private MagickWand BuildPosterCollageWandWithText(List paths, string label, int width, int height)
- {
- var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
- using (var wandImages = new MagickWand(inputPaths.ToArray()))
- {
- var wand = new MagickWand(width, height);
- wand.OpenImage("gradient:#111111-#111111");
- using (var draw = new DrawingWand())
- {
- using (var fcolor = new PixelWand(ColorName.White))
- {
- draw.FillColor = fcolor;
- draw.Font = MontserratLightFont;
- draw.FontSize = 60;
- draw.FontWeight = FontWeightType.LightStyle;
- draw.TextAntialias = true;
- }
-
- var fontMetrics = wand.QueryFontMetrics(draw, label);
- var textContainerY = Convert.ToInt32(height * .165);
- wand.CurrentImage.AnnotateImage(draw, (width - fontMetrics.TextWidth) / 2, textContainerY, 0.0, label);
-
- var iSlice = Convert.ToInt32(width * 0.225);
- int iTrans = Convert.ToInt32(height * 0.2);
- int iHeight = Convert.ToInt32(height * 0.46296296296296296296296296296296);
- var horizontalImagePadding = Convert.ToInt32(width * 0.0275);
-
- foreach (var element in wandImages.ImageList)
- {
- int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
- element.Gravity = GravityType.CenterGravity;
- element.BackgroundColor = new PixelWand("none", 1);
- element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
- int ix = (int)Math.Abs((iWidth - iSlice) / 2);
- element.CropImage(iSlice, iHeight, ix, 0);
-
- element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
- }
-
- wandImages.SetFirstIterator();
- using (var wandList = wandImages.AppendImages())
- {
- wandList.CurrentImage.TrimImage(1);
- using (var mwr = wandList.CloneMagickWand())
- {
- using (var blackPixelWand = new PixelWand(ColorName.Black))
- {
- using (var greyPixelWand = new PixelWand(ColorName.Grey70))
- {
- mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
- mwr.CurrentImage.FlipImage();
-
- mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
- mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
-
- using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
- {
- mwg.OpenImage("gradient:black-none");
- var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
- mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.DstInCompositeOp, 0, verticalSpacing);
-
- wandList.AddImage(mwr);
- int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
- wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * 0.26851851851851851851851851851852));
- }
- }
- }
- }
- }
- }
-
- return wand;
- }
- }
-
private MagickWand BuildThumbCollageWand(List paths, int width, int height)
{
var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
@@ -352,148 +172,29 @@ namespace Emby.Drawing.ImageMagick
}
private MagickWand BuildSquareCollageWand(List paths, int width, int height)
- {
- var inputPaths = ImageHelpers.ProjectPaths(paths, 3);
- using (var wandImages = new MagickWand(inputPaths.ToArray()))
- {
- var wand = new MagickWand(width, height);
- wand.OpenImage("gradient:#111111-#111111");
- using (var draw = new DrawingWand())
- {
- var iSlice = Convert.ToInt32(width * .32);
- int iTrans = Convert.ToInt32(height * .25);
- int iHeight = Convert.ToInt32(height * .68);
- var horizontalImagePadding = Convert.ToInt32(width * 0.02);
-
- foreach (var element in wandImages.ImageList)
- {
- using (var blackPixelWand = new PixelWand(ColorName.Black))
- {
- int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
- element.Gravity = GravityType.CenterGravity;
- element.BackgroundColor = blackPixelWand;
- element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
- int ix = (int)Math.Abs((iWidth - iSlice) / 2);
- element.CropImage(iSlice, iHeight, ix, 0);
-
- element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
- }
- }
-
- wandImages.SetFirstIterator();
- using (var wandList = wandImages.AppendImages())
- {
- wandList.CurrentImage.TrimImage(1);
- using (var mwr = wandList.CloneMagickWand())
- {
- using (var blackPixelWand = new PixelWand(ColorName.Black))
- {
- using (var greyPixelWand = new PixelWand(ColorName.Grey70))
- {
- mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
- mwr.CurrentImage.FlipImage();
-
- mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
- mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
-
- using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
- {
- mwg.OpenImage("gradient:black-none");
- var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
- mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.CopyOpacityCompositeOp, 0, verticalSpacing);
-
- wandList.AddImage(mwr);
- int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
- wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .03));
- }
- }
- }
- }
- }
- }
-
- return wand;
- }
- }
-
- private MagickWand BuildSquareCollageWandWithText(List paths, string label, int width, int height)
{
var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
- using (var wandImages = new MagickWand(inputPaths.ToArray()))
+ var outputWand = new MagickWand(width, height, new PixelWand("none", 1));
+ var imageIndex = 0;
+ var cellWidth = width/2;
+ var cellHeight = height/2;
+ for (var x = 0; x < 2; x++)
{
- var wand = new MagickWand(width, height);
- wand.OpenImage("gradient:#111111-#111111");
- using (var draw = new DrawingWand())
+ for (var y = 0; y < 2; y++)
{
- using (var fcolor = new PixelWand(ColorName.White))
- {
- draw.FillColor = fcolor;
- draw.Font = MontserratLightFont;
- draw.FontSize = 60;
- draw.FontWeight = FontWeightType.LightStyle;
- draw.TextAntialias = true;
- }
-
- var fontMetrics = wand.QueryFontMetrics(draw, label);
- var textContainerY = Convert.ToInt32(height * .165);
- wand.CurrentImage.AnnotateImage(draw, (width - fontMetrics.TextWidth) / 2, textContainerY, 0.0, label);
-
- var iSlice = Convert.ToInt32(width * .225);
- int iTrans = Convert.ToInt32(height * 0.2);
- int iHeight = Convert.ToInt32(height * 0.46296296296296296296296296296296);
- var horizontalImagePadding = Convert.ToInt32(width * 0.02);
-
- foreach (var element in wandImages.ImageList)
- {
- int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
- element.Gravity = GravityType.CenterGravity;
- element.BackgroundColor = new PixelWand("none", 1);
- element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
- int ix = (int)Math.Abs((iWidth - iSlice) / 2);
- element.CropImage(iSlice, iHeight, ix, 0);
-
- element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
- }
-
- wandImages.SetFirstIterator();
- using (var wandList = wandImages.AppendImages())
+ using (var temp = new MagickWand(inputPaths[imageIndex]))
{
- wandList.CurrentImage.TrimImage(1);
- using (var mwr = wandList.CloneMagickWand())
- {
- using (var blackPixelWand = new PixelWand(ColorName.Black))
- {
- using (var greyPixelWand = new PixelWand(ColorName.Grey70))
- {
- mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
- mwr.CurrentImage.FlipImage();
-
- mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
- mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
-
- using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
- {
- mwg.OpenImage("gradient:black-none");
- var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
- mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.DstInCompositeOp, 0, verticalSpacing);
-
- wandList.AddImage(mwr);
- int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
- wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * 0.26851851851851851851851851851852));
- }
- }
- }
- }
+ temp.CurrentImage.ScaleImage(cellWidth, cellHeight);
+ // draw this image into the strip at the next position
+ var xPos = x*cellWidth;
+ var yPos = y*cellHeight;
+ outputWand.CurrentImage.CompositeImage(temp, CompositeOperator.OverCompositeOp, xPos, yPos);
}
+ imageIndex++;
}
-
- return wand;
}
- }
- private string MontserratLightFont
- {
- get { return PlayedIndicatorDrawer.ExtractFont("MontserratLight.otf", _appPaths, _fileSystem); }
+ return outputWand;
}
}
}
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 44d459a01e..44a367be09 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -115,7 +115,7 @@ namespace MediaBrowser.Api
/// System.Object.
protected object ToStaticFileResult(string path)
{
- return ResultFactory.GetStaticFileResult(Request, path);
+ return ResultFactory.GetStaticFileResult(Request, path).Result;
}
protected DtoOptions GetDtoOptions(object request)
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs
index 446415fbb5..2e5c252d63 100644
--- a/MediaBrowser.Api/ConfigurationService.cs
+++ b/MediaBrowser.Api/ConfigurationService.cs
@@ -9,7 +9,9 @@ using ServiceStack.Web;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Controller.MediaEncoding;
namespace MediaBrowser.Api
{
@@ -71,6 +73,16 @@ namespace MediaBrowser.Api
}
+ [Route("/System/MediaEncoder/Path", "POST", Summary = "Updates the path to the media encoder")]
+ [Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)]
+ public class UpdateMediaEncoderPath : IReturnVoid
+ {
+ [ApiMember(Name = "Path", Description = "Path", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string Path { get; set; }
+ [ApiMember(Name = "PathType", Description = "PathType", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string PathType { get; set; }
+ }
+
public class ConfigurationService : BaseApiService
{
///
@@ -86,14 +98,22 @@ namespace MediaBrowser.Api
private readonly IFileSystem _fileSystem;
private readonly IProviderManager _providerManager;
private readonly ILibraryManager _libraryManager;
+ private readonly IMediaEncoder _mediaEncoder;
- public ConfigurationService(IJsonSerializer jsonSerializer, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IProviderManager providerManager, ILibraryManager libraryManager)
+ public ConfigurationService(IJsonSerializer jsonSerializer, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IProviderManager providerManager, ILibraryManager libraryManager, IMediaEncoder mediaEncoder)
{
_jsonSerializer = jsonSerializer;
_configurationManager = configurationManager;
_fileSystem = fileSystem;
_providerManager = providerManager;
_libraryManager = libraryManager;
+ _mediaEncoder = mediaEncoder;
+ }
+
+ public void Post(UpdateMediaEncoderPath request)
+ {
+ var task = _mediaEncoder.UpdateEncoderPath(request.Path, request.PathType);
+ Task.WaitAll(task);
}
///
diff --git a/MediaBrowser.Api/FilterService.cs b/MediaBrowser.Api/FilterService.cs
index c4419531c5..b3b75359aa 100644
--- a/MediaBrowser.Api/FilterService.cs
+++ b/MediaBrowser.Api/FilterService.cs
@@ -80,7 +80,7 @@ namespace MediaBrowser.Api
.OrderBy(i => i)
.ToArray();
- result.Tags = items.OfType()
+ result.Tags = items
.SelectMany(i => i.Tags)
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(i => i)
diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs
index 387771b6d5..0953b95e62 100644
--- a/MediaBrowser.Api/GamesService.cs
+++ b/MediaBrowser.Api/GamesService.cs
@@ -10,6 +10,8 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api
{
@@ -107,8 +109,7 @@ namespace MediaBrowser.Api
{
IncludeItemTypes = new[] { typeof(GameSystem).Name }
};
- var parentIds = new string[] { } ;
- var gameSystems = _libraryManager.GetItemList(query, parentIds)
+ var gameSystems = _libraryManager.GetItemList(query)
.Cast()
.ToList();
@@ -128,8 +129,7 @@ namespace MediaBrowser.Api
{
IncludeItemTypes = new[] { typeof(Game).Name }
};
- var parentIds = new string[] { };
- var games = _libraryManager.GetItemList(query, parentIds)
+ var games = _libraryManager.GetItemList(query)
.Cast()
.ToList();
@@ -185,20 +185,42 @@ namespace MediaBrowser.Api
///
/// The request.
/// System.Object.
- public object Get(GetSimilarGames request)
+ public async Task
/// The request.
/// System.Object.
- public object Head(GetAudioStream request)
+ public Task Head(GetAudioStream request)
{
return ProcessRequest(request, true);
}
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 3211f9e39f..868d8d4889 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -113,11 +113,11 @@ namespace MediaBrowser.Api.Playback.Progressive
/// The request.
/// if set to true [is head request].
/// Task.
- protected object ProcessRequest(StreamRequest request, bool isHeadRequest)
+ protected async Task ProcessRequest(StreamRequest request, bool isHeadRequest)
{
var cancellationTokenSource = new CancellationTokenSource();
- var state = GetState(request, cancellationTokenSource.Token).Result;
+ var state = await GetState(request, cancellationTokenSource.Token).ConfigureAwait(false);
var responseHeaders = new Dictionary();
@@ -128,7 +128,8 @@ namespace MediaBrowser.Api.Playback.Progressive
using (state)
{
- return GetStaticRemoteStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource).Result;
+ return await GetStaticRemoteStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource)
+ .ConfigureAwait(false);
}
}
@@ -138,7 +139,7 @@ namespace MediaBrowser.Api.Playback.Progressive
}
var outputPath = state.OutputFilePath;
- var outputPathExists = FileSystem.FileExists(outputPath);
+ var outputPathExists = FileSystem.FileExists(outputPath);
var isTranscodeCached = outputPathExists && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive);
@@ -151,13 +152,13 @@ namespace MediaBrowser.Api.Playback.Progressive
using (state)
{
- return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+ return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
{
ResponseHeaders = responseHeaders,
ContentType = contentType,
IsHeadRequest = isHeadRequest,
Path = state.MediaPath
- });
+ }).ConfigureAwait(false);
}
}
@@ -168,13 +169,13 @@ namespace MediaBrowser.Api.Playback.Progressive
try
{
- return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+ return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
{
ResponseHeaders = responseHeaders,
ContentType = contentType,
IsHeadRequest = isHeadRequest,
Path = outputPath
- });
+ }).ConfigureAwait(false);
}
finally
{
@@ -185,7 +186,8 @@ namespace MediaBrowser.Api.Playback.Progressive
// Need to start ffmpeg
try
{
- return GetStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource).Result;
+ return await GetStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource)
+ .ConfigureAwait(false);
}
catch
{
@@ -229,7 +231,7 @@ namespace MediaBrowser.Api.Playback.Progressive
if (trySupportSeek)
{
- foreach (var name in new[] {"Content-Range", "Accept-Ranges"})
+ foreach (var name in new[] { "Content-Range", "Accept-Ranges" })
{
var val = response.Headers[name];
if (!string.IsNullOrWhiteSpace(val))
@@ -242,12 +244,12 @@ namespace MediaBrowser.Api.Playback.Progressive
{
responseHeaders["Accept-Ranges"] = "none";
}
-
+
if (response.ContentLength.HasValue)
{
responseHeaders["Content-Length"] = response.ContentLength.Value.ToString(UsCulture);
}
-
+
if (isHeadRequest)
{
using (response)
@@ -324,7 +326,7 @@ namespace MediaBrowser.Api.Playback.Progressive
{
TranscodingJob job;
- if (!FileSystem.FileExists(outputPath))
+ if (!FileSystem.FileExists(outputPath))
{
job = await StartFfMpeg(state, outputPath, cancellationTokenSource).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index be3995aeb6..3fd67c51ea 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -10,6 +10,7 @@ using MediaBrowser.Model.Serialization;
using ServiceStack;
using System;
using System.IO;
+using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Model.Dlna;
@@ -76,7 +77,7 @@ namespace MediaBrowser.Api.Playback.Progressive
///
/// The request.
/// System.Object.
- public object Get(GetVideoStream request)
+ public Task Get(GetVideoStream request)
{
return ProcessRequest(request, false);
}
@@ -86,7 +87,7 @@ namespace MediaBrowser.Api.Playback.Progressive
///
/// The request.
/// System.Object.
- public object Head(GetVideoStream request)
+ public Task Head(GetVideoStream request)
{
return ProcessRequest(request, true);
}
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index 061afed6d9..fbcccbaca2 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -96,7 +96,7 @@ namespace MediaBrowser.Api.Playback
public long? InputFileSize { get; set; }
public string OutputAudioSync = "1";
- public string OutputVideoSync = "vfr";
+ public string OutputVideoSync = "-1";
public List SupportedAudioCodecs { get; set; }
diff --git a/MediaBrowser.Api/PlaylistService.cs b/MediaBrowser.Api/PlaylistService.cs
index 3dafd0eebc..604227a150 100644
--- a/MediaBrowser.Api/PlaylistService.cs
+++ b/MediaBrowser.Api/PlaylistService.cs
@@ -157,7 +157,7 @@ namespace MediaBrowser.Api
Task.WaitAll(task);
}
- public object Get(GetPlaylistItems request)
+ public async Task Get(GetPlaylistItems request)
{
var playlist = (Playlist)_libraryManager.GetItemById(request.Id);
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
@@ -178,7 +178,7 @@ namespace MediaBrowser.Api
var dtoOptions = GetDtoOptions(request);
- var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2), dtoOptions, user)
+ var dtos = (await _dtoService.GetBaseItemDtos(items.Select(i => i.Item2), dtoOptions, user).ConfigureAwait(false))
.ToArray();
var index = 0;
diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs
index cb16158268..36a2a4b619 100644
--- a/MediaBrowser.Api/Reports/ReportsService.cs
+++ b/MediaBrowser.Api/Reports/ReportsService.cs
@@ -213,7 +213,6 @@ namespace MediaBrowser.Api.Reports
NameStartsWith = request.NameStartsWith,
NameStartsWithOrGreater = request.NameStartsWithOrGreater,
HasImdbId = request.HasImdbId,
- IsYearMismatched = request.IsYearMismatched,
IsPlaceHolder = request.IsPlaceHolder,
IsLocked = request.IsLocked,
IsInBoxSet = request.IsInBoxSet,
diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs
index 277bba1dd1..c98a91a55f 100644
--- a/MediaBrowser.Api/SimilarItemsHelper.cs
+++ b/MediaBrowser.Api/SimilarItemsHelper.cs
@@ -9,6 +9,8 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Dto;
namespace MediaBrowser.Api
{
@@ -54,7 +56,7 @@ namespace MediaBrowser.Api
///
public static class SimilarItemsHelper
{
- internal static ItemsResult GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, ILogger logger, BaseGetSimilarItemsFromItem request, Type[] includeTypes, Func, List, BaseItem, int> getSimilarityScore)
+ internal static async Task> GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, ILogger logger, BaseGetSimilarItemsFromItem request, Type[] includeTypes, Func, List, BaseItem, int> getSimilarityScore)
{
var user = !string.IsNullOrWhiteSpace(request.UserId) ? userManager.GetUserById(request.UserId) : null;
@@ -80,14 +82,14 @@ namespace MediaBrowser.Api
returnItems = returnItems.Take(request.Limit.Value);
}
- var result = new ItemsResult
+ var dtos = await dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ConfigureAwait(false);
+
+ return new QueryResult
{
- Items = dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(),
+ Items = dtos.ToArray(),
TotalRecordCount = items.Count
};
-
- return result;
}
///
@@ -116,24 +118,12 @@ namespace MediaBrowser.Api
private static IEnumerable GetTags(BaseItem item)
{
- var hasTags = item as IHasTags;
- if (hasTags != null)
- {
- return hasTags.Tags;
- }
-
- return new List();
+ return item.Tags;
}
private static IEnumerable GetKeywords(BaseItem item)
{
- var hasTags = item as IHasKeywords;
- if (hasTags != null)
- {
- return hasTags.Keywords;
- }
-
- return new List();
+ return item.Keywords;
}
///
diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs
index ca934830d1..38a7337ecf 100644
--- a/MediaBrowser.Api/StartupWizardService.cs
+++ b/MediaBrowser.Api/StartupWizardService.cs
@@ -11,6 +11,7 @@ using ServiceStack;
using System;
using System.Linq;
using System.Threading.Tasks;
+using MediaBrowser.Controller.MediaEncoding;
namespace MediaBrowser.Api
{
@@ -52,14 +53,16 @@ namespace MediaBrowser.Api
private readonly IUserManager _userManager;
private readonly IConnectManager _connectManager;
private readonly ILiveTvManager _liveTvManager;
+ private readonly IMediaEncoder _mediaEncoder;
- public StartupWizardService(IServerConfigurationManager config, IServerApplicationHost appHost, IUserManager userManager, IConnectManager connectManager, ILiveTvManager liveTvManager)
+ public StartupWizardService(IServerConfigurationManager config, IServerApplicationHost appHost, IUserManager userManager, IConnectManager connectManager, ILiveTvManager liveTvManager, IMediaEncoder mediaEncoder)
{
_config = config;
_appHost = appHost;
_userManager = userManager;
_connectManager = connectManager;
_liveTvManager = liveTvManager;
+ _mediaEncoder = mediaEncoder;
}
public void Post(ReportStartupWizardComplete request)
@@ -69,13 +72,14 @@ namespace MediaBrowser.Api
_config.SaveConfiguration();
}
- public object Get(GetStartupInfo request)
+ public async Task Get(GetStartupInfo request)
{
- var info = _appHost.GetSystemInfo();
+ var info = await _appHost.GetSystemInfo().ConfigureAwait(false);
return new StartupInfo
{
- SupportsRunningAsService = info.SupportsRunningAsService
+ SupportsRunningAsService = info.SupportsRunningAsService,
+ HasMediaEncoder = !string.IsNullOrWhiteSpace(_mediaEncoder.EncoderPath)
};
}
@@ -111,10 +115,10 @@ namespace MediaBrowser.Api
{
config.EnableLocalizedGuids = true;
config.EnableCustomPathSubFolders = true;
- config.EnableDateLastRefresh = true;
config.EnableStandaloneMusicKeys = true;
config.EnableCaseSensitiveItemIds = true;
- config.SchemaVersion = 79;
+ config.EnableFolderView = true;
+ config.SchemaVersion = 97;
}
public void Post(UpdateStartupConfiguration request)
@@ -231,6 +235,7 @@ namespace MediaBrowser.Api
public class StartupInfo
{
public bool SupportsRunningAsService { get; set; }
+ public bool HasMediaEncoder { get; set; }
}
public class StartupUser
diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs
index c2183ad7b9..fe13e8b219 100644
--- a/MediaBrowser.Api/Subtitles/SubtitleService.cs
+++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs
@@ -98,6 +98,10 @@ namespace MediaBrowser.Api.Subtitles
[ApiMember(Name = "EndPositionTicks", Description = "EndPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public long? EndPositionTicks { get; set; }
+
+ [ApiMember(Name = "CopyTimestamps", Description = "CopyTimestamps", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+ public bool CopyTimestamps { get; set; }
+ public bool AddVttTimeMap { get; set; }
}
[Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")]
@@ -175,7 +179,7 @@ namespace MediaBrowser.Api.Subtitles
var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks);
- var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
+ var url = string.Format("stream.vtt?CopyTimestamps=true&AddVttTimeMap=true&StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
positionTicks.ToString(CultureInfo.InvariantCulture),
endPositionTicks.ToString(CultureInfo.InvariantCulture),
accessToken);
@@ -190,7 +194,7 @@ namespace MediaBrowser.Api.Subtitles
return ResultFactory.GetResult(builder.ToString(), MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary());
}
- public object Get(GetSubtitle request)
+ public async Task Get(GetSubtitle request)
{
if (string.Equals(request.Format, "js", StringComparison.OrdinalIgnoreCase))
{
@@ -206,23 +210,35 @@ namespace MediaBrowser.Api.Subtitles
var subtitleStream = mediaSource.MediaStreams
.First(i => i.Type == MediaStreamType.Subtitle && i.Index == request.Index);
- return ToStaticFileResult(subtitleStream.Path);
+ return await ResultFactory.GetStaticFileResult(Request, subtitleStream.Path).ConfigureAwait(false);
}
- var stream = GetSubtitles(request).Result;
+ using (var stream = await GetSubtitles(request).ConfigureAwait(false))
+ {
+ using (var reader = new StreamReader(stream))
+ {
+ var text = reader.ReadToEnd();
+
+ if (string.Equals(request.Format, "vtt", StringComparison.OrdinalIgnoreCase) && request.AddVttTimeMap)
+ {
+ text = text.Replace("WEBVTT", "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000");
+ }
- return ResultFactory.GetResult(stream, MimeTypes.GetMimeType("file." + request.Format));
+ return ResultFactory.GetResult(text, MimeTypes.GetMimeType("file." + request.Format));
+ }
+ }
}
- private async Task GetSubtitles(GetSubtitle request)
+ private Task GetSubtitles(GetSubtitle request)
{
- return await _subtitleEncoder.GetSubtitles(request.Id,
+ return _subtitleEncoder.GetSubtitles(request.Id,
request.MediaSourceId,
request.Index,
request.Format,
request.StartPositionTicks,
request.EndPositionTicks,
- CancellationToken.None).ConfigureAwait(false);
+ request.CopyTimestamps,
+ CancellationToken.None);
}
public object Get(SearchRemoteSubtitles request)
@@ -248,9 +264,9 @@ namespace MediaBrowser.Api.Subtitles
return ToOptimizedResult(result);
}
- public object Get(GetRemoteSubtitles request)
+ public async Task Get(GetRemoteSubtitles request)
{
- var result = _subtitleManager.GetRemoteSubtitles(request.Id, CancellationToken.None).Result;
+ var result = await _subtitleManager.GetRemoteSubtitles(request.Id, CancellationToken.None).ConfigureAwait(false);
return ResultFactory.GetResult(result.Stream, MimeTypes.GetMimeType("file." + result.Format));
}
diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs
index 593c3a108b..a15ce216f2 100644
--- a/MediaBrowser.Api/Sync/SyncService.cs
+++ b/MediaBrowser.Api/Sync/SyncService.cs
@@ -227,7 +227,7 @@ namespace MediaBrowser.Api.Sync
Task.WaitAll(task);
}
- public object Get(GetSyncJobItemFile request)
+ public async Task Get(GetSyncJobItemFile request)
{
var jobItem = _syncManager.GetJobItem(request.Id);
@@ -241,10 +241,9 @@ namespace MediaBrowser.Api.Sync
throw new ArgumentException("The job item is not yet ready for transfer.");
}
- var task = _syncManager.ReportSyncJobItemTransferBeginning(request.Id);
- Task.WaitAll(task);
+ await _syncManager.ReportSyncJobItemTransferBeginning(request.Id).ConfigureAwait(false);
- return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+ return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
{
Path = jobItem.OutputPath,
OnError = () =>
@@ -252,10 +251,11 @@ namespace MediaBrowser.Api.Sync
var failedTask = _syncManager.ReportSyncJobItemTransferFailed(request.Id);
Task.WaitAll(failedTask);
}
- });
+
+ }).ConfigureAwait(false);
}
- public object Get(GetSyncDialogOptions request)
+ public async Task Get(GetSyncDialogOptions request)
{
var result = new SyncDialogOptions();
@@ -298,8 +298,7 @@ namespace MediaBrowser.Api.Sync
.Select(_libraryManager.GetItemById)
.Where(i => i != null);
- var dtos = _dtoService.GetBaseItemDtos(items, dtoOptions, authenticatedUser)
- .ToList();
+ var dtos = (await _dtoService.GetBaseItemDtos(items, dtoOptions, authenticatedUser).ConfigureAwait(false));
result.Options = SyncHelper.GetSyncOptions(dtos);
}
@@ -343,7 +342,7 @@ namespace MediaBrowser.Api.Sync
Task.WaitAll(task);
}
- public object Get(GetSyncJobItemAdditionalFile request)
+ public Task Get(GetSyncJobItemAdditionalFile request)
{
var jobItem = _syncManager.GetJobItem(request.Id);
@@ -359,7 +358,7 @@ namespace MediaBrowser.Api.Sync
throw new ArgumentException("Sync job additional file not found.");
}
- return ToStaticFileResult(file.Path);
+ return ResultFactory.GetStaticFileResult(Request, file.Path);
}
public void Post(EnableSyncJobItem request)
diff --git a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
index 9ab7770ed6..a53bfac276 100644
--- a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
+++ b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
@@ -43,7 +43,7 @@ namespace MediaBrowser.Api.System
/// Task{SystemInfo}.
protected override Task GetDataToSend(WebSocketListenerState state)
{
- return Task.FromResult(_appHost.GetSystemInfo());
+ return _appHost.GetSystemInfo();
}
}
}
diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs
index b4b41c844e..c2318dccbc 100644
--- a/MediaBrowser.Api/System/SystemService.cs
+++ b/MediaBrowser.Api/System/SystemService.cs
@@ -19,7 +19,7 @@ namespace MediaBrowser.Api.System
/// Class GetSystemInfo
///
[Route("/System/Info", "GET", Summary = "Gets information about the server")]
- [Authenticated(EscapeParentalControl = true)]
+ [Authenticated(EscapeParentalControl = true, AllowBeforeStartupWizard = true)]
public class GetSystemInfo : IReturn
{
@@ -120,7 +120,7 @@ namespace MediaBrowser.Api.System
try
{
- files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
+ files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
.Where(i => string.Equals(i.Extension, ".txt", StringComparison.OrdinalIgnoreCase))
.ToList();
}
@@ -144,9 +144,9 @@ namespace MediaBrowser.Api.System
return ToOptimizedResult(result);
}
- public object Get(GetLogFile request)
+ public Task Get(GetLogFile request)
{
- var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
+ var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
.First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase));
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.ReadWrite);
@@ -157,16 +157,16 @@ namespace MediaBrowser.Api.System
///
/// The request.
/// System.Object.
- public object Get(GetSystemInfo request)
+ public async Task Get(GetSystemInfo request)
{
- var result = _appHost.GetSystemInfo();
+ var result = await _appHost.GetSystemInfo().ConfigureAwait(false);
return ToOptimizedResult(result);
}
- public object Get(GetPublicSystemInfo request)
+ public async Task Get(GetPublicSystemInfo request)
{
- var result = _appHost.GetSystemInfo();
+ var result = await _appHost.GetSystemInfo().ConfigureAwait(false);
var publicInfo = new PublicSystemInfo
{
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index aa0485d57e..3f248ea8f0 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -12,6 +12,8 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Dto;
namespace MediaBrowser.Api
{
@@ -271,29 +273,51 @@ namespace MediaBrowser.Api
///
/// The request.
/// System.Object.
- public object Get(GetSimilarShows request)
+ public async Task Get(GetSimilarShows request)
{
+ var result = await GetSimilarItemsResult(request).ConfigureAwait(false);
+
+ return ToOptimizedSerializedResultUsingCache(result);
+ }
+
+ private async Task> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
+ {
+ var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+
+ var item = string.IsNullOrEmpty(request.Id) ?
+ (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
+ _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
+
+ var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ {
+ Limit = request.Limit,
+ IncludeItemTypes = new[]
+ {
+ typeof(Series).Name
+ },
+ SimilarTo = item
+
+ }).ToList();
+
var dtoOptions = GetDtoOptions(request);
- var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
- _itemRepo,
- _libraryManager,
- _userDataManager,
- _dtoService,
- Logger,
- request, new[] { typeof(Series) },
- SimilarItemsHelper.GetSimiliarityScore);
+ var result = new QueryResult
+ {
+ Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
- return ToOptimizedSerializedResultUsingCache(result);
+ TotalRecordCount = itemsResult.Count
+ };
+
+ return result;
}
- public object Get(GetUpcomingEpisodes request)
+ public async Task Get(GetUpcomingEpisodes request)
{
var user = _userManager.GetUserById(request.UserId);
var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1);
- var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId };
+ var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId);
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
@@ -302,13 +326,15 @@ namespace MediaBrowser.Api
SortOrder = SortOrder.Ascending,
MinPremiereDate = minPremiereDate,
StartIndex = request.StartIndex,
- Limit = request.Limit
+ Limit = request.Limit,
+ ParentId = parentIdGuid,
+ Recursive = true
- }, parentIds).ToList();
+ }).ToList();
var options = GetDtoOptions(request);
- var returnItems = _dtoService.GetBaseItemDtos(itemsResult, options, user).ToArray();
+ var returnItems = (await _dtoService.GetBaseItemDtos(itemsResult, options, user).ConfigureAwait(false)).ToArray();
var result = new ItemsResult
{
@@ -324,7 +350,7 @@ namespace MediaBrowser.Api
///
/// The request.
/// System.Object.
- public object Get(GetNextUpEpisodes request)
+ public async Task Get(GetNextUpEpisodes request)
{
var result = _tvSeriesManager.GetNextUp(new NextUpQuery
{
@@ -339,7 +365,7 @@ namespace MediaBrowser.Api
var options = GetDtoOptions(request);
- var returnItems = _dtoService.GetBaseItemDtos(result.Items, options, user).ToArray();
+ var returnItems = (await _dtoService.GetBaseItemDtos(result.Items, options, user).ConfigureAwait(false)).ToArray();
return ToOptimizedSerializedResultUsingCache(new ItemsResult
{
@@ -372,7 +398,7 @@ namespace MediaBrowser.Api
return items;
}
- public object Get(GetSeasons request)
+ public async Task Get(GetSeasons request)
{
var user = _userManager.GetUserById(request.UserId);
@@ -403,7 +429,7 @@ namespace MediaBrowser.Api
var dtoOptions = GetDtoOptions(request);
- var returnItems = _dtoService.GetBaseItemDtos(seasons, dtoOptions, user)
+ var returnItems = (await _dtoService.GetBaseItemDtos(seasons, dtoOptions, user).ConfigureAwait(false))
.ToArray();
return new ItemsResult
@@ -430,7 +456,7 @@ namespace MediaBrowser.Api
return items;
}
- public object Get(GetEpisodes request)
+ public async Task Get(GetEpisodes request)
{
var user = _userManager.GetUserById(request.UserId);
@@ -512,7 +538,7 @@ namespace MediaBrowser.Api
var dtoOptions = GetDtoOptions(request);
- var dtos = _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user)
+ var dtos = (await _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user).ConfigureAwait(false))
.ToArray();
return new ItemsResult
diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
index cde5eade5b..df73ef720b 100644
--- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using System;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
@@ -8,6 +9,8 @@ using MediaBrowser.Model.Dto;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -100,7 +103,12 @@ namespace MediaBrowser.Api.UserLibrary
/// System.Object.
public object Get(GetArtists request)
{
- var result = GetResult(request);
+ if (string.IsNullOrWhiteSpace(request.IncludeItemTypes))
+ {
+ //request.IncludeItemTypes = "Audio,MusicVideo";
+ }
+
+ var result = GetResultSlim(request);
return ToOptimizedResult(result);
}
@@ -112,11 +120,26 @@ namespace MediaBrowser.Api.UserLibrary
/// System.Object.
public object Get(GetAlbumArtists request)
{
- var result = GetResult(request);
+ if (string.IsNullOrWhiteSpace(request.IncludeItemTypes))
+ {
+ //request.IncludeItemTypes = "Audio,MusicVideo";
+ }
+
+ var result = GetResultSlim(request);
return ToOptimizedResult(result);
}
+ protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ if (request is GetAlbumArtists)
+ {
+ return LibraryManager.GetAlbumArtists(query);
+ }
+
+ return LibraryManager.GetArtists(query);
+ }
+
///
/// Gets all items.
///
@@ -125,16 +148,7 @@ namespace MediaBrowser.Api.UserLibrary
/// IEnumerable{Tuple{System.StringFunc{System.Int32}}}.
protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items)
{
- if (request is GetAlbumArtists)
- {
- return LibraryManager.GetAlbumArtists(items
- .Where(i => !i.IsFolder)
- .OfType());
- }
-
- return LibraryManager.GetArtists(items
- .Where(i => !i.IsFolder)
- .OfType());
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index 565bed0531..9465d1fdc5 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -8,6 +8,7 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Dto;
namespace MediaBrowser.Api.UserLibrary
{
@@ -83,6 +84,137 @@ namespace MediaBrowser.Api.UserLibrary
return null;
}
+ protected ItemsResult GetResultSlim(GetItemsByName request)
+ {
+ var dtoOptions = GetDtoOptions(request);
+
+ User user = null;
+ BaseItem parentItem;
+
+ if (!string.IsNullOrWhiteSpace(request.UserId))
+ {
+ user = UserManager.GetUserById(request.UserId);
+ parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
+ }
+ else
+ {
+ parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId);
+ }
+
+ var excludeItemTypes = request.GetExcludeItemTypes();
+ var includeItemTypes = request.GetIncludeItemTypes();
+ var mediaTypes = request.GetMediaTypes();
+
+ var query = new InternalItemsQuery(user)
+ {
+ ExcludeItemTypes = excludeItemTypes,
+ IncludeItemTypes = includeItemTypes,
+ MediaTypes = mediaTypes,
+ StartIndex = request.StartIndex,
+ Limit = request.Limit,
+ IsFavorite = request.IsFavorite,
+ NameLessThan = request.NameLessThan,
+ NameStartsWith = request.NameStartsWith,
+ NameStartsWithOrGreater = request.NameStartsWithOrGreater,
+ AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater,
+ Tags = request.GetTags(),
+ OfficialRatings = request.GetOfficialRatings(),
+ Genres = request.GetGenres(),
+ GenreIds = request.GetGenreIds(),
+ Studios = request.GetStudios(),
+ StudioIds = request.GetStudioIds(),
+ Person = request.Person,
+ PersonIds = request.GetPersonIds(),
+ PersonTypes = request.GetPersonTypes(),
+ Years = request.GetYears(),
+ MinCommunityRating = request.MinCommunityRating
+ };
+
+ if (!string.IsNullOrWhiteSpace(request.ParentId))
+ {
+ if (parentItem is Folder)
+ {
+ query.AncestorIds = new[] { request.ParentId };
+ }
+ else
+ {
+ query.ItemIds = new[] { request.ParentId };
+ }
+ }
+
+ foreach (var filter in request.GetFilters())
+ {
+ switch (filter)
+ {
+ case ItemFilter.Dislikes:
+ query.IsLiked = false;
+ break;
+ case ItemFilter.IsFavorite:
+ query.IsFavorite = true;
+ break;
+ case ItemFilter.IsFavoriteOrLikes:
+ query.IsFavoriteOrLiked = true;
+ break;
+ case ItemFilter.IsFolder:
+ query.IsFolder = true;
+ break;
+ case ItemFilter.IsNotFolder:
+ query.IsFolder = false;
+ break;
+ case ItemFilter.IsPlayed:
+ query.IsPlayed = true;
+ break;
+ case ItemFilter.IsRecentlyAdded:
+ break;
+ case ItemFilter.IsResumable:
+ query.IsResumable = true;
+ break;
+ case ItemFilter.IsUnplayed:
+ query.IsPlayed = false;
+ break;
+ case ItemFilter.Likes:
+ query.IsLiked = true;
+ break;
+ }
+ }
+
+ var result = GetItems(request, query);
+
+ var dtos = result.Items.Select(i =>
+ {
+ var dto = DtoService.GetItemByNameDto(i.Item1, dtoOptions, null, user);
+
+ if (!string.IsNullOrWhiteSpace(request.IncludeItemTypes))
+ {
+ SetItemCounts(dto, i.Item2);
+ }
+ return dto;
+ });
+
+ return new ItemsResult
+ {
+ Items = dtos.ToArray(),
+ TotalRecordCount = result.TotalRecordCount
+ };
+ }
+
+ protected virtual QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return new QueryResult>();
+ }
+
+ private void SetItemCounts(BaseItemDto dto, ItemCounts counts)
+ {
+ dto.ChildCount = counts.ItemCount;
+ dto.SeriesCount = counts.SeriesCount;
+ dto.EpisodeCount = counts.EpisodeCount;
+ dto.MovieCount = counts.MovieCount;
+ dto.TrailerCount = counts.TrailerCount;
+ dto.AlbumCount = counts.AlbumCount;
+ dto.SongCount = counts.SongCount;
+ dto.GameCount = counts.GameCount;
+ }
+
///
/// Gets the specified request.
///
@@ -333,12 +465,7 @@ namespace MediaBrowser.Api.UserLibrary
var tags = request.GetTags();
if (tags.Length > 0)
{
- var hasTags = i as IHasTags;
- if (hasTags == null)
- {
- return false;
- }
- if (!tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
+ if (!tags.Any(v => i.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
{
return false;
}
@@ -379,7 +506,7 @@ namespace MediaBrowser.Api.UserLibrary
/// The include item types.
/// The media types.
/// IEnumerable{BaseItem}.
- protected bool FilterItem(GetItemsByName request, BaseItem f, string[] excludeItemTypes, string[] includeItemTypes, string[] mediaTypes)
+ private bool FilterItem(GetItemsByName request, BaseItem f, string[] excludeItemTypes, string[] includeItemTypes, string[] mediaTypes)
{
// Exclude item types
if (excludeItemTypes.Length > 0)
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
index aee1a8d545..d27a560ba5 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
@@ -100,9 +100,6 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "HasTvdbId", Description = "Optional filter by items that have a tvdb id or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasTvdbId { get; set; }
- [ApiMember(Name = "IsYearMismatched", Description = "Optional filter by items that are potentially misidentified.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
- public bool? IsYearMismatched { get; set; }
-
[ApiMember(Name = "IsInBoxSet", Description = "Optional filter by items that are in boxsets, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsInBoxSet { get; set; }
diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs
index 58237f80f2..a0883f98cc 100644
--- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs
@@ -9,16 +9,13 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
[Route("/GameGenres", "GET", Summary = "Gets all Game genres from a given item, folder, or the entire library")]
public class GetGameGenres : GetItemsByName
{
- public GetGameGenres()
- {
- MediaTypes = MediaType.Game;
- }
}
[Route("/GameGenres/{Name}", "GET", Summary = "Gets a Game genre, by name")]
@@ -87,11 +84,16 @@ namespace MediaBrowser.Api.UserLibrary
/// System.Object.
public object Get(GetGameGenres request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
+ protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return LibraryManager.GetGameGenres(query);
+ }
+
///
/// Gets all items.
///
@@ -100,22 +102,7 @@ namespace MediaBrowser.Api.UserLibrary
/// IEnumerable{Tuple{System.StringFunc{System.Int32}}}.
protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items)
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name =>
- {
- try
- {
- return LibraryManager.GetGameGenre(name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting genre {0}", ex, name);
- return null;
- }
- })
- .Where(i => i != null);
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs
index d383bd0adb..57c11a1fad 100644
--- a/MediaBrowser.Api/UserLibrary/GenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GenresService.cs
@@ -9,6 +9,7 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -92,65 +93,37 @@ namespace MediaBrowser.Api.UserLibrary
/// System.Object.
public object Get(GetGenres request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
- ///
- /// Gets all items.
- ///
- /// The request.
- /// The items.
- /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}.
- protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items)
+ protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query)
{
var viewType = GetParentItemViewType(request);
if (string.Equals(viewType, CollectionType.Music) || string.Equals(viewType, CollectionType.MusicVideos))
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name => LibraryManager.GetMusicGenre(name));
+ return LibraryManager.GetMusicGenres(query);
}
if (string.Equals(viewType, CollectionType.Games))
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name =>
- {
- try
- {
- return LibraryManager.GetGameGenre(name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting genre {0}", ex, name);
- return null;
- }
- })
- .Where(i => i != null);
+ return LibraryManager.GetGameGenres(query);
}
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name =>
- {
- try
- {
- return LibraryManager.GetGenre(name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting genre {0}", ex, name);
- return null;
- }
- })
- .Where(i => i != null);
+ return LibraryManager.GetGenres(query);
+ }
+
+ ///
+ /// Gets all items.
+ ///
+ /// The request.
+ /// The items.
+ /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}.
+ protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items)
+ {
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index dac1a6b1a8..a6f1d8b98f 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -34,7 +34,6 @@ namespace MediaBrowser.Api.UserLibrary
/// The _user manager
///
private readonly IUserManager _userManager;
- private readonly IUserDataManager _userDataRepository;
///
/// The _library manager
@@ -43,25 +42,37 @@ namespace MediaBrowser.Api.UserLibrary
private readonly ILocalizationManager _localization;
private readonly IDtoService _dtoService;
- private readonly ICollectionManager _collectionManager;
///
/// Initializes a new instance of the class.
///
/// The user manager.
/// The library manager.
- /// The user data repository.
/// The localization.
/// The dto service.
- /// The collection manager.
- public ItemsService(IUserManager userManager, ILibraryManager libraryManager, IUserDataManager userDataRepository, ILocalizationManager localization, IDtoService dtoService, ICollectionManager collectionManager)
+ public ItemsService(IUserManager userManager, ILibraryManager libraryManager, ILocalizationManager localization, IDtoService dtoService)
{
+ if (userManager == null)
+ {
+ throw new ArgumentNullException("userManager");
+ }
+ if (libraryManager == null)
+ {
+ throw new ArgumentNullException("libraryManager");
+ }
+ if (localization == null)
+ {
+ throw new ArgumentNullException("localization");
+ }
+ if (dtoService == null)
+ {
+ throw new ArgumentNullException("dtoService");
+ }
+
_userManager = userManager;
_libraryManager = libraryManager;
- _userDataRepository = userDataRepository;
_localization = localization;
_dtoService = dtoService;
- _collectionManager = collectionManager;
}
///
@@ -71,6 +82,11 @@ namespace MediaBrowser.Api.UserLibrary
/// System.Object.
public async Task Get(GetItems request)
{
+ if (request == null)
+ {
+ throw new ArgumentNullException("request");
+ }
+
var result = await GetItems(request).ConfigureAwait(false);
return ToOptimizedSerializedResultUsingCache(result);
@@ -84,15 +100,32 @@ namespace MediaBrowser.Api.UserLibrary
private async Task GetItems(GetItems request)
{
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
-
+
var result = await GetItemsToSerialize(request, user).ConfigureAwait(false);
+ if (result == null)
+ {
+ throw new InvalidOperationException("GetItemsToSerialize returned null");
+ }
+
+ if (result.Items == null)
+ {
+ throw new InvalidOperationException("GetItemsToSerialize result.Items returned null");
+ }
+
var dtoOptions = GetDtoOptions(request);
+ var dtoList = await _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user).ConfigureAwait(false);
+
+ if (dtoList == null)
+ {
+ throw new InvalidOperationException("GetBaseItemDtos returned null");
+ }
+
return new ItemsResult
{
TotalRecordCount = result.TotalRecordCount,
- Items = _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user).ToArray()
+ Items = dtoList.ToArray()
};
}
@@ -119,11 +152,17 @@ namespace MediaBrowser.Api.UserLibrary
// Default list type = children
+ var folder = item as Folder;
+ if (folder == null)
+ {
+ folder = user == null ? _libraryManager.RootFolder : _libraryManager.GetUserRootFolder();
+ }
+
if (!string.IsNullOrEmpty(request.Ids))
{
request.Recursive = true;
var query = GetItemsQuery(request, user);
- var result = await ((Folder)item).GetItems(query).ConfigureAwait(false);
+ var result = await folder.GetItems(query).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(request.SortBy))
{
@@ -138,22 +177,22 @@ namespace MediaBrowser.Api.UserLibrary
if (request.Recursive)
{
- return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
+ return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
}
if (user == null)
{
- return await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false);
+ return await folder.GetItems(GetItemsQuery(request, null)).ConfigureAwait(false);
}
var userRoot = item as UserRootFolder;
if (userRoot == null)
{
- return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
+ return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
}
- IEnumerable items = ((Folder)item).GetChildren(user, true);
+ IEnumerable items = folder.GetChildren(user, true);
var itemsArray = items.ToArray();
@@ -187,7 +226,6 @@ namespace MediaBrowser.Api.UserLibrary
NameStartsWith = request.NameStartsWith,
NameStartsWithOrGreater = request.NameStartsWithOrGreater,
HasImdbId = request.HasImdbId,
- IsYearMismatched = request.IsYearMismatched,
IsPlaceHolder = request.IsPlaceHolder,
IsLocked = request.IsLocked,
IsInBoxSet = request.IsInBoxSet,
@@ -301,7 +339,7 @@ namespace MediaBrowser.Api.UserLibrary
{
query.LocationTypes = request.LocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray();
}
-
+
// Min official rating
if (!string.IsNullOrWhiteSpace(request.MinOfficialRating))
{
diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
index 12cb62fac9..887c999411 100644
--- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using System;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
@@ -8,16 +9,14 @@ using MediaBrowser.Model.Dto;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
[Route("/MusicGenres", "GET", Summary = "Gets all music genres from a given item, folder, or the entire library")]
public class GetMusicGenres : GetItemsByName
{
- public GetMusicGenres()
- {
- IncludeItemTypes = typeof(Audio).Name;
- }
}
[Route("/MusicGenres/{Name}", "GET", Summary = "Gets a music genre, by name")]
@@ -86,11 +85,16 @@ namespace MediaBrowser.Api.UserLibrary
/// System.Object.
public object Get(GetMusicGenres request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
+ protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return LibraryManager.GetMusicGenres(query);
+ }
+
///
/// Gets all items.
///
@@ -99,10 +103,7 @@ namespace MediaBrowser.Api.UserLibrary
/// IEnumerable{Tuple{System.StringFunc{System.Int32}}}.
protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items)
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name => LibraryManager.GetMusicGenre(name));
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs
index 94c391cb5b..710d337ec1 100644
--- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs
+++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs
@@ -247,9 +247,9 @@ namespace MediaBrowser.Api.UserLibrary
/// Posts the specified request.
///
/// The request.
- public object Post(MarkPlayedItem request)
+ public async Task Post(MarkPlayedItem request)
{
- var result = MarkPlayed(request).Result;
+ var result = await MarkPlayed(request).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@@ -429,7 +429,7 @@ namespace MediaBrowser.Api.UserLibrary
await item.MarkUnplayed(user).ConfigureAwait(false);
}
- return _userDataRepository.GetUserDataDto(item, user);
+ return await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false);
}
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs
index 2cdabf721f..9e9c25d78a 100644
--- a/MediaBrowser.Api/UserLibrary/StudiosService.cs
+++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using System;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
@@ -7,6 +8,7 @@ using MediaBrowser.Model.Dto;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -90,11 +92,16 @@ namespace MediaBrowser.Api.UserLibrary
/// System.Object.
public object Get(GetStudios request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
+ protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return LibraryManager.GetStudios(query);
+ }
+
///
/// Gets all items.
///
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index 8cc5cab358..3be11bdc56 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -488,9 +488,9 @@ namespace MediaBrowser.Api.UserLibrary
/// Posts the specified request.
///
/// The request.
- public object Post(MarkFavoriteItem request)
+ public async Task Post(MarkFavoriteItem request)
{
- var dto = MarkFavorite(request.UserId, request.Id, true).Result;
+ var dto = await MarkFavorite(request.UserId, request.Id, true).ConfigureAwait(false);
return ToOptimizedResult(dto);
}
@@ -527,7 +527,7 @@ namespace MediaBrowser.Api.UserLibrary
await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false);
- return _userDataRepository.GetUserDataDto(item, user);
+ return await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false);
}
///
@@ -545,9 +545,9 @@ namespace MediaBrowser.Api.UserLibrary
/// Posts the specified request.
///
/// The request.
- public object Post(UpdateUserItemRating request)
+ public async Task Post(UpdateUserItemRating request)
{
- var dto = UpdateUserItemRating(request.UserId, request.Id, request.Likes).Result;
+ var dto = await UpdateUserItemRating(request.UserId, request.Id, request.Likes).ConfigureAwait(false);
return ToOptimizedResult(dto);
}
@@ -572,7 +572,7 @@ namespace MediaBrowser.Api.UserLibrary
await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false);
- return _userDataRepository.GetUserDataDto(item, user);
+ return await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false);
}
}
}
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 9b611c3971..07ff36c41f 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -385,7 +385,7 @@ namespace MediaBrowser.Api
throw new ResourceNotFoundException("User not found");
}
- await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false);
+ await _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), null).ConfigureAwait(false);
await _userManager.DeleteUser(user).ConfigureAwait(false);
}
@@ -465,6 +465,10 @@ namespace MediaBrowser.Api
}
await _userManager.ChangePassword(user, request.NewPassword).ConfigureAwait(false);
+
+ var currentToken = AuthorizationContext.GetAuthorizationInfo(Request).Token;
+
+ await _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), currentToken).ConfigureAwait(false);
}
}
@@ -602,7 +606,8 @@ namespace MediaBrowser.Api
throw new ArgumentException("There must be at least one enabled user in the system.");
}
- await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false);
+ var currentToken = AuthorizationContext.GetAuthorizationInfo(Request).Token;
+ await _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), currentToken).ConfigureAwait(false);
}
await _userManager.UpdateUserPolicy(request.Id, request).ConfigureAwait(false);
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
index f44c975d41..baf5afc1ba 100644
--- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
+++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
@@ -199,7 +199,7 @@ namespace MediaBrowser.Common.Implementations
ILogManager logManager,
IFileSystem fileSystem)
{
- XmlSerializer = new MediaBrowser.Common.Implementations.Serialization.XmlSerializer (fileSystem);
+ XmlSerializer = new XmlSerializer (fileSystem, logManager.GetLogger("XmlSerializer"));
FailedAssemblies = new List();
ApplicationPaths = applicationPaths;
@@ -321,7 +321,7 @@ namespace MediaBrowser.Common.Implementations
protected virtual IJsonSerializer CreateJsonSerializer()
{
- return new JsonSerializer(FileSystemManager);
+ return new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer"));
}
private void SetHttpLimit()
@@ -552,7 +552,7 @@ namespace MediaBrowser.Common.Implementations
}
catch (Exception ex)
{
- Logger.Error("Error creating {0}", ex, type.Name);
+ Logger.ErrorException("Error creating {0}", ex, type.Name);
throw;
}
@@ -571,7 +571,7 @@ namespace MediaBrowser.Common.Implementations
}
catch (Exception ex)
{
- Logger.Error("Error creating {0}", ex, type.Name);
+ Logger.ErrorException("Error creating {0}", ex, type.Name);
// Don't blow up in release mode
return null;
}
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index f9dbd766f8..5c70179a83 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -128,11 +128,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
private void AddIpv4Option(HttpWebRequest request, HttpRequestOptions options)
{
- if (!options.PreferIpv4)
- {
- return;
- }
-
request.ServicePoint.BindIPEndPointDelegate = (servicePount, remoteEndPoint, retryCount) =>
{
if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork)
@@ -143,18 +138,23 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
};
}
- private WebRequest GetRequest(HttpRequestOptions options, string method, bool enableHttpCompression)
+ private WebRequest GetRequest(HttpRequestOptions options, string method)
{
var request = CreateWebRequest(options.Url);
var httpWebRequest = request as HttpWebRequest;
if (httpWebRequest != null)
{
- AddIpv4Option(httpWebRequest, options);
+ if (options.PreferIpv4)
+ {
+ AddIpv4Option(httpWebRequest, options);
+ }
AddRequestHeaders(httpWebRequest, options);
- httpWebRequest.AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None;
+ httpWebRequest.AutomaticDecompression = options.EnableHttpCompression ?
+ (options.DecompressionMethod ?? DecompressionMethods.Deflate) :
+ DecompressionMethods.None;
}
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
@@ -366,7 +366,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
};
}
- var httpWebRequest = GetRequest(options, httpMethod, options.EnableHttpCompression);
+ var httpWebRequest = GetRequest(options, httpMethod);
if (options.RequestContentBytes != null ||
!string.IsNullOrEmpty(options.RequestContent) ||
@@ -556,7 +556,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
options.CancellationToken.ThrowIfCancellationRequested();
- var httpWebRequest = GetRequest(options, "GET", options.EnableHttpCompression);
+ var httpWebRequest = GetRequest(options, "GET");
if (options.ResourcePool != null)
{
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index 70489d7142..108eddcf9e 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -55,7 +55,7 @@
..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll
- ..\packages\NLog.4.3.4\lib\net45\NLog.dll
+ ..\packages\NLog.4.3.5\lib\net45\NLog.dll
True
@@ -65,8 +65,8 @@
False
..\ThirdParty\SharpCompress\SharpCompress.dll
-
- ..\packages\SimpleInjector.3.1.4\lib\net45\SimpleInjector.dll
+
+ ..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll
True
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index 090966d2b6..b34d57c42e 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -122,30 +122,27 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
get
{
- if (_lastExecutionResult == null)
- {
- var path = GetHistoryFilePath();
+ var path = GetHistoryFilePath();
- lock (_lastExecutionResultSyncLock)
+ lock (_lastExecutionResultSyncLock)
+ {
+ if (_lastExecutionResult == null)
{
- if (_lastExecutionResult == null)
+ try
+ {
+ _lastExecutionResult = JsonSerializer.DeserializeFromFile(path);
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // File doesn't exist. No biggie
+ }
+ catch (FileNotFoundException)
+ {
+ // File doesn't exist. No biggie
+ }
+ catch (Exception ex)
{
- try
- {
- return JsonSerializer.DeserializeFromFile(path);
- }
- catch (DirectoryNotFoundException)
- {
- // File doesn't exist. No biggie
- }
- catch (FileNotFoundException)
- {
- // File doesn't exist. No biggie
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error deserializing {0}", ex, path);
- }
+ Logger.ErrorException("Error deserializing {0}", ex, path);
}
}
}
diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
index 6610cd3ff7..5dbbe53731 100644
--- a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
@@ -2,6 +2,7 @@
using System;
using System.IO;
using CommonIO;
+using MediaBrowser.Model.Logging;
namespace MediaBrowser.Common.Implementations.Serialization
{
@@ -11,10 +12,12 @@ namespace MediaBrowser.Common.Implementations.Serialization
public class JsonSerializer : IJsonSerializer
{
private readonly IFileSystem _fileSystem;
-
- public JsonSerializer(IFileSystem fileSystem)
+ private readonly ILogger _logger;
+
+ public JsonSerializer(IFileSystem fileSystem, ILogger logger)
{
_fileSystem = fileSystem;
+ _logger = logger;
Configure();
}
@@ -65,6 +68,7 @@ namespace MediaBrowser.Common.Implementations.Serialization
private Stream OpenFile(string path)
{
+ _logger.Debug("Deserializing file {0}", path);
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 131072);
}
diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
index 189fb7afc9..290524921e 100644
--- a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
@@ -4,6 +4,7 @@ using System.Collections.Concurrent;
using System.IO;
using System.Xml;
using CommonIO;
+using MediaBrowser.Model.Logging;
namespace MediaBrowser.Common.Implementations.Serialization
{
@@ -12,12 +13,14 @@ namespace MediaBrowser.Common.Implementations.Serialization
///
public class XmlSerializer : IXmlSerializer
{
- private IFileSystem _fileSystem;
+ private readonly IFileSystem _fileSystem;
+ private readonly ILogger _logger;
- public XmlSerializer(IFileSystem fileSystem)
- {
- _fileSystem = fileSystem;
- }
+ public XmlSerializer(IFileSystem fileSystem, ILogger logger)
+ {
+ _fileSystem = fileSystem;
+ _logger = logger;
+ }
// Need to cache these
// http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html
@@ -91,6 +94,7 @@ namespace MediaBrowser.Common.Implementations.Serialization
/// System.Object.
public object DeserializeFromFile(Type type, string file)
{
+ _logger.Debug("Deserializing file {0}", file);
using (var stream = _fileSystem.OpenRead(file))
{
return DeserializeFromStream(type, stream);
diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config
index d1d135b20c..882acc9ffd 100644
--- a/MediaBrowser.Common.Implementations/packages.config
+++ b/MediaBrowser.Common.Implementations/packages.config
@@ -2,7 +2,7 @@
-
+
-
+
\ No newline at end of file
diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs
index 75368a5fc3..1a7f414a77 100644
--- a/MediaBrowser.Common/Net/HttpRequestOptions.cs
+++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net;
using System.Threading;
namespace MediaBrowser.Common.Net
@@ -16,6 +17,8 @@ namespace MediaBrowser.Common.Net
/// The URL.
public string Url { get; set; }
+ public DecompressionMethods? DecompressionMethod { get; set; }
+
///
/// Gets or sets the accept header.
///
diff --git a/MediaBrowser.Controller/Channels/ChannelItemInfo.cs b/MediaBrowser.Controller/Channels/ChannelItemInfo.cs
index 587023ab48..57c2f1f7fd 100644
--- a/MediaBrowser.Controller/Channels/ChannelItemInfo.cs
+++ b/MediaBrowser.Controller/Channels/ChannelItemInfo.cs
@@ -53,6 +53,12 @@ namespace MediaBrowser.Controller.Channels
public bool IsInfiniteStream { get; set; }
+ public string HomePageUrl { get; set; }
+
+ public List Artists { get; set; }
+
+ public List AlbumArtists { get; set; }
+
public ChannelItemInfo()
{
MediaSources = new List();
@@ -62,6 +68,8 @@ namespace MediaBrowser.Controller.Channels
People = new List();
Tags = new List();
ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ Artists = new List();
+ AlbumArtists = new List();
}
}
}
diff --git a/MediaBrowser.Controller/Chapters/IChapterManager.cs b/MediaBrowser.Controller/Chapters/IChapterManager.cs
index 676ef9c561..27e06fb8dd 100644
--- a/MediaBrowser.Controller/Chapters/IChapterManager.cs
+++ b/MediaBrowser.Controller/Chapters/IChapterManager.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Chapters
/// The chapters.
/// The cancellation token.
/// Task.
- Task SaveChapters(string itemId, IEnumerable chapters, CancellationToken cancellationToken);
+ Task SaveChapters(string itemId, List chapters, CancellationToken cancellationToken);
///
/// Searches the specified video.
diff --git a/MediaBrowser.Controller/Drawing/ImageCollageOptions.cs b/MediaBrowser.Controller/Drawing/ImageCollageOptions.cs
index edc4f85586..92a7f5ac92 100644
--- a/MediaBrowser.Controller/Drawing/ImageCollageOptions.cs
+++ b/MediaBrowser.Controller/Drawing/ImageCollageOptions.cs
@@ -23,10 +23,5 @@ namespace MediaBrowser.Controller.Drawing
///
/// The height.
public int Height { get; set; }
- ///
- /// Gets or sets the text.
- ///
- /// The text.
- public string Text { get; set; }
}
}
diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs
index 5f0442f934..e4aa466dfd 100644
--- a/MediaBrowser.Controller/Dto/IDtoService.cs
+++ b/MediaBrowser.Controller/Dto/IDtoService.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
using System.Collections.Generic;
+using System.Threading.Tasks;
namespace MediaBrowser.Controller.Dto
{
@@ -68,7 +69,7 @@ namespace MediaBrowser.Controller.Dto
/// The user.
/// The owner.
/// IEnumerable<BaseItemDto>.
- IEnumerable GetBaseItemDtos(IEnumerable items, DtoOptions options, User user = null,
+ Task> GetBaseItemDtos(IEnumerable items, DtoOptions options, User user = null,
BaseItem owner = null);
///
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index c34a884ff5..b3df34c4dc 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -20,15 +20,12 @@ namespace MediaBrowser.Controller.Entities.Audio
IHasArtist,
IHasMusicGenres,
IHasLookupInfo,
- IHasTags,
IHasMediaSources,
IThemeMedia,
IArchivable
{
public List ChannelMediaSources { get; set; }
- public long? Size { get; set; }
- public string Container { get; set; }
public int? TotalBitrate { get; set; }
public ExtraType? ExtraType { get; set; }
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index 615276e837..1f3b0c92a5 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
@@ -179,17 +179,13 @@ namespace MediaBrowser.Controller.Entities.Audio
{
var items = GetRecursiveChildren().ToList();
- var songs = items.OfType
/// IEnumerable{BaseItem}.
- protected IEnumerable GetCachedChildren()
+ protected IEnumerable GetCachedChildren()
{
- return ItemRepository.GetItemIdsList(new InternalItemsQuery
+ return ItemRepository.GetItemList(new InternalItemsQuery
{
ParentId = Id,
GroupByPresentationUniqueKey = false
});
}
+ public virtual int GetChildCount(User user)
+ {
+ if (LinkedChildren.Count > 0)
+ {
+ if (!(this is ICollectionFolder))
+ {
+ return GetChildren(user, true).Count();
+ }
+ }
+
+ var result = GetItems(new InternalItemsQuery(user)
+ {
+ Recursive = false,
+ Limit = 0,
+ ParentId = Id
+
+ }).Result;
+
+ return result.TotalRecordCount;
+ }
+
public QueryResult QueryRecursive(InternalItemsQuery query)
{
var user = query.User;
@@ -768,58 +723,13 @@ namespace MediaBrowser.Controller.Entities
{
if (!(this is ICollectionFolder))
{
- Logger.Debug("Query requires post-filtering due to LinkedChildren");
+ Logger.Debug("Query requires post-filtering due to LinkedChildren. Type: " + GetType().Name);
return true;
}
}
- var supportsUserDataQueries = ConfigurationManager.Configuration.SchemaVersion >= 76;
-
if (query.SortBy != null && query.SortBy.Length > 0)
{
- if (!supportsUserDataQueries)
- {
- if (query.SortBy.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked");
- return true;
- }
- if (query.SortBy.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.PlayCount");
- return true;
- }
- if (query.SortBy.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked");
- return true;
- }
- if (query.SortBy.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.IsPlayed");
- return true;
- }
- if (query.SortBy.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.IsUnplayed");
- return true;
- }
- }
-
- if (ConfigurationManager.Configuration.SchemaVersion < 79)
- {
- if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist");
- return true;
- }
- if (query.SortBy.Contains(ItemSortBy.Artist, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.Artist");
- return true;
- }
- }
-
if (query.SortBy.Contains(ItemSortBy.AiredEpisodeOrder, StringComparer.OrdinalIgnoreCase))
{
Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder");
@@ -840,11 +750,6 @@ namespace MediaBrowser.Controller.Entities
Logger.Debug("Query requires post-filtering due to ItemSortBy.Metascore");
return true;
}
- if (query.SortBy.Contains(ItemSortBy.OfficialRating, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.OfficialRating");
- return true;
- }
if (query.SortBy.Contains(ItemSortBy.Players, StringComparer.OrdinalIgnoreCase))
{
Logger.Debug("Query requires post-filtering due to ItemSortBy.Players");
@@ -860,11 +765,6 @@ namespace MediaBrowser.Controller.Entities
Logger.Debug("Query requires post-filtering due to ItemSortBy.SeriesSortName");
return true;
}
- if (query.SortBy.Contains(ItemSortBy.Studio, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.Studio");
- return true;
- }
if (query.SortBy.Contains(ItemSortBy.VideoBitRate, StringComparer.OrdinalIgnoreCase))
{
Logger.Debug("Query requires post-filtering due to ItemSortBy.VideoBitRate");
@@ -878,45 +778,6 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- if (query.PersonIds.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to PersonIds");
- return true;
- }
-
- if (!supportsUserDataQueries)
- {
- if (query.IsLiked.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsLiked");
- return true;
- }
-
- if (query.IsFavoriteOrLiked.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsFavoriteOrLiked");
- return true;
- }
-
- if (query.IsFavorite.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsFavorite");
- return true;
- }
-
- if (query.IsResumable.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsResumable");
- return true;
- }
-
- if (query.IsPlayed.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsPlayed");
- return true;
- }
- }
-
if (query.IsInBoxSet.HasValue)
{
Logger.Debug("Query requires post-filtering due to IsInBoxSet");
@@ -930,30 +791,6 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- if (query.HasImdbId.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to HasImdbId");
- return true;
- }
-
- if (query.HasTmdbId.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to HasTmdbId");
- return true;
- }
-
- if (query.HasTvdbId.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to HasTvdbId");
- return true;
- }
-
- if (query.IsYearMismatched.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsYearMismatched");
- return true;
- }
-
if (query.HasOfficialRating.HasValue)
{
Logger.Debug("Query requires post-filtering due to HasOfficialRating");
@@ -1003,26 +840,6 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- if (query.ImageTypes.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to ImageTypes");
- return true;
- }
-
- // Apply studio filter
- if (query.StudioIds.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to StudioIds");
- return true;
- }
-
- // Apply genre filter
- if (query.GenreIds.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to GenreIds");
- return true;
- }
-
// Apply person filter
if (query.ItemIdsFromPersonFilters != null)
{
@@ -1042,12 +859,6 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- if (query.OfficialRatings.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to OfficialRatings");
- return true;
- }
-
if (query.IsMissing.HasValue)
{
Logger.Debug("Query requires post-filtering due to IsMissing");
@@ -1066,7 +877,7 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- if (UserViewBuilder.CollapseBoxSetItems(query, this, query.User))
+ if (UserViewBuilder.CollapseBoxSetItems(query, this, query.User, ConfigurationManager))
{
Logger.Debug("Query requires post-filtering due to CollapseBoxSetItems");
return true;
@@ -1102,15 +913,6 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- if (ConfigurationManager.Configuration.SchemaVersion < 79)
- {
- if (query.ArtistNames.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to ArtistNames");
- return true;
- }
- }
-
return false;
}
@@ -1183,7 +985,7 @@ namespace MediaBrowser.Controller.Entities
protected QueryResult PostFilterAndSort(IEnumerable items, InternalItemsQuery query)
{
- return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager);
+ return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager, ConfigurationManager);
}
public virtual IEnumerable GetChildren(User user, bool includeLinkedChildren)
@@ -1601,72 +1403,61 @@ namespace MediaBrowser.Controller.Entities
{
return false;
}
+ if (this is Channel)
+ {
+ return false;
+ }
+ if (SourceType != SourceType.Library)
+ {
+ return false;
+ }
return true;
}
}
- public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
+ public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user)
{
if (!SupportsUserDataFromChildren)
{
return;
}
- var recursiveItemCount = 0;
- var unplayed = 0;
-
- double totalPercentPlayed = 0;
-
- var itemsResult = GetItems(new InternalItemsQuery(user)
+ var unplayedQueryResult = await GetItems(new InternalItemsQuery(user)
{
Recursive = true,
IsFolder = false,
- ExcludeLocationTypes = new[] { LocationType.Virtual },
- EnableTotalRecordCount = false
-
- }).Result;
+ IsVirtualItem = false,
+ EnableTotalRecordCount = true,
+ Limit = 0,
+ IsPlayed = false
- var children = itemsResult.Items;
+ }).ConfigureAwait(false);
- // Loop through each recursive child
- foreach (var child in children)
+ var allItemsQueryResult = await GetItems(new InternalItemsQuery(user)
{
- recursiveItemCount++;
-
- var isUnplayed = true;
-
- var itemUserData = UserDataManager.GetUserData(user, child);
-
- // Incrememt totalPercentPlayed
- if (itemUserData != null)
- {
- if (itemUserData.Played)
- {
- totalPercentPlayed += 100;
+ Recursive = true,
+ IsFolder = false,
+ IsVirtualItem = false,
+ EnableTotalRecordCount = true,
+ Limit = 0
- isUnplayed = false;
- }
- else if (itemUserData.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0)
- {
- double itemPercent = itemUserData.PlaybackPositionTicks;
- itemPercent /= child.RunTimeTicks.Value;
- totalPercentPlayed += itemPercent;
- }
- }
+ }).ConfigureAwait(false);
- if (isUnplayed)
- {
- unplayed++;
- }
+ if (itemDto != null)
+ {
+ itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount;
}
- dto.UnplayedItemCount = unplayed;
+ double recursiveItemCount = allItemsQueryResult.TotalRecordCount;
+ double unplayedCount = unplayedQueryResult.TotalRecordCount;
if (recursiveItemCount > 0)
{
- dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
+ var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
+ dto.PlayedPercentage = 100 - unplayedPercentage;
dto.Played = dto.PlayedPercentage.Value >= 100;
+ dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
}
}
}
diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs
index 9ed2400469..317c71529e 100644
--- a/MediaBrowser.Controller/Entities/Game.cs
+++ b/MediaBrowser.Controller/Entities/Game.cs
@@ -7,7 +7,7 @@ using System.Linq;
namespace MediaBrowser.Controller.Entities
{
- public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo
+ public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo
{
public List ThemeSongIds { get; set; }
public List ThemeVideoIds { get; set; }
diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs
index 7c1e88cb1a..45e766c0f0 100644
--- a/MediaBrowser.Controller/Entities/GameGenre.cs
+++ b/MediaBrowser.Controller/Entities/GameGenre.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities
{
@@ -11,10 +12,18 @@ namespace MediaBrowser.Controller.Entities
{
var list = base.GetUserDataKeys();
- list.Insert(0, "GameGenre-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
///
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
index c87d4daaf9..cc5aebb2a4 100644
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ b/MediaBrowser.Controller/Entities/Genre.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities.Audio;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities
{
@@ -15,10 +16,18 @@ namespace MediaBrowser.Controller.Entities
{
var list = base.GetUserDataKeys();
- list.Insert(0, "Genre-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
///
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs
index 244b319bd6..2495b0ccd9 100644
--- a/MediaBrowser.Controller/Entities/IHasUserData.cs
+++ b/MediaBrowser.Controller/Entities/IHasUserData.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Threading.Tasks;
using MediaBrowser.Model.Dto;
namespace MediaBrowser.Controller.Entities
@@ -16,7 +17,7 @@ namespace MediaBrowser.Controller.Entities
/// The dto.
/// The user data.
/// The user.
- void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user);
+ Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user);
bool EnableRememberingTrackSelections { get; }
}
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index 823f4066c4..5faf85b2a0 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -19,6 +19,8 @@ namespace MediaBrowser.Controller.Entities
public User User { get; set; }
+ public BaseItem SimilarTo { get; set; }
+
public bool? IsFolder { get; set; }
public bool? IsFavorite { get; set; }
public bool? IsFavoriteOrLiked { get; set; }
@@ -33,6 +35,7 @@ namespace MediaBrowser.Controller.Entities
public string[] ExcludeTags { get; set; }
public string[] ExcludeInheritedTags { get; set; }
public string[] Genres { get; set; }
+ public string[] Keywords { get; set; }
public bool? IsMissing { get; set; }
public bool? IsUnaired { get; set; }
@@ -43,6 +46,7 @@ namespace MediaBrowser.Controller.Entities
public string NameStartsWith { get; set; }
public string NameLessThan { get; set; }
public string NameContains { get; set; }
+ public string MinSortName { get; set; }
public string PresentationUniqueKey { get; set; }
public string Path { get; set; }
@@ -52,6 +56,7 @@ namespace MediaBrowser.Controller.Entities
public string Person { get; set; }
public string[] PersonIds { get; set; }
public string[] ItemIds { get; set; }
+ public string[] ExcludeItemIds { get; set; }
public string AdjacentTo { get; set; }
public string[] PersonTypes { get; set; }
@@ -60,7 +65,6 @@ namespace MediaBrowser.Controller.Entities
public bool? IsInBoxSet { get; set; }
public bool? IsLocked { get; set; }
public bool? IsPlaceHolder { get; set; }
- public bool? IsYearMismatched { get; set; }
public bool? HasImdbId { get; set; }
public bool? HasOverview { get; set; }
@@ -107,6 +111,7 @@ namespace MediaBrowser.Controller.Entities
internal List ItemIdsFromPersonFilters { get; set; }
public int? ParentIndexNumber { get; set; }
+ public int? ParentIndexNumberNotEquals { get; set; }
public int? IndexNumber { get; set; }
public int? MinParentalRating { get; set; }
public int? MaxParentalRating { get; set; }
@@ -114,6 +119,7 @@ namespace MediaBrowser.Controller.Entities
public bool? IsCurrentSchema { get; set; }
public bool? HasDeadParentId { get; set; }
public bool? IsOffline { get; set; }
+ public bool? IsVirtualItem { get; set; }
public Guid? ParentId { get; set; }
public string[] AncestorIds { get; set; }
@@ -137,6 +143,8 @@ namespace MediaBrowser.Controller.Entities
public bool GroupByPresentationUniqueKey { get; set; }
public bool EnableTotalRecordCount { get; set; }
public bool ForceDirect { get; set; }
+ public Dictionary ExcludeProviderIds { get; set; }
+ public bool EnableGroupByMetadataKey { get; set; }
public InternalItemsQuery()
{
@@ -145,12 +153,14 @@ namespace MediaBrowser.Controller.Entities
AlbumNames = new string[] { };
ArtistNames = new string[] { };
-
+ ExcludeProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
BlockUnratedItems = new UnratedItem[] { };
Tags = new string[] { };
OfficialRatings = new string[] { };
SortBy = new string[] { };
MediaTypes = new string[] { };
+ Keywords = new string[] { };
IncludeItemTypes = new string[] { };
ExcludeItemTypes = new string[] { };
Genres = new string[] { };
@@ -164,6 +174,7 @@ namespace MediaBrowser.Controller.Entities
PersonIds = new string[] { };
ChannelIds = new string[] { };
ItemIds = new string[] { };
+ ExcludeItemIds = new string[] { };
AncestorIds = new string[] { };
TopParentIds = new string[] { };
ExcludeTags = new string[] { };
diff --git a/MediaBrowser.Controller/Entities/IHasKeywords.cs b/MediaBrowser.Controller/Entities/KeywordExtensions.cs
similarity index 57%
rename from MediaBrowser.Controller/Entities/IHasKeywords.cs
rename to MediaBrowser.Controller/Entities/KeywordExtensions.cs
index ab9eb4aeee..5c9afdf3d5 100644
--- a/MediaBrowser.Controller/Entities/IHasKeywords.cs
+++ b/MediaBrowser.Controller/Entities/KeywordExtensions.cs
@@ -1,21 +1,11 @@
using System;
-using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Controller.Entities
{
- public interface IHasKeywords
- {
- ///
- /// Gets or sets the keywords.
- ///
- /// The keywords.
- List Keywords { get; set; }
- }
-
public static class KeywordExtensions
{
- public static void AddKeyword(this IHasKeywords item, string name)
+ public static void AddKeyword(this BaseItem item, string name)
{
if (string.IsNullOrWhiteSpace(name))
{
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
index 09a9d97bcf..4effc162e4 100644
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Movies
///
/// Class BoxSet
///
- public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasDisplayOrder, IHasLookupInfo, IHasShares
+ public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasShares
{
public List Shares { get; set; }
@@ -26,7 +26,6 @@ namespace MediaBrowser.Controller.Entities.Movies
RemoteTrailerIds = new List();
DisplayOrder = ItemSortBy.PremiereDate;
- Keywords = new List();
Shares = new List();
}
@@ -47,12 +46,6 @@ namespace MediaBrowser.Controller.Entities.Movies
/// The remote trailers.
public List RemoteTrailers { get; set; }
- ///
- /// Gets or sets the tags.
- ///
- /// The tags.
- public List Keywords { get; set; }
-
///
/// Gets or sets the display order.
///
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 5882b5f4dd..c7a833c58f 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -8,13 +8,14 @@ using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Providers;
namespace MediaBrowser.Controller.Entities.Movies
{
///
/// Class Movie
///
- public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle
+ public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle
{
public List SpecialFeatureIds { get; set; }
@@ -31,7 +32,6 @@ namespace MediaBrowser.Controller.Entities.Movies
ThemeSongIds = new List();
ThemeVideoIds = new List();
Taglines = new List();
- Keywords = new List();
ProductionLocations = new List();
}
@@ -41,7 +41,6 @@ namespace MediaBrowser.Controller.Entities.Movies
public List LocalTrailerIds { get; set; }
public List RemoteTrailerIds { get; set; }
- public List Keywords { get; set; }
public List RemoteTrailers { get; set; }
@@ -163,5 +162,22 @@ namespace MediaBrowser.Controller.Entities.Movies
return hasChanges;
}
+
+ public override List GetRelatedUrls()
+ {
+ var list = base.GetRelatedUrls();
+
+ var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+ if (!string.IsNullOrWhiteSpace(imdbId))
+ {
+ list.Add(new ExternalUrl
+ {
+ Name = "Trakt",
+ Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
+ });
+ }
+
+ return list;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs
index 2b099e3d5f..8ef0d70bf9 100644
--- a/MediaBrowser.Controller/Entities/Person.cs
+++ b/MediaBrowser.Controller/Entities/Person.cs
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Entities
@@ -22,10 +23,18 @@ namespace MediaBrowser.Controller.Entities
{
var list = base.GetUserDataKeys();
- list.Insert(0, "Person-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
public PersonLookupInfo GetLookupInfo()
{
return GetItemLookupInfo();
diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs
index 3358ccc6fc..de756563d8 100644
--- a/MediaBrowser.Controller/Entities/Photo.cs
+++ b/MediaBrowser.Controller/Entities/Photo.cs
@@ -5,7 +5,7 @@ using System.Runtime.Serialization;
namespace MediaBrowser.Controller.Entities
{
- public class Photo : BaseItem, IHasTags, IHasTaglines
+ public class Photo : BaseItem, IHasTaglines
{
public List Taglines { get; set; }
diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs
index 48ca7bbccc..762798b553 100644
--- a/MediaBrowser.Controller/Entities/Studio.cs
+++ b/MediaBrowser.Controller/Entities/Studio.cs
@@ -2,22 +2,31 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities
{
///
/// Class Studio
///
- public class Studio : BaseItem, IItemByName, IHasTags
+ public class Studio : BaseItem, IItemByName
{
public override List GetUserDataKeys()
{
var list = base.GetUserDataKeys();
- list.Insert(0, "Studio-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
///
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index a4b0b3082a..2dc459239d 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -11,13 +11,25 @@ namespace MediaBrowser.Controller.Entities.TV
///
/// Class Episode
///
- public class Episode : Video, IHasLookupInfo, IHasSeries
- {
- ///
- /// Gets the season in which it aired.
- ///
- /// The aired season.
- public int? AirsBeforeSeasonNumber { get; set; }
+ public class Episode : Video, IHasTrailers, IHasLookupInfo, IHasSeries
+ {
+
+ public Episode()
+ {
+ RemoteTrailers = new List();
+ LocalTrailerIds = new List();
+ RemoteTrailerIds = new List();
+ }
+
+ public List LocalTrailerIds { get; set; }
+ public List RemoteTrailerIds { get; set; }
+ public List RemoteTrailers { get; set; }
+
+ ///
+ /// Gets the season in which it aired.
+ ///
+ /// The aired season.
+ public int? AirsBeforeSeasonNumber { get; set; }
public int? AirsAfterSeasonNumber { get; set; }
public int? AirsBeforeEpisodeNumber { get; set; }
@@ -96,7 +108,13 @@ namespace MediaBrowser.Controller.Entities.TV
var series = Series;
if (series != null && ParentIndexNumber.HasValue && IndexNumber.HasValue)
{
- list.InsertRange(0, series.GetUserDataKeys().Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
+ var seriesUserDataKeys = series.GetUserDataKeys();
+ var take = seriesUserDataKeys.Count;
+ if (seriesUserDataKeys.Count > 1)
+ {
+ take--;
+ }
+ list.InsertRange(0, seriesUserDataKeys.Take(take).Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
}
return list;
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 7fa1b55dea..9a90148443 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -75,6 +75,11 @@ namespace MediaBrowser.Controller.Entities.TV
return list;
}
+ public override int GetChildCount(User user)
+ {
+ return GetChildren(user, true).Count();
+ }
+
///
/// This Episode's Series Instance
///
@@ -128,39 +133,16 @@ namespace MediaBrowser.Controller.Entities.TV
return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
}
- public override bool RequiresRefresh()
- {
- var result = base.RequiresRefresh();
-
- if (!result)
- {
- if (!IsVirtualItem.HasValue)
- {
- return true;
- }
- }
-
- return result;
- }
-
- [IgnoreDataMember]
- public bool? IsVirtualItem { get; set; }
-
[IgnoreDataMember]
public bool IsMissingSeason
{
- get { return (IsVirtualItem ?? DetectIsVirtualItem()) && !IsUnaired; }
+ get { return (IsVirtualItem) && !IsUnaired; }
}
[IgnoreDataMember]
public bool IsVirtualUnaired
{
- get { return (IsVirtualItem ?? DetectIsVirtualItem()) && IsUnaired; }
- }
-
- private bool DetectIsVirtualItem()
- {
- return LocationType == LocationType.Virtual && GetEpisodes().All(i => i.LocationType == LocationType.Virtual);
+ get { return (IsVirtualItem) && IsUnaired; }
}
[IgnoreDataMember]
@@ -196,52 +178,17 @@ namespace MediaBrowser.Controller.Entities.TV
{
var config = user.Configuration;
- return GetEpisodes(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
+ return GetEpisodes(Series, user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
}
- public IEnumerable GetEpisodes(User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
+ public IEnumerable GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
{
- var series = Series;
-
- if (IndexNumber.HasValue && series != null)
- {
- return series.GetEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes);
- }
-
- var episodes = GetRecursiveChildren(user)
- .OfType();
-
- if (series != null && series.ContainsEpisodesWithoutSeasonFolders)
- {
- var seasonNumber = IndexNumber;
- var list = episodes.ToList();
-
- if (seasonNumber.HasValue)
- {
- list.AddRange(series.GetRecursiveChildren(user).OfType()
- .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value));
- }
- else
- {
- list.AddRange(series.GetRecursiveChildren(user).OfType()
- .Where(i => !i.ParentIndexNumber.HasValue));
- }
-
- episodes = list.DistinctBy(i => i.Id);
- }
-
- if (!includeMissingEpisodes)
- {
- episodes = episodes.Where(i => !i.IsMissingEpisode);
- }
- if (!includeVirtualUnairedEpisodes)
- {
- episodes = episodes.Where(i => !i.IsVirtualUnaired);
- }
+ return GetEpisodes(series, user, includeMissingEpisodes, includeVirtualUnairedEpisodes, null);
+ }
- return LibraryManager
- .Sort(episodes, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending)
- .Cast();
+ public IEnumerable GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable allSeriesEpisodes)
+ {
+ return series.GetEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes, allSeriesEpisodes);
}
public IEnumerable GetEpisodes()
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 6c499f6180..1cc496b352 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -9,6 +9,7 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Providers;
using MoreLinq;
namespace MediaBrowser.Controller.Entities.TV
@@ -30,7 +31,6 @@ namespace MediaBrowser.Controller.Entities.TV
RemoteTrailers = new List();
LocalTrailerIds = new List();
RemoteTrailerIds = new List();
- DisplaySpecialsWithSeasons = true;
}
[IgnoreDataMember]
@@ -57,8 +57,6 @@ namespace MediaBrowser.Controller.Entities.TV
}
}
- public bool DisplaySpecialsWithSeasons { get; set; }
-
public List LocalTrailerIds { get; set; }
public List RemoteTrailerIds { get; set; }
@@ -94,10 +92,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
get
{
- return GetRecursiveChildren(i => i is Episode)
- .Select(i => i.DateCreated)
- .OrderByDescending(i => i)
- .FirstOrDefault();
+ return DateLastMediaAdded ?? DateTime.MinValue;
}
}
@@ -106,14 +101,30 @@ namespace MediaBrowser.Controller.Entities.TV
{
get
{
- if (EnablePooling())
+ var userdatakeys = GetUserDataKeys();
+
+ if (userdatakeys.Count > 1)
{
- return GetUserDataKeys().First();
+ return userdatakeys[0];
}
return base.PresentationUniqueKey;
}
}
+ public override int GetChildCount(User user)
+ {
+ var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user)
+ {
+ AncestorWithPresentationUniqueKey = PresentationUniqueKey,
+ IncludeItemTypes = new[] { typeof(Season).Name },
+ SortBy = new[] { ItemSortBy.SortName },
+ IsVirtualItem = false,
+ Limit = 0
+ });
+
+ return result.TotalRecordCount;
+ }
+
///
/// Gets the user data key.
///
@@ -182,27 +193,32 @@ namespace MediaBrowser.Controller.Entities.TV
protected override Task> GetItemsInternal(InternalItemsQuery query)
{
- var user = query.User;
-
- Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
-
- IEnumerable items;
-
if (query.User == null)
{
- items = query.Recursive
- ? GetRecursiveChildren(filter)
- : Children.Where(filter);
+ return base.GetItemsInternal(query);
}
- else
+
+ var user = query.User;
+
+ if (query.Recursive)
{
- items = query.Recursive
- ? GetSeasons(user).Cast().Concat(GetEpisodes(user)).Where(filter)
- : GetSeasons(user).Where(filter);
+ query.AncestorWithPresentationUniqueKey = PresentationUniqueKey;
+ if (query.SortBy.Length == 0)
+ {
+ query.SortBy = new[] { ItemSortBy.SortName };
+ }
+ if (query.IncludeItemTypes.Length == 0)
+ {
+ query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
+ }
+ query.IsVirtualItem = false;
+ return Task.FromResult(LibraryManager.GetItemsResult(query));
}
- var result = PostFilterAndSort(items, query);
+ Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
+ var items = GetSeasons(user).Where(filter);
+ var result = PostFilterAndSort(items, query);
return Task.FromResult(result);
}
@@ -210,33 +226,13 @@ namespace MediaBrowser.Controller.Entities.TV
{
IEnumerable seasons;
- if (EnablePooling())
+ seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
{
- var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
- {
- PresentationUniqueKey = PresentationUniqueKey,
- IncludeItemTypes = new[] { typeof(Series).Name }
- });
+ AncestorWithPresentationUniqueKey = PresentationUniqueKey,
+ IncludeItemTypes = new[] { typeof(Season).Name },
+ SortBy = new[] { ItemSortBy.SortName }
- if (seriesIds.Count > 1)
- {
- seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
- {
- AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
- IncludeItemTypes = new[] { typeof(Season).Name },
- SortBy = new[] { ItemSortBy.SortName }
-
- }).Cast();
- }
- else
- {
- seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType();
- }
- }
- else
- {
- seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType();
- }
+ }).Cast();
if (!includeMissingSeasons)
{
@@ -259,8 +255,18 @@ namespace MediaBrowser.Controller.Entities.TV
public IEnumerable GetEpisodes(User user, bool includeMissing, bool includeVirtualUnaired)
{
- var allEpisodes = GetSeasons(user, true, true)
- .SelectMany(i => i.GetEpisodes(user, includeMissing, includeVirtualUnaired))
+ var allItems = LibraryManager.GetItemList(new InternalItemsQuery(user)
+ {
+ AncestorWithPresentationUniqueKey = PresentationUniqueKey,
+ IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
+ SortBy = new[] { ItemSortBy.SortName }
+
+ }).ToList();
+
+ var allSeriesEpisodes = allItems.OfType().ToList();
+
+ var allEpisodes = allItems.OfType()
+ .SelectMany(i => i.GetEpisodes(this, user, includeMissing, includeVirtualUnaired, allSeriesEpisodes))
.Reverse()
.ToList();
@@ -283,9 +289,6 @@ namespace MediaBrowser.Controller.Entities.TV
var totalItems = seasons.Count + otherItems.Count;
var numComplete = 0;
- refreshOptions = new MetadataRefreshOptions(refreshOptions);
- refreshOptions.IsPostRecursiveRefresh = true;
-
// Refresh current item
await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
@@ -315,7 +318,7 @@ namespace MediaBrowser.Controller.Entities.TV
&& refreshOptions.MetadataRefreshMode != MetadataRefreshMode.FullRefresh
&& !refreshOptions.ReplaceAllMetadata
&& episode.IsMissingEpisode
- && episode.LocationType == Model.Entities.LocationType.Virtual
+ && episode.LocationType == LocationType.Virtual
&& episode.PremiereDate.HasValue
&& (DateTime.UtcNow - episode.PremiereDate.Value).TotalDays > 30)
{
@@ -333,6 +336,8 @@ namespace MediaBrowser.Controller.Entities.TV
progress.Report(percent * 100);
}
+ refreshOptions = new MetadataRefreshOptions(refreshOptions);
+ refreshOptions.IsPostRecursiveRefresh = true;
await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
progress.Report(100);
@@ -345,50 +350,32 @@ namespace MediaBrowser.Controller.Entities.TV
return GetEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
}
- private bool EnablePooling()
+ private IEnumerable GetAllEpisodes(User user)
{
- return false;
+ return LibraryManager.GetItemList(new InternalItemsQuery(user)
+ {
+ AncestorWithPresentationUniqueKey = PresentationUniqueKey,
+ IncludeItemTypes = new[] { typeof(Episode).Name },
+ SortBy = new[] { ItemSortBy.SortName }
+
+ }).Cast();
}
public IEnumerable GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
{
- IEnumerable episodes;
-
- if (EnablePooling())
- {
- var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
- {
- PresentationUniqueKey = PresentationUniqueKey,
- IncludeItemTypes = new[] { typeof(Series).Name }
- });
+ IEnumerable episodes = GetAllEpisodes(user);
- if (seriesIds.Count > 1)
- {
- episodes = LibraryManager.GetItemList(new InternalItemsQuery(user)
- {
- AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
- IncludeItemTypes = new[] { typeof(Episode).Name },
- SortBy = new[] { ItemSortBy.SortName }
+ return GetEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes);
+ }
- }).Cast();
- }
- else
- {
- episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
- {
- IncludeItemTypes = new[] { typeof(Episode).Name }
- }).Cast();
- }
- }
- else
+ public IEnumerable GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable allSeriesEpisodes)
+ {
+ if (allSeriesEpisodes == null)
{
- episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
- {
- IncludeItemTypes = new[] { typeof(Episode).Name }
- }).Cast();
+ return GetEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes);
}
- episodes = FilterEpisodesBySeason(episodes, parentSeason, DisplaySpecialsWithSeasons);
+ var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons);
if (!includeMissingEpisodes)
{
@@ -436,38 +423,31 @@ namespace MediaBrowser.Controller.Entities.TV
public static IEnumerable FilterEpisodesBySeason(IEnumerable episodes, Season parentSeason, bool includeSpecials)
{
var seasonNumber = parentSeason.IndexNumber;
- if (!includeSpecials || (seasonNumber.HasValue && seasonNumber.Value == 0))
- {
- var seasonPresentationKey = parentSeason.PresentationUniqueKey;
+ var seasonPresentationKey = parentSeason.PresentationUniqueKey;
- return episodes.Where(i =>
- {
- if ((i.ParentIndexNumber ?? -1) == seasonNumber)
- {
- return true;
- }
+ var supportSpecialsInSeason = includeSpecials && seasonNumber.HasValue && seasonNumber.Value != 0;
- var season = i.Season;
- return season != null && string.Equals(season.PresentationUniqueKey, seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
- });
- }
- else
+ return episodes.Where(episode =>
{
- var seasonPresentationKey = parentSeason.PresentationUniqueKey;
-
- return episodes.Where(episode =>
+ var currentSeasonNumber = supportSpecialsInSeason ? episode.AiredSeasonNumber : episode.ParentIndexNumber;
+ if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
{
- var currentSeasonNumber = episode.AiredSeasonNumber;
+ return true;
+ }
- if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
- {
- return true;
- }
+ if (!currentSeasonNumber.HasValue && !seasonNumber.HasValue && parentSeason.LocationType == LocationType.Virtual)
+ {
+ return true;
+ }
+ if (!episode.ParentIndexNumber.HasValue)
+ {
var season = episode.Season;
return season != null && string.Equals(season.PresentationUniqueKey, seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
- });
- }
+ }
+
+ return false;
+ });
}
protected override bool GetBlockUnratedValue(UserPolicy config)
@@ -508,5 +488,22 @@ namespace MediaBrowser.Controller.Entities.TV
return hasChanges;
}
+
+ public override List GetRelatedUrls()
+ {
+ var list = base.GetRelatedUrls();
+
+ var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+ if (!string.IsNullOrWhiteSpace(imdbId))
+ {
+ list.Add(new ExternalUrl
+ {
+ Name = "Trakt",
+ Url = string.Format("https://trakt.tv/shows/{0}", imdbId)
+ });
+ }
+
+ return list;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/IHasTags.cs b/MediaBrowser.Controller/Entities/TagExtensions.cs
similarity index 54%
rename from MediaBrowser.Controller/Entities/IHasTags.cs
rename to MediaBrowser.Controller/Entities/TagExtensions.cs
index 45a56009d0..0e1df72cd0 100644
--- a/MediaBrowser.Controller/Entities/IHasTags.cs
+++ b/MediaBrowser.Controller/Entities/TagExtensions.cs
@@ -1,24 +1,11 @@
using System;
-using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Controller.Entities
{
- ///
- /// Interface IHasTags
- ///
- public interface IHasTags
- {
- ///
- /// Gets or sets the tags.
- ///
- /// The tags.
- List Tags { get; set; }
- }
-
public static class TagExtensions
{
- public static void AddTag(this IHasTags item, string name)
+ public static void AddTag(this BaseItem item, string name)
{
if (string.IsNullOrWhiteSpace(name))
{
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
index 3be2fc6243..eab5ab6794 100644
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ b/MediaBrowser.Controller/Entities/Trailer.cs
@@ -5,13 +5,14 @@ using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Model.Providers;
namespace MediaBrowser.Controller.Entities
{
///
/// Class Trailer
///
- public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo
+ public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo
{
public List ProductionLocations { get; set; }
@@ -30,8 +31,6 @@ namespace MediaBrowser.Controller.Entities
public List RemoteTrailers { get; set; }
- public List Keywords { get; set; }
-
[IgnoreDataMember]
public bool IsLocalTrailer
{
@@ -110,5 +109,22 @@ namespace MediaBrowser.Controller.Entities
return hasChanges;
}
+
+ public override List GetRelatedUrls()
+ {
+ var list = base.GetRelatedUrls();
+
+ var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+ if (!string.IsNullOrWhiteSpace(imdbId))
+ {
+ list.Add(new ExternalUrl
+ {
+ Name = "Trakt",
+ Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
+ });
+ }
+
+ return list;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs
index 37c4c91b17..8e6f11c2ce 100644
--- a/MediaBrowser.Controller/Entities/UserRootFolder.cs
+++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs
@@ -38,6 +38,11 @@ namespace MediaBrowser.Controller.Entities
return PostFilterAndSort(result.Where(filter), query);
}
+ public override int GetChildCount(User user)
+ {
+ return GetChildren(user, true).Count();
+ }
+
[IgnoreDataMember]
protected override bool SupportsShortcutChildren
{
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index e40d9ca381..35375e7e66 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -45,6 +45,11 @@ namespace MediaBrowser.Controller.Entities
return list;
}
+ public override int GetChildCount(User user)
+ {
+ return GetChildren(user, true).Count();
+ }
+
protected override Task> GetItemsInternal(InternalItemsQuery query)
{
var parent = this as Folder;
@@ -58,7 +63,7 @@ namespace MediaBrowser.Controller.Entities
parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
}
- return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, CollectionManager, PlaylistManager)
+ return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, ConfigurationManager, PlaylistManager)
.GetUserItems(parent, this, ViewType, query);
}
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index d4a8b07305..175a7240c6 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -18,6 +18,8 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Controller.Entities
{
@@ -30,10 +32,10 @@ namespace MediaBrowser.Controller.Entities
private readonly ILogger _logger;
private readonly IUserDataManager _userDataManager;
private readonly ITVSeriesManager _tvSeriesManager;
- private readonly ICollectionManager _collectionManager;
+ private readonly IServerConfigurationManager _config;
private readonly IPlaylistManager _playlistManager;
- public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, ICollectionManager collectionManager, IPlaylistManager playlistManager)
+ public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, IServerConfigurationManager config, IPlaylistManager playlistManager)
{
_userViewManager = userViewManager;
_liveTvManager = liveTvManager;
@@ -42,7 +44,7 @@ namespace MediaBrowser.Controller.Entities
_logger = logger;
_userDataManager = userDataManager;
_tvSeriesManager = tvSeriesManager;
- _collectionManager = collectionManager;
+ _config = config;
_playlistManager = playlistManager;
}
@@ -159,7 +161,7 @@ namespace MediaBrowser.Controller.Entities
return await GetTvGenres(queryParent, user, query).ConfigureAwait(false);
case SpecialFolder.TvGenre:
- return await GetTvGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
+ return GetTvGenreItems(queryParent, displayParent, user, query);
case SpecialFolder.TvResume:
return GetTvResume(queryParent, user, query);
@@ -332,13 +334,14 @@ namespace MediaBrowser.Controller.Entities
private QueryResult GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ var items = parent.QueryRecursive(new InternalItemsQuery(user)
{
Recursive = true,
ParentId = parent.Id,
- IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
+ EnableTotalRecordCount = false
- }).Cast();
+ }).Items.Cast();
var artists = _libraryManager.GetAlbumArtists(items);
@@ -347,13 +350,14 @@ namespace MediaBrowser.Controller.Entities
private QueryResult GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ var items = parent.QueryRecursive(new InternalItemsQuery(user)
{
Recursive = true,
ParentId = parent.Id,
- IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name }
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name },
+ EnableTotalRecordCount = false
- }).Cast();
+ }).Items.Cast();
var artists = _libraryManager.GetArtists(items);
@@ -362,13 +366,14 @@ namespace MediaBrowser.Controller.Entities
private QueryResult GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ var items = parent.QueryRecursive(new InternalItemsQuery(user)
{
Recursive = true,
ParentId = parent.Id,
- IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
+ EnableTotalRecordCount = false
- }).Cast();
+ }).Items.Cast();
var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
@@ -545,7 +550,7 @@ namespace MediaBrowser.Controller.Entities
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Movie).Name };
- return _libraryManager.GetItemsResult(query);
+ return ConvertToResult(_libraryManager.GetItemList(query));
}
private QueryResult GetMovieResume(Folder parent, User user, InternalItemsQuery query)
@@ -559,7 +564,17 @@ namespace MediaBrowser.Controller.Entities
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Movie).Name };
- return _libraryManager.GetItemsResult(query);
+ return ConvertToResult(_libraryManager.GetItemList(query));
+ }
+
+ private QueryResult ConvertToResult(IEnumerable items)
+ {
+ var arr = items.ToArray();
+ return new QueryResult
+ {
+ Items = arr,
+ TotalRecordCount = arr.Length
+ };
}
private async Task> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
@@ -660,8 +675,9 @@ namespace MediaBrowser.Controller.Entities
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Episode).Name };
+ query.ExcludeLocationTypes = new[] { LocationType.Virtual };
- return _libraryManager.GetItemsResult(query);
+ return ConvertToResult(_libraryManager.GetItemList(query));
}
private QueryResult GetTvNextUp(Folder parent, InternalItemsQuery query)
@@ -690,7 +706,7 @@ namespace MediaBrowser.Controller.Entities
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Episode).Name };
- return _libraryManager.GetItemsResult(query);
+ return ConvertToResult(_libraryManager.GetItemList(query));
}
private QueryResult GetTvSeries(Folder parent, User user, InternalItemsQuery query)
@@ -737,7 +753,7 @@ namespace MediaBrowser.Controller.Entities
return GetResult(genres, parent, query);
}
- private async Task> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ private QueryResult GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
{
query.Recursive = true;
query.ParentId = queryParent.Id;
@@ -766,7 +782,7 @@ namespace MediaBrowser.Controller.Entities
{
items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager));
- return PostFilterAndSort(items, queryParent, null, query, _libraryManager);
+ return PostFilterAndSort(items, queryParent, null, query, _libraryManager, _config);
}
public static bool FilterItem(BaseItem item, InternalItemsQuery query)
@@ -779,14 +795,15 @@ namespace MediaBrowser.Controller.Entities
int? totalRecordLimit,
InternalItemsQuery query)
{
- return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager);
+ return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager, _config);
}
public static QueryResult PostFilterAndSort(IEnumerable items,
BaseItem queryParent,
int? totalRecordLimit,
InternalItemsQuery query,
- ILibraryManager libraryManager)
+ ILibraryManager libraryManager,
+ IServerConfigurationManager configurationManager)
{
var user = query.User;
@@ -795,7 +812,7 @@ namespace MediaBrowser.Controller.Entities
query.IsVirtualUnaired,
query.IsUnaired);
- items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user);
+ items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user, configurationManager);
// This must be the last filter
if (!string.IsNullOrEmpty(query.AdjacentTo))
@@ -809,14 +826,15 @@ namespace MediaBrowser.Controller.Entities
public static IEnumerable CollapseBoxSetItemsIfNeeded(IEnumerable items,
InternalItemsQuery query,
BaseItem queryParent,
- User user)
+ User user,
+ IServerConfigurationManager configurationManager)
{
if (items == null)
{
throw new ArgumentNullException("items");
}
- if (CollapseBoxSetItems(query, queryParent, user))
+ if (CollapseBoxSetItems(query, queryParent, user, configurationManager))
{
items = BaseItem.CollectionManager.CollapseItemsWithinBoxSets(items, user);
}
@@ -849,7 +867,8 @@ namespace MediaBrowser.Controller.Entities
public static bool CollapseBoxSetItems(InternalItemsQuery query,
BaseItem queryParent,
- User user)
+ User user,
+ IServerConfigurationManager configurationManager)
{
// Could end up stuck in a loop like this
if (queryParent is BoxSet)
@@ -861,7 +880,7 @@ namespace MediaBrowser.Controller.Entities
if (!param.HasValue)
{
- if (user != null && !user.Configuration.GroupMoviesIntoBoxSets)
+ if (user != null && !configurationManager.Configuration.EnableGroupingIntoCollections)
{
return false;
}
@@ -992,11 +1011,6 @@ namespace MediaBrowser.Controller.Entities
return false;
}
- if (request.IsYearMismatched.HasValue)
- {
- return false;
- }
-
if (!string.IsNullOrWhiteSpace(request.Person))
{
return false;
@@ -1415,16 +1429,6 @@ namespace MediaBrowser.Controller.Entities
}
}
- if (query.IsYearMismatched.HasValue)
- {
- var filterValue = query.IsYearMismatched.Value;
-
- if (IsYearMismatched(item, libraryManager) != filterValue)
- {
- return false;
- }
- }
-
if (query.HasOfficialRating.HasValue)
{
var filterValue = query.HasOfficialRating.Value;
@@ -1658,12 +1662,7 @@ namespace MediaBrowser.Controller.Entities
var tags = query.Tags;
if (tags.Length > 0)
{
- var hasTags = item as IHasTags;
- if (hasTags == null)
- {
- return false;
- }
- if (!tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
+ if (!tags.Any(v => item.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
{
return false;
}
@@ -1976,34 +1975,6 @@ namespace MediaBrowser.Controller.Entities
return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, sortName, CancellationToken.None);
}
- public static bool IsYearMismatched(BaseItem item, ILibraryManager libraryManager)
- {
- if (item.ProductionYear.HasValue)
- {
- var path = item.Path;
-
- if (!string.IsNullOrEmpty(path))
- {
- var info = libraryManager.ParseName(Path.GetFileName(path));
- var yearInName = info.Year;
-
- // Go up a level if we didn't get a year
- if (!yearInName.HasValue)
- {
- info = libraryManager.ParseName(Path.GetFileName(Path.GetDirectoryName(path)));
- yearInName = info.Year;
- }
-
- if (yearInName.HasValue)
- {
- return yearInName.Value != item.ProductionYear.Value;
- }
- }
- }
-
- return false;
- }
-
public static IEnumerable FilterForAdjacency(IEnumerable items, string adjacentToId)
{
var list = items.ToList();
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 6a9d7cb511..73c893dd6e 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -21,7 +21,6 @@ namespace MediaBrowser.Controller.Entities
///
public class Video : BaseItem,
IHasAspectRatio,
- IHasTags,
ISupportsPlaceHolders,
IHasMediaSources,
IHasShortOverview,
@@ -59,10 +58,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- public long? Size { get; set; }
- public string Container { get; set; }
public int? TotalBitrate { get; set; }
- public string ShortOverview { get; set; }
public ExtraType? ExtraType { get; set; }
///
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index 65eed1a235..f4c0e76581 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Model.System;
using System;
using System.Collections.Generic;
using System.Net;
+using System.Threading.Tasks;
namespace MediaBrowser.Controller
{
@@ -17,7 +18,7 @@ namespace MediaBrowser.Controller
/// Gets the system info.
///
/// SystemInfo.
- SystemInfo GetSystemInfo();
+ Task GetSystemInfo();
///
/// Gets a value indicating whether [supports automatic run at startup].
@@ -65,13 +66,13 @@ namespace MediaBrowser.Controller
/// Gets the local ip address.
///
/// The local ip address.
- List LocalIpAddresses { get; }
+ Task> GetLocalIpAddresses();
///
/// Gets the local API URL.
///
/// The local API URL.
- string LocalApiUrl { get; }
+ Task GetLocalApiUrl();
///
/// Gets the local API URL.
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 936b97c6e2..4e641b0056 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Dto;
namespace MediaBrowser.Controller.Library
{
@@ -150,13 +151,6 @@ namespace MediaBrowser.Controller.Library
/// BaseItem.
BaseItem GetItemById(Guid id);
- ///
- /// Gets the memory item by identifier.
- ///
- /// The identifier.
- /// BaseItem.
- BaseItem GetMemoryItemById(Guid id);
-
///
/// Gets the intros.
///
@@ -574,5 +568,12 @@ namespace MediaBrowser.Controller.Library
void RemoveVirtualFolder(string name, bool refreshLibrary);
void AddMediaPath(string virtualFolderName, string path);
void RemoveMediaPath(string virtualFolderName, string path);
+
+ QueryResult> GetGenres(InternalItemsQuery query);
+ QueryResult> GetMusicGenres(InternalItemsQuery query);
+ QueryResult> GetGameGenres(InternalItemsQuery query);
+ QueryResult> GetStudios(InternalItemsQuery query);
+ QueryResult> GetArtists(InternalItemsQuery query);
+ QueryResult> GetAlbumArtists(InternalItemsQuery query);
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs
index e2358650be..86c52c4c31 100644
--- a/MediaBrowser.Controller/Library/IUserDataManager.cs
+++ b/MediaBrowser.Controller/Library/IUserDataManager.cs
@@ -40,7 +40,9 @@ namespace MediaBrowser.Controller.Library
/// The item.
/// The user.
/// UserItemDataDto.
- UserItemDataDto GetUserDataDto(IHasUserData item, User user);
+ Task GetUserDataDto(IHasUserData item, User user);
+
+ Task GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user);
///
/// Get all user data for the given user
diff --git a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
index f5048bdda0..5ecd70cc5c 100644
--- a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
+++ b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
@@ -15,5 +15,6 @@ namespace MediaBrowser.Controller.LiveTv
Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken);
Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings);
Task> GetLineups(ListingsProviderInfo info, string country, string location);
+ Task> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index a4bd32fffe..fe69b38cb0 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Events;
namespace MediaBrowser.Controller.LiveTv
{
@@ -344,6 +345,13 @@ namespace MediaBrowser.Controller.LiveTv
/// if set to true [validate listings].
/// Task.
Task SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings);
+
+ void DeleteListingsProvider(string id);
+
+ Task SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber);
+
+ TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List mappings, List providerChannels);
+
///
/// Gets the lineups.
///
@@ -385,5 +393,15 @@ namespace MediaBrowser.Controller.LiveTv
List GetSatIniMappings();
Task> GetSatChannelScanResult(TunerHostInfo info, CancellationToken cancellationToken);
+
+ Task> GetChannelsForListingsProvider(string id, CancellationToken cancellationToken);
+ Task> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken);
+
+ List ListingProviders { get;}
+
+ event EventHandler> SeriesTimerCancelled;
+ event EventHandler> TimerCancelled;
+ event EventHandler> TimerCreated;
+ event EventHandler> SeriesTimerCreated;
}
}
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
index 4ef4847a34..d7d8336d02 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
@@ -226,4 +226,23 @@ namespace MediaBrowser.Controller.LiveTv
/// Task.
Task ResetTuner(string id, CancellationToken cancellationToken);
}
+
+ public interface ISupportsNewTimerIds
+ {
+ ///
+ /// Creates the timer asynchronous.
+ ///
+ /// The information.
+ /// The cancellation token.
+ /// Task.
+ Task CreateTimer(TimerInfo info, CancellationToken cancellationToken);
+
+ ///
+ /// Creates the series timer asynchronous.
+ ///
+ /// The information.
+ /// The cancellation token.
+ /// Task.
+ Task CreateSeriesTimer(SeriesTimerInfo info, CancellationToken cancellationToken);
+ }
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
index cc30709db2..74c9932480 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
@@ -7,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Providers;
namespace MediaBrowser.Controller.LiveTv
{
@@ -235,5 +236,25 @@ namespace MediaBrowser.Controller.LiveTv
return false;
}
}
+
+ public override List GetRelatedUrls()
+ {
+ var list = base.GetRelatedUrls();
+
+ var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+ if (!string.IsNullOrWhiteSpace(imdbId))
+ {
+ if (IsMovie)
+ {
+ list.Add(new ExternalUrl
+ {
+ Name = "Trakt",
+ Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
+ });
+ }
+ }
+
+ return list;
+ }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs
new file mode 100644
index 0000000000..0e1a054754
--- /dev/null
+++ b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.LiveTv
+{
+ public class TimerEventInfo
+ {
+ public string Id { get; set; }
+ public string ProgramId { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs
new file mode 100644
index 0000000000..da0527eeaf
--- /dev/null
+++ b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.LiveTv
+{
+ public class TunerChannelMapping
+ {
+ public string Name { get; set; }
+ public string Number { get; set; }
+ public string ProviderChannelNumber { get; set; }
+ public string ProviderChannelName { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index bc28ec0155..0462117cb5 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -142,7 +142,7 @@
-
+
@@ -154,7 +154,6 @@
-
@@ -177,6 +176,7 @@
+
@@ -218,7 +218,9 @@
+
+
@@ -290,21 +292,17 @@
-
-
-
-
@@ -330,12 +328,8 @@
-
-
-
-
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
index c87ac4e734..44b7417553 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Model.Dlna;
+using System.Linq;
+using MediaBrowser.Model.Dlna;
namespace MediaBrowser.Controller.MediaEncoding
{
@@ -74,7 +75,7 @@ namespace MediaBrowser.Controller.MediaEncoding
Level = info.VideoLevel;
ItemId = info.ItemId;
MediaSourceId = info.MediaSourceId;
- AudioCodec = info.AudioCodec;
+ AudioCodec = info.TargetAudioCodec;
MaxAudioChannels = info.MaxAudioChannels;
AudioBitRate = info.AudioBitrate;
AudioSampleRate = info.TargetAudioSampleRate;
diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
index 7c3959f6e8..62377b19e0 100644
--- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
@@ -13,18 +13,14 @@ namespace MediaBrowser.Controller.MediaEncoding
///
public interface IMediaEncoder : ITranscoderSupport
{
+ string EncoderLocationType { get; }
+
///
/// Gets the encoder path.
///
/// The encoder path.
string EncoderPath { get; }
- ///
- /// Gets the version.
- ///
- /// The version.
- string Version { get; }
-
///
/// Supportses the decoder.
///
@@ -66,12 +62,12 @@ namespace MediaBrowser.Controller.MediaEncoding
/// The maximum width.
/// The cancellation token.
/// Task.
- Task ExtractVideoImagesOnInterval(string[] inputFiles,
- MediaProtocol protocol,
- Video3DFormat? threedFormat,
- TimeSpan interval,
- string targetDirectory,
- string filenamePrefix,
+ Task ExtractVideoImagesOnInterval(string[] inputFiles,
+ MediaProtocol protocol,
+ Video3DFormat? threedFormat,
+ TimeSpan interval,
+ string targetDirectory,
+ string filenamePrefix,
int? maxWidth,
CancellationToken cancellationToken);
@@ -134,5 +130,9 @@ namespace MediaBrowser.Controller.MediaEncoding
/// The path.
/// System.String.
string EscapeSubtitleFilterPath(string path);
+
+ Task Init();
+
+ Task UpdateEncoderPath(string path, string pathType);
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
index e538b84d8f..44489cbf58 100644
--- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
@@ -10,13 +10,6 @@ namespace MediaBrowser.Controller.MediaEncoding
///
/// Gets the subtitles.
///
- /// The item identifier.
- /// The media source identifier.
- /// Index of the subtitle stream.
- /// The output format.
- /// The start time ticks.
- /// The end time ticks.
- /// The cancellation token.
/// Task{Stream}.
Task GetSubtitles(string itemId,
string mediaSourceId,
@@ -24,6 +17,7 @@ namespace MediaBrowser.Controller.MediaEncoding
string outputFormat,
long startTimeTicks,
long? endTimeTicks,
+ bool preserveOriginalTimestamps,
CancellationToken cancellationToken);
///
diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs
index 526bf4be2e..cd7ee603e3 100644
--- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs
+++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs
@@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.Net
/// The response headers.
/// if set to true [is head request].
/// System.Object.
- object GetStaticResult(IRequest requestContext,
+ Task GetStaticResult(IRequest requestContext,
Guid cacheKey,
DateTime? lastDateModified,
TimeSpan? cacheDuration,
@@ -94,7 +94,7 @@ namespace MediaBrowser.Controller.Net
/// The request context.
/// The options.
/// System.Object.
- object GetStaticResult(IRequest requestContext, StaticResultOptions options);
+ Task GetStaticResult(IRequest requestContext, StaticResultOptions options);
///
/// Gets the static file result.
@@ -103,7 +103,7 @@ namespace MediaBrowser.Controller.Net
/// The path.
/// The file share.
/// System.Object.
- object GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read);
+ Task GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read);
///
/// Gets the static file result.
@@ -111,7 +111,7 @@ namespace MediaBrowser.Controller.Net
/// The request context.
/// The options.
/// System.Object.
- object GetStaticFileResult(IRequest requestContext,
+ Task GetStaticFileResult(IRequest requestContext,
StaticFileResultOptions options);
}
}
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index 7bcc36958a..78138999c5 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Controller.Persistence
@@ -81,7 +82,7 @@ namespace MediaBrowser.Controller.Persistence
/// The chapters.
/// The cancellation token.
/// Task.
- Task SaveChapters(Guid id, IEnumerable chapters, CancellationToken cancellationToken);
+ Task SaveChapters(Guid id, List chapters, CancellationToken cancellationToken);
///
/// Gets the media streams.
@@ -97,7 +98,7 @@ namespace MediaBrowser.Controller.Persistence
/// The streams.
/// The cancellation token.
/// Task.
- Task SaveMediaStreams(Guid id, IEnumerable streams, CancellationToken cancellationToken);
+ Task SaveMediaStreams(Guid id, List streams, CancellationToken cancellationToken);
///
/// Gets the item ids.
@@ -153,7 +154,7 @@ namespace MediaBrowser.Controller.Persistence
///
/// The query.
/// List<BaseItem>.
- IEnumerable GetItemList(InternalItemsQuery query);
+ List GetItemList(InternalItemsQuery query);
///
/// Updates the inherited values.
@@ -161,6 +162,13 @@ namespace MediaBrowser.Controller.Persistence
/// The cancellation token.
/// Task.
Task UpdateInheritedValues(CancellationToken cancellationToken);
+
+ QueryResult> GetGenres(InternalItemsQuery query);
+ QueryResult> GetMusicGenres(InternalItemsQuery query);
+ QueryResult> GetGameGenres(InternalItemsQuery query);
+ QueryResult> GetStudios(InternalItemsQuery query);
+ QueryResult> GetArtists(InternalItemsQuery query);
+ QueryResult> GetAlbumArtists(InternalItemsQuery query);
}
}
diff --git a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
index 2e165f4163..ca4dc97513 100644
--- a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
@@ -29,6 +29,8 @@ namespace MediaBrowser.Controller.Persistence
/// Task{UserItemData}.
UserItemData GetUserData(Guid userId, string key);
+ UserItemData GetUserData(Guid userId, List keys);
+
///
/// Return all user data associated with the given user
///
diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index 1014fc2ee9..a783910e34 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -803,11 +803,7 @@ namespace MediaBrowser.Controller.Providers
{
using (var subtree = reader.ReadSubtree())
{
- var hasTags = item as IHasTags;
- if (hasTags != null)
- {
- FetchFromTagsNode(subtree, hasTags);
- }
+ FetchFromTagsNode(subtree, item);
}
break;
}
@@ -816,11 +812,7 @@ namespace MediaBrowser.Controller.Providers
{
using (var subtree = reader.ReadSubtree())
{
- var hasTags = item as IHasKeywords;
- if (hasTags != null)
- {
- FetchFromKeywordsNode(subtree, hasTags);
- }
+ FetchFromKeywordsNode(subtree, item);
}
break;
}
@@ -1070,7 +1062,7 @@ namespace MediaBrowser.Controller.Providers
}
}
- private void FetchFromTagsNode(XmlReader reader, IHasTags item)
+ private void FetchFromTagsNode(XmlReader reader, BaseItem item)
{
reader.MoveToContent();
@@ -1099,7 +1091,7 @@ namespace MediaBrowser.Controller.Providers
}
}
- private void FetchFromKeywordsNode(XmlReader reader, IHasKeywords item)
+ private void FetchFromKeywordsNode(XmlReader reader, BaseItem item)
{
reader.MoveToContent();
diff --git a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs b/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs
deleted file mode 100644
index bfdd1dbf3a..0000000000
--- a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace MediaBrowser.Controller.Providers
-{
- public interface IItemIdentityConverter { }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs b/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs
deleted file mode 100644
index 6b403bb55f..0000000000
--- a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace MediaBrowser.Controller.Providers
-{
- public interface IItemIdentityProvider { }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 57e4ff3200..3eefa9647d 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -97,13 +97,11 @@ namespace MediaBrowser.Controller.Providers
///
/// The image providers.
/// The metadata services.
- /// The identity providers.
- /// The identity converters.
/// The metadata providers.
/// The savers.
/// The image savers.
/// The external ids.
- void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable identityProviders, IEnumerable identityConverters, IEnumerable metadataProviders,
+ void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders,
IEnumerable savers,
IEnumerable imageSavers,
IEnumerable externalIds);
@@ -135,7 +133,7 @@ namespace MediaBrowser.Controller.Providers
///
/// The item.
/// IEnumerable{ExternalUrl}.
- IEnumerable GetExternalUrls(IHasProviderIds item);
+ IEnumerable GetExternalUrls(BaseItem item);
///
/// Gets the external identifier infos.
@@ -190,21 +188,5 @@ namespace MediaBrowser.Controller.Providers
/// The cancellation token.
/// Task{HttpResponseInfo}.
Task GetSearchImage(string providerName, string url, CancellationToken cancellationToken);
-
- ///
- /// Gets the item identity providers.
- ///
- /// The type of the t lookup information.
- /// IEnumerable<IItemIdentityProvider<TLookupInfo, TIdentity>>.
- IEnumerable> GetItemIdentityProviders()
- where TLookupInfo : ItemLookupInfo;
-
- ///
- /// Gets the item identity converters.
- ///
- /// The type of the t lookup information.
- /// IEnumerable<IItemIdentityConverter<TIdentity>>.
- IEnumerable> GetItemIdentityConverters()
- where TLookupInfo : ItemLookupInfo;
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Providers/IProviderRepository.cs b/MediaBrowser.Controller/Providers/IProviderRepository.cs
deleted file mode 100644
index 891275d775..0000000000
--- a/MediaBrowser.Controller/Providers/IProviderRepository.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using MediaBrowser.Controller.Persistence;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Providers
-{
- public interface IProviderRepository : IRepository
- {
- ///
- /// Gets the metadata status.
- ///
- /// The item identifier.
- /// MetadataStatus.
- MetadataStatus GetMetadataStatus(Guid itemId);
-
- ///
- /// Saves the metadata status.
- ///
- /// The status.
- /// The cancellation token.
- /// Task.
- Task SaveMetadataStatus(MetadataStatus status, CancellationToken cancellationToken);
- }
-}
diff --git a/MediaBrowser.Controller/Providers/ISeriesOrderManager.cs b/MediaBrowser.Controller/Providers/ISeriesOrderManager.cs
deleted file mode 100644
index 970f7a7be5..0000000000
--- a/MediaBrowser.Controller/Providers/ISeriesOrderManager.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Providers
-{
- public interface ISeriesOrderManager
- {
- Task FindSeriesIndex(string orderType, string seriesName);
- void AddParts(IEnumerable orderProviders);
- }
-}
diff --git a/MediaBrowser.Controller/Providers/ISeriesOrderProvider.cs b/MediaBrowser.Controller/Providers/ISeriesOrderProvider.cs
deleted file mode 100644
index ee0f3c197f..0000000000
--- a/MediaBrowser.Controller/Providers/ISeriesOrderProvider.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Providers
-{
- public interface ISeriesOrderProvider
- {
- string OrderType { get; }
- Task FindSeriesIndex(string seriesName);
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Providers/ItemIdentifier.cs b/MediaBrowser.Controller/Providers/ItemIdentifier.cs
deleted file mode 100644
index bbc6dd76cd..0000000000
--- a/MediaBrowser.Controller/Providers/ItemIdentifier.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Providers
-{
- public static class ItemIdentifier
- where TLookupInfo : ItemLookupInfo
- {
- public static async Task FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken)
- {
- var providers = providerManager.GetItemIdentityProviders();
- var converters = providerManager.GetItemIdentityConverters().ToList();
-
- foreach (var provider in providers)
- {
- await provider.Identify(item);
- }
-
- bool changesMade = true;
-
- while (changesMade)
- {
- changesMade = false;
-
- foreach (var converter in converters)
- {
- if (await converter.Convert(item))
- {
- changesMade = true;
- }
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Providers/ItemIdentities.cs b/MediaBrowser.Controller/Providers/ItemIdentities.cs
deleted file mode 100644
index 48316d0f44..0000000000
--- a/MediaBrowser.Controller/Providers/ItemIdentities.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Providers
-{
- public interface IItemIdentityProvider : IItemIdentityProvider
- where TLookupInfo : ItemLookupInfo
- {
- Task Identify(TLookupInfo info);
- }
-
- public interface IItemIdentityConverter : IItemIdentityConverter
- where TLookupInfo : ItemLookupInfo
- {
- Task Convert(TLookupInfo info);
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Providers/ItemInfo.cs b/MediaBrowser.Controller/Providers/ItemInfo.cs
index d16a730286..63cc48058f 100644
--- a/MediaBrowser.Controller/Providers/ItemInfo.cs
+++ b/MediaBrowser.Controller/Providers/ItemInfo.cs
@@ -1,3 +1,4 @@
+using System;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
@@ -5,10 +6,6 @@ namespace MediaBrowser.Controller.Providers
{
public class ItemInfo
{
- public ItemInfo()
- {
- }
-
public ItemInfo(IHasMetadata item)
{
Path = item.Path;
@@ -21,8 +18,11 @@ namespace MediaBrowser.Controller.Providers
VideoType = video.VideoType;
IsPlaceHolder = video.IsPlaceHolder;
}
+
+ ItemType = item.GetType();
}
+ public Type ItemType { get; set; }
public string Path { get; set; }
public string ContainingFolderPath { get; set; }
public VideoType VideoType { get; set; }
diff --git a/MediaBrowser.Controller/Providers/MetadataStatus.cs b/MediaBrowser.Controller/Providers/MetadataStatus.cs
deleted file mode 100644
index b19377a680..0000000000
--- a/MediaBrowser.Controller/Providers/MetadataStatus.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Providers
-{
- public class MetadataStatus
- {
- ///
- /// Gets or sets the item identifier.
- ///
- /// The item identifier.
- public Guid ItemId { get; set; }
-
- ///
- /// Gets or sets the date last metadata refresh.
- ///
- /// The date last metadata refresh.
- public DateTime? DateLastMetadataRefresh { get; set; }
-
- ///
- /// Gets or sets the date last images refresh.
- ///
- /// The date last images refresh.
- public DateTime? DateLastImagesRefresh { get; set; }
-
- public DateTime? ItemDateModified { get; set; }
-
- public bool IsDirty { get; private set; }
-
- public void SetDateLastMetadataRefresh(DateTime? date)
- {
- if (date != DateLastMetadataRefresh)
- {
- IsDirty = true;
- }
-
- DateLastMetadataRefresh = date;
- }
-
- public void SetDateLastImagesRefresh(DateTime? date)
- {
- if (date != DateLastImagesRefresh)
- {
- IsDirty = true;
- }
-
- DateLastImagesRefresh = date;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index fa74c57499..6659d15530 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -315,9 +315,8 @@ namespace MediaBrowser.Controller.Session
///
/// Revokes the user tokens.
///
- /// The user identifier.
/// Task.
- Task RevokeUserTokens(string userId);
+ Task RevokeUserTokens(string userId, string currentAccessToken);
///
/// Revokes the token.
diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
index af833a85cf..0a15491b67 100644
--- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
@@ -160,7 +160,7 @@ namespace MediaBrowser.Dlna.Didl
var contentFeatureList = new ContentFeatureBuilder(_profile).BuildVideoHeader(streamInfo.Container,
streamInfo.VideoCodec,
- streamInfo.AudioCodec,
+ streamInfo.TargetAudioCodec,
targetWidth,
targetHeight,
streamInfo.TargetVideoBitDepth,
@@ -307,7 +307,7 @@ namespace MediaBrowser.Dlna.Didl
}
var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container,
- streamInfo.AudioCodec,
+ streamInfo.TargetAudioCodec,
streamInfo.VideoCodec,
streamInfo.TargetAudioBitrate,
targetWidth,
@@ -441,7 +441,7 @@ namespace MediaBrowser.Dlna.Didl
}
var mediaProfile = _profile.GetAudioMediaProfile(streamInfo.Container,
- streamInfo.AudioCodec,
+ streamInfo.TargetAudioCodec,
targetChannels,
targetAudioBitrate);
@@ -846,7 +846,7 @@ namespace MediaBrowser.Dlna.Didl
if (item is Video)
{
- var userData = _userDataManager.GetUserDataDto(item, _user);
+ var userData = _userDataManager.GetUserDataDto(item, _user).Result;
playbackPercentage = Convert.ToInt32(userData.PlayedPercentage ?? 0);
if (playbackPercentage >= 100 || userData.Played)
@@ -856,7 +856,7 @@ namespace MediaBrowser.Dlna.Didl
}
else if (item is Series || item is Season || item is BoxSet)
{
- var userData = _userDataManager.GetUserDataDto(item, _user);
+ var userData = _userDataManager.GetUserDataDto(item, _user).Result;
if (userData.Played)
{
@@ -1015,17 +1015,17 @@ namespace MediaBrowser.Dlna.Didl
int? width = null;
int? height = null;
- //try
- //{
- // var size = _imageProcessor.GetImageSize(imageInfo);
+ try
+ {
+ var size = _imageProcessor.GetImageSize(imageInfo);
- // width = Convert.ToInt32(size.Width);
- // height = Convert.ToInt32(size.Height);
- //}
- //catch
- //{
+ width = Convert.ToInt32(size.Width);
+ height = Convert.ToInt32(size.Height);
+ }
+ catch
+ {
- //}
+ }
var inputFormat = (Path.GetExtension(imageInfo.Path) ?? string.Empty)
.TrimStart('.')
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index 3cc6a4379d..b4127a91f1 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -29,6 +29,8 @@ namespace MediaBrowser.Dlna
private readonly IJsonSerializer _jsonSerializer;
private readonly IServerApplicationHost _appHost;
+ private readonly Dictionary _profiles = new Dictionary(StringComparer.Ordinal);
+
public DlnaManager(IXmlSerializer xmlSerializer,
IFileSystem fileSystem,
IApplicationPaths appPaths,
@@ -300,20 +302,31 @@ namespace MediaBrowser.Dlna
private DeviceProfile ParseProfileXmlFile(string path, DeviceProfileType type)
{
- try
+ lock (_profiles)
{
- var profile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path);
+ DeviceProfile profile;
+ if (_profiles.TryGetValue(path, out profile))
+ {
+ return profile;
+ }
+
+ try
+ {
+ profile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path);
- profile.Id = path.ToLower().GetMD5().ToString("N");
- profile.ProfileType = type;
+ profile.Id = path.ToLower().GetMD5().ToString("N");
+ profile.ProfileType = type;
- return profile;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error parsing profile xml: {0}", ex, path);
+ _profiles[path] = profile;
- return null;
+ return profile;
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error parsing profile xml: {0}", ex, path);
+
+ return null;
+ }
}
}
@@ -428,7 +441,7 @@ namespace MediaBrowser.Dlna
var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml";
var path = Path.Combine(UserProfilesPath, newFilename);
- _xmlSerializer.SerializeToFile(profile, path);
+ SaveProfile(profile, path);
}
public void UpdateProfile(DeviceProfile profile)
@@ -455,6 +468,15 @@ namespace MediaBrowser.Dlna
_fileSystem.DeleteFile(current.Path);
}
+ SaveProfile(profile, path);
+ }
+
+ private void SaveProfile(DeviceProfile profile, string path)
+ {
+ lock (_profiles)
+ {
+ _profiles[path] = profile;
+ }
_xmlSerializer.SerializeToFile(profile, path);
}
diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
index 22f308979f..b9d9944eca 100644
--- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
+++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
@@ -15,6 +15,7 @@ using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Dlna.Channels;
@@ -105,7 +106,7 @@ namespace MediaBrowser.Dlna.Main
}
}
- private void ReloadComponents()
+ private async void ReloadComponents()
{
var options = _config.GetDlnaConfiguration();
@@ -130,7 +131,7 @@ namespace MediaBrowser.Dlna.Main
if (options.EnableServer && !isServerStarted)
{
- StartDlnaServer();
+ await StartDlnaServer().ConfigureAwait(false);
}
else if (!options.EnableServer && isServerStarted)
{
@@ -208,11 +209,11 @@ namespace MediaBrowser.Dlna.Main
}
}
- public void StartDlnaServer()
+ public async Task StartDlnaServer()
{
try
{
- RegisterServerEndpoints();
+ await RegisterServerEndpoints().ConfigureAwait(false);
_dlnaServerStarted = true;
}
@@ -222,9 +223,9 @@ namespace MediaBrowser.Dlna.Main
}
}
- private void RegisterServerEndpoints()
+ private async Task RegisterServerEndpoints()
{
- foreach (var address in _appHost.LocalIpAddresses)
+ foreach (var address in await _appHost.GetLocalIpAddresses().ConfigureAwait(false))
{
//if (IPAddress.IsLoopback(address))
//{
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
index 80bb756ef5..873ae5ae41 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
@@ -62,7 +62,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
return false;
}
-
+
return _device != null;
}
}
@@ -119,7 +119,7 @@ namespace MediaBrowser.Dlna.PlayTo
string nt;
if (!e.Headers.TryGetValue("NT", out nt)) nt = String.Empty;
- if ( usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
+ if (usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
!_disposed)
{
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1 ||
@@ -141,7 +141,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
try
{
- var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager);
+ var streamInfo = await StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
if (streamInfo.Item != null)
{
var progress = GetProgressInfo(e.OldMediaInfo, streamInfo);
@@ -151,9 +151,9 @@ namespace MediaBrowser.Dlna.PlayTo
ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks);
}
- streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager);
+ streamInfo = await StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
if (streamInfo.Item == null) return;
-
+
var newItemProgress = GetProgressInfo(e.NewMediaInfo, streamInfo);
await _sessionManager.OnPlaybackStart(newItemProgress).ConfigureAwait(false);
@@ -168,7 +168,8 @@ namespace MediaBrowser.Dlna.PlayTo
{
try
{
- var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
+ var streamInfo = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager)
+ .ConfigureAwait(false);
if (streamInfo.Item == null) return;
@@ -230,7 +231,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
try
{
- var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
+ var info = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
if (info.Item != null)
{
@@ -249,7 +250,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
try
{
- var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
+ var info = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
if (info.Item != null)
{
@@ -377,7 +378,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (media != null)
{
- var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
+ var info = await StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
if (info.Item != null && !EnableClientSideSeek(info))
{
@@ -470,7 +471,7 @@ namespace MediaBrowser.Dlna.PlayTo
var profile = _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification()) ??
_dlnaManager.GetDefaultProfile();
-
+
var hasMediaSources = item as IHasMediaSources;
var mediaSources = hasMediaSources != null
? (_mediaSourceManager.GetStaticMediaSources(hasMediaSources, true, user)).ToList()
@@ -498,7 +499,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
return new ContentFeatureBuilder(profile)
.BuildAudioHeader(streamInfo.Container,
- streamInfo.AudioCodec,
+ streamInfo.TargetAudioCodec,
streamInfo.TargetAudioBitrate,
streamInfo.TargetAudioSampleRate,
streamInfo.TargetAudioChannels,
@@ -512,7 +513,7 @@ namespace MediaBrowser.Dlna.PlayTo
var list = new ContentFeatureBuilder(profile)
.BuildVideoHeader(streamInfo.Container,
streamInfo.VideoCodec,
- streamInfo.AudioCodec,
+ streamInfo.TargetAudioCodec,
streamInfo.TargetWidth,
streamInfo.TargetHeight,
streamInfo.TargetVideoBitDepth,
@@ -739,7 +740,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (media != null)
{
- var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
+ var info = await StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
if (info.Item != null)
{
@@ -765,7 +766,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (media != null)
{
- var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
+ var info = await StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
if (info.Item != null)
{
@@ -840,7 +841,7 @@ namespace MediaBrowser.Dlna.PlayTo
return null;
}
- public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager)
+ public static async Task ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager)
{
var request = new StreamParams
{
@@ -906,11 +907,9 @@ namespace MediaBrowser.Dlna.PlayTo
var hasMediaSources = request.Item as IHasMediaSources;
- request.MediaSource = hasMediaSources == null ?
- null :
- mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, false).Result;
-
-
+ request.MediaSource = hasMediaSources == null
+ ? null
+ : (await mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, false).ConfigureAwait(false));
return request;
}
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
index bbb9bf6de9..cd9a7b1f0c 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
@@ -101,6 +101,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
var uri = new Uri(location);
+ _logger.Debug("Attempting to create PlayToController from location {0}", location);
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
if (device.RendererCommands == null)
@@ -112,6 +113,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
+ _logger.Debug("Logging session activity from location {0}", location);
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null)
.ConfigureAwait(false);
diff --git a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs
index 3bff80a704..202ea76fbf 100644
--- a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs
@@ -54,21 +54,21 @@ namespace MediaBrowser.Dlna.Profiles
new DirectPlayProfile
{
Container = "ts",
- VideoCodec = "h264,hevc",
+ VideoCodec = "h264",
AudioCodec = "aac,ac3,mp3",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Container = "mkv",
- VideoCodec = "h264,hevc",
+ VideoCodec = "h264",
AudioCodec = "aac,ac3,mp3",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Container = "mp4",
- VideoCodec = "h264,mpeg4,hevc",
+ VideoCodec = "h264,mpeg4",
AudioCodec = "aac,ac3,mp3",
Type = DlnaProfileType.Video
},
@@ -189,6 +189,15 @@ namespace MediaBrowser.Dlna.Profiles
}
}
};
+
+ SubtitleProfiles = new[]
+ {
+ new SubtitleProfile
+ {
+ Format = "srt",
+ Method = SubtitleDeliveryMethod.External
+ }
+ };
}
}
}
diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
index 1b06e1d6a7..c117d030f9 100644
--- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -21,8 +21,8 @@ namespace MediaBrowser.Dlna.Profiles
new HttpHeaderInfo
{
Name = "User-Agent",
- Value = @"SEC_",
- Match = HeaderMatchType.Substring
+ Value = @".*(SEC_HHP_\[TV\] [A-Z]{2}\d{2}J[A-Z]?\d{3,4})*.",
+ Match = HeaderMatchType.Regex
}
}
};
diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
index 404bbbb206..1147aa2993 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
@@ -35,9 +35,9 @@
false
-
-
-
+
+
+
@@ -77,5 +77,7 @@
-
+
+
+
\ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
index b09c25afa9..967538bdf0 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -4,7 +4,7 @@
samsung.com
-
+
Emby
diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
index 1eda79f022..68768745e8 100644
--- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
@@ -61,7 +61,7 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
- void _ssdpHandler_MessageReceived(object sender, SsdpMessageEventArgs e)
+ async void _ssdpHandler_MessageReceived(object sender, SsdpMessageEventArgs e)
{
string nts;
e.Headers.TryGetValue("NTS", out nts);
@@ -78,7 +78,7 @@ namespace MediaBrowser.Dlna.Ssdp
{
if (e.LocalEndPoint == null)
{
- var ip = _appHost.LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i));
+ var ip = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !IPAddress.IsLoopback(i));
if (ip != null)
{
e.LocalEndPoint = new IPEndPoint(ip, 0);
diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
index be81d21d20..2b3f53aeb5 100644
--- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
@@ -593,36 +593,28 @@ namespace MediaBrowser.LocalMetadata.Savers
builder.Append("");
}
- var hasTags = item as IHasTags;
- if (hasTags != null)
+ if (item.Tags.Count > 0)
{
- if (hasTags.Tags.Count > 0)
- {
- builder.Append("");
-
- foreach (var tag in hasTags.Tags)
- {
- builder.Append("" + SecurityElement.Escape(tag) + "");
- }
+ builder.Append("");
- builder.Append("");
+ foreach (var tag in item.Tags)
+ {
+ builder.Append("" + SecurityElement.Escape(tag) + "");
}
+
+ builder.Append("");
}
- var hasKeywords = item as IHasKeywords;
- if (hasKeywords != null)
+ if (item.Keywords.Count > 0)
{
- if (hasKeywords.Keywords.Count > 0)
- {
- builder.Append("");
-
- foreach (var tag in hasKeywords.Keywords)
- {
- builder.Append("" + SecurityElement.Escape(tag) + "");
- }
+ builder.Append("");
- builder.Append("");
+ foreach (var tag in item.Keywords)
+ {
+ builder.Append("" + SecurityElement.Escape(tag) + "");
}
+
+ builder.Append("");
}
var people = libraryManager.GetPeople(item);
diff --git a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
index 2d5225344e..cd1575fa58 100644
--- a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
@@ -6,6 +6,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using CommonIO;
namespace MediaBrowser.MediaEncoding.Encoder
@@ -16,7 +17,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
}
- protected override string GetCommandLineArguments(EncodingJob state)
+ protected override Task GetCommandLineArguments(EncodingJob state)
{
var audioTranscodeParams = new List();
@@ -61,7 +62,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
vn = " -vn";
}
- return string.Format("{0} {1}{6}{7} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1{8} -y \"{5}\"",
+ var result = string.Format("{0} {1}{6}{7} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1{8} -y \"{5}\"",
inputModifier,
GetInputArgument(state),
threads,
@@ -71,6 +72,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
albumCoverInput,
mapArgs,
metadata).Trim();
+
+ return Task.FromResult(result);
}
protected override string GetOutputFileExtension(EncodingJob state)
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index d551d5c8c0..77bd50b9b3 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -42,8 +42,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
IFileSystem fileSystem,
IIsoManager isoManager,
ILibraryManager libraryManager,
- ISessionManager sessionManager,
- ISubtitleEncoder subtitleEncoder,
+ ISessionManager sessionManager,
+ ISubtitleEncoder subtitleEncoder,
IMediaSourceManager mediaSourceManager)
{
MediaEncoder = mediaEncoder;
@@ -71,12 +71,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
await AcquireResources(encodingJob, cancellationToken).ConfigureAwait(false);
- var commandLineArgs = GetCommandLineArguments(encodingJob);
-
- if (GetEncodingOptions().EnableDebugLogging)
- {
- commandLineArgs = "-loglevel debug " + commandLineArgs;
- }
+ var commandLineArgs = await GetCommandLineArguments(encodingJob).ConfigureAwait(false);
var process = new Process
{
@@ -136,7 +131,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
cancellationToken.Register(() => Cancel(process, encodingJob));
-
+
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
process.BeginOutputReadLine();
@@ -144,7 +139,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
new JobLogger(Logger).StartStreamingLog(encodingJob, process.StandardError.BaseStream, encodingJob.LogFileStream);
// Wait for the file to exist before proceeeding
- while (!FileSystem.FileExists(encodingJob.OutputFilePath) && !encodingJob.HasExited)
+ while (!FileSystem.FileExists(encodingJob.OutputFilePath) && !encodingJob.HasExited)
{
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
@@ -269,11 +264,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
return ConfigurationManager.GetConfiguration("encoding");
}
- protected abstract string GetCommandLineArguments(EncodingJob job);
+ protected abstract Task GetCommandLineArguments(EncodingJob job);
private string GetOutputFilePath(EncodingJob state)
{
- var folder = string.IsNullOrWhiteSpace(state.Options.OutputDirectory) ?
+ var folder = string.IsNullOrWhiteSpace(state.Options.OutputDirectory) ?
ConfigurationManager.ApplicationPaths.TranscodingTempPath :
state.Options.OutputDirectory;
@@ -368,7 +363,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
- return null;
+ return null;
}
if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec))
@@ -382,7 +377,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (MediaEncoder.SupportsDecoder("h264_qsv"))
{
// Seeing stalls and failures with decoding. Not worth it compared to encoding.
- //return "-c:v h264_qsv ";
+ return "-c:v h264_qsv ";
}
break;
case "mpeg2video":
@@ -541,7 +536,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// The state.
/// The output video codec.
/// System.String.
- protected string GetGraphicalSubtitleParam(EncodingJob state, string outputVideoCodec)
+ protected async Task GetGraphicalSubtitleParam(EncodingJob state, string outputVideoCodec)
{
var outputSizeParam = string.Empty;
@@ -550,7 +545,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Add resolution params, if specified
if (request.Width.HasValue || request.Height.HasValue || request.MaxHeight.HasValue || request.MaxWidth.HasValue)
{
- outputSizeParam = GetOutputSizeParam(state, outputVideoCodec).TrimEnd('"');
+ outputSizeParam = await GetOutputSizeParam(state, outputVideoCodec).ConfigureAwait(false);
+ outputSizeParam = outputSizeParam.TrimEnd('"');
outputSizeParam = "," + outputSizeParam.Substring(outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase));
}
@@ -676,17 +672,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!string.IsNullOrEmpty(state.Options.Profile))
{
- param += " -profile:v " + state.Options.Profile;
+ if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
+ {
+ // not supported by h264_omx
+ param += " -profile:v " + state.Options.Profile;
+ }
}
var levelString = state.Options.Level.HasValue ? state.Options.Level.Value.ToString(CultureInfo.InvariantCulture) : null;
if (!string.IsNullOrEmpty(levelString))
{
- var h264Encoder = EncodingJobFactory.GetH264Encoder(state, GetEncodingOptions());
-
// h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
- if (String.Equals(h264Encoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) || String.Equals(h264Encoder, "libnvenc", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase))
{
switch (levelString)
{
@@ -722,13 +721,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
break;
}
}
- else
+ else if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
{
param += " -level " + levelString;
}
}
- return "-pix_fmt yuv420p " + param;
+ if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase))
+ {
+ param = "-pix_fmt yuv420p " + param;
+ }
+
+ return param;
}
protected string GetVideoBitrateParam(EncodingJob state, string videoCodec)
@@ -863,7 +869,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// The output video codec.
/// if set to true [allow time stamp copy].
/// System.String.
- protected string GetOutputSizeParam(EncodingJob state,
+ protected async Task GetOutputSizeParam(EncodingJob state,
string outputVideoCodec,
bool allowTimeStampCopy = true)
{
@@ -940,7 +946,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode)
{
- var subParam = GetTextSubtitleParam(state);
+ var subParam = await GetTextSubtitleParam(state).ConfigureAwait(false);
filters.Add(subParam);
@@ -963,7 +969,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
///
/// The state.
/// System.String.
- protected string GetTextSubtitleParam(EncodingJob state)
+ protected async Task GetTextSubtitleParam(EncodingJob state)
{
var seconds = Math.Round(TimeSpan.FromTicks(state.Options.StartTimeTicks ?? 0).TotalSeconds);
@@ -975,7 +981,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!string.IsNullOrEmpty(state.SubtitleStream.Language))
{
- var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language, state.MediaSource.Protocol, CancellationToken.None).Result;
+ var charenc = await SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language, state.MediaSource.Protocol, CancellationToken.None).ConfigureAwait(false);
if (!string.IsNullOrEmpty(charenc))
{
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
similarity index 60%
rename from MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs
rename to MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index 0ae021407b..133cc8d70e 100644
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -1,48 +1,42 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Model.Logging;
-using System;
+using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Collections.Generic;
-using CommonIO;
+using MediaBrowser.Model.Logging;
-namespace MediaBrowser.Server.Startup.Common.FFMpeg
+namespace MediaBrowser.MediaEncoding.Encoder
{
- public class FFmpegValidator
+ public class EncoderValidator
{
private readonly ILogger _logger;
- private readonly IApplicationPaths _appPaths;
- private readonly IFileSystem _fileSystem;
- public FFmpegValidator(ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem)
+ public EncoderValidator(ILogger logger)
{
_logger = logger;
- _appPaths = appPaths;
- _fileSystem = fileSystem;
}
- public Tuple,List> Validate(FFMpegInfo info)
+ public Tuple, List> Validate(string encoderPath)
{
- _logger.Info("FFMpeg: {0}", info.EncoderPath);
- _logger.Info("FFProbe: {0}", info.ProbePath);
+ _logger.Info("Validating media encoder at {0}", encoderPath);
+
+ var decoders = GetDecoders(encoderPath);
+ var encoders = GetEncoders(encoderPath);
- var decoders = GetDecoders(info.EncoderPath);
- var encoders = GetEncoders(info.EncoderPath);
+ _logger.Info("Encoder validation complete");
return new Tuple, List>(decoders, encoders);
}
- private List GetDecoders(string ffmpegPath)
+ private List GetDecoders(string encoderAppPath)
{
string output = string.Empty;
try
{
- output = GetFFMpegOutput(ffmpegPath, "-decoders");
+ output = GetProcessOutput(encoderAppPath, "-decoders");
}
catch
{
}
- //_logger.Debug("ffmpeg decoder query result: {0}", output ?? string.Empty);
var found = new List();
var required = new[]
@@ -56,12 +50,9 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
{
var srch = " " + codec + " ";
- if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1)
- {
- _logger.Warn("ffmpeg is missing decoder " + codec);
- }
- else
+ if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
{
+ _logger.Info("Decoder available: " + codec);
found.Add(codec);
}
}
@@ -69,17 +60,16 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
return found;
}
- private List GetEncoders(string ffmpegPath)
+ private List GetEncoders(string encoderAppPath)
{
string output = null;
try
{
- output = GetFFMpegOutput(ffmpegPath, "-encoders");
+ output = GetProcessOutput(encoderAppPath, "-encoders");
}
catch
{
}
- //_logger.Debug("ffmpeg encoder query result: {0}", output ?? string.Empty);
var found = new List();
var required = new[]
@@ -94,19 +84,18 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
"libmp3lame",
"libopus",
//"libvorbis",
- "srt"
+ "srt",
+ "libnvenc",
+ "h264_qsv"
};
foreach (var codec in required)
{
var srch = " " + codec + " ";
- if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1)
- {
- _logger.Warn("ffmpeg is missing encoder " + codec);
- }
- else
+ if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
{
+ _logger.Info("Encoder available: " + codec);
found.Add(codec);
}
}
@@ -114,7 +103,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
return found;
}
- private string GetFFMpegOutput(string path, string arguments)
+ private string GetProcessOutput(string path, string arguments)
{
var process = new Process
{
@@ -139,13 +128,12 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
{
process.BeginErrorReadLine();
- using (var reader = new StreamReader(process.StandardOutput.BaseStream))
- {
- return reader.ReadToEnd();
- }
+ return process.StandardOutput.ReadToEnd();
}
catch
{
+ _logger.Info("Killing process {0} {1}", path, arguments);
+
// Hate having to do this
try
{
@@ -153,7 +141,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
}
catch (Exception ex1)
{
- _logger.ErrorException("Error killing ffmpeg", ex1);
+ _logger.ErrorException("Error killing process", ex1);
}
throw;
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
index 1544a78b66..1770093060 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
@@ -99,7 +99,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (videoRequest != null)
{
state.OutputVideoCodec = state.Options.VideoCodec;
- state.OutputVideoBitrate = GetVideoBitrateParamValue(state.Options, state.VideoStream);
+ state.OutputVideoBitrate = GetVideoBitrateParamValue(state.Options, state.VideoStream, state.OutputVideoCodec);
if (state.OutputVideoBitrate.HasValue)
{
@@ -396,7 +396,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return request.AudioChannels;
}
- private int? GetVideoBitrateParamValue(EncodingJobOptions request, MediaStream videoStream)
+ private int? GetVideoBitrateParamValue(EncodingJobOptions request, MediaStream videoStream, string outputVideoCodec)
{
var bitrate = request.VideoBitRate;
@@ -421,6 +421,18 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}
+ if (bitrate.HasValue)
+ {
+ var inputVideoCodec = videoStream == null ? null : videoStream.Codec;
+ bitrate = ResolutionNormalizer.ScaleBitrate(bitrate.Value, inputVideoCodec, outputVideoCodec);
+
+ // If a max bitrate was requested, don't let the scaled bitrate exceed it
+ if (request.VideoBitRate.HasValue)
+ {
+ bitrate = Math.Min(bitrate.Value, request.VideoBitRate.Value);
+ }
+ }
+
return bitrate;
}
@@ -544,13 +556,19 @@ namespace MediaBrowser.MediaEncoding.Encoder
internal static string GetH264Encoder(EncodingJob state, EncodingOptions options)
{
- if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(options.HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
{
- // It's currently failing on live tv
- if (state.RunTimeTicks.HasValue)
- {
- return "h264_qsv";
- }
+ return "h264_qsv";
+ }
+
+ if (string.Equals(options.HardwareAccelerationType, "libnvenc", StringComparison.OrdinalIgnoreCase))
+ {
+ return "libnvenc";
+ }
+ if (string.Equals(options.HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase))
+ {
+ return "h264_omx";
}
return "libx264";
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 399fdead9c..7264ad2d17 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -21,6 +21,9 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.MediaEncoding.Encoder
{
@@ -64,8 +67,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
public string FFProbePath { get; private set; }
- public string Version { get; private set; }
-
protected readonly IServerConfigurationManager ConfigurationManager;
protected readonly IFileSystem FileSystem;
protected readonly ILiveTvManager LiveTvManager;
@@ -77,12 +78,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
protected readonly Func MediaSourceManager;
private readonly List _runningProcesses = new List();
+ private readonly bool _hasExternalEncoder;
- public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func subtitleEncoder, Func mediaSourceManager)
+ public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func subtitleEncoder, Func mediaSourceManager)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
- Version = version;
ConfigurationManager = configurationManager;
FileSystem = fileSystem;
LiveTvManager = liveTvManager;
@@ -94,6 +95,271 @@ namespace MediaBrowser.MediaEncoding.Encoder
MediaSourceManager = mediaSourceManager;
FFProbePath = ffProbePath;
FFMpegPath = ffMpegPath;
+
+ _hasExternalEncoder = hasExternalEncoder;
+ }
+
+ public string EncoderLocationType
+ {
+ get
+ {
+ if (_hasExternalEncoder)
+ {
+ return "External";
+ }
+
+ if (string.IsNullOrWhiteSpace(FFMpegPath))
+ {
+ return null;
+ }
+
+ if (IsSystemInstalledPath(FFMpegPath))
+ {
+ return "System";
+ }
+
+ return "Custom";
+ }
+ }
+
+ private bool IsSystemInstalledPath(string path)
+ {
+ if (path.IndexOf("/", StringComparison.Ordinal) == -1 && path.IndexOf("\\", StringComparison.Ordinal) == -1)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public async Task Init()
+ {
+ InitPaths();
+
+ if (!string.IsNullOrWhiteSpace(FFMpegPath))
+ {
+ var result = new EncoderValidator(_logger).Validate(FFMpegPath);
+
+ SetAvailableDecoders(result.Item1);
+ SetAvailableEncoders(result.Item2);
+ }
+ }
+
+ private void InitPaths()
+ {
+ ConfigureEncoderPaths();
+
+ if (_hasExternalEncoder)
+ {
+ LogPaths();
+ return;
+ }
+
+ // If the path was passed in, save it into config now.
+ var encodingOptions = GetEncodingOptions();
+ var appPath = encodingOptions.EncoderAppPath;
+
+ var valueToSave = FFMpegPath;
+
+ if (!string.IsNullOrWhiteSpace(valueToSave))
+ {
+ // if using system variable, don't save this.
+ if (IsSystemInstalledPath(valueToSave))
+ {
+ valueToSave = null;
+ }
+ }
+
+ if (!string.Equals(valueToSave, appPath, StringComparison.Ordinal))
+ {
+ encodingOptions.EncoderAppPath = valueToSave;
+ ConfigurationManager.SaveConfiguration("encoding", encodingOptions);
+ }
+ }
+
+ public async Task UpdateEncoderPath(string path, string pathType)
+ {
+ if (_hasExternalEncoder)
+ {
+ return;
+ }
+
+ Tuple newPaths;
+
+ if (string.Equals(pathType, "system", StringComparison.OrdinalIgnoreCase))
+ {
+ path = "ffmpeg";
+
+ newPaths = TestForInstalledVersions();
+ }
+ else if (string.Equals(pathType, "custom", StringComparison.OrdinalIgnoreCase))
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ if (!File.Exists(path) && !Directory.Exists(path))
+ {
+ throw new ResourceNotFoundException();
+ }
+ newPaths = GetEncoderPaths(path);
+ }
+ else
+ {
+ throw new ArgumentException("Unexpected pathType value");
+ }
+
+ if (string.IsNullOrWhiteSpace(newPaths.Item1))
+ {
+ throw new ResourceNotFoundException("ffmpeg not found");
+ }
+ if (string.IsNullOrWhiteSpace(newPaths.Item2))
+ {
+ throw new ResourceNotFoundException("ffprobe not found");
+ }
+
+ var config = GetEncodingOptions();
+ config.EncoderAppPath = path;
+ ConfigurationManager.SaveConfiguration("encoding", config);
+
+ Init();
+ }
+
+ private void ConfigureEncoderPaths()
+ {
+ if (_hasExternalEncoder)
+ {
+ return;
+ }
+
+ var appPath = GetEncodingOptions().EncoderAppPath;
+
+ if (string.IsNullOrWhiteSpace(appPath))
+ {
+ appPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg");
+ }
+
+ var newPaths = GetEncoderPaths(appPath);
+ if (string.IsNullOrWhiteSpace(newPaths.Item1) || string.IsNullOrWhiteSpace(newPaths.Item2))
+ {
+ newPaths = TestForInstalledVersions();
+ }
+
+ if (!string.IsNullOrWhiteSpace(newPaths.Item1) && !string.IsNullOrWhiteSpace(newPaths.Item2))
+ {
+ FFMpegPath = newPaths.Item1;
+ FFProbePath = newPaths.Item2;
+ }
+
+ LogPaths();
+ }
+
+ private Tuple GetEncoderPaths(string configuredPath)
+ {
+ var appPath = configuredPath;
+
+ if (!string.IsNullOrWhiteSpace(appPath))
+ {
+ if (Directory.Exists(appPath))
+ {
+ return GetPathsFromDirectory(appPath);
+ }
+
+ if (File.Exists(appPath))
+ {
+ return new Tuple(appPath, GetProbePathFromEncoderPath(appPath));
+ }
+ }
+
+ return new Tuple(null, null);
+ }
+
+ private Tuple TestForInstalledVersions()
+ {
+ string encoderPath = null;
+ string probePath = null;
+
+ if (TestSystemInstalled("ffmpeg"))
+ {
+ encoderPath = "ffmpeg";
+ }
+ if (TestSystemInstalled("ffprobe"))
+ {
+ probePath = "ffprobe";
+ }
+
+ return new Tuple(encoderPath, probePath);
+ }
+
+ private bool TestSystemInstalled(string app)
+ {
+ try
+ {
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = app,
+ Arguments = "-v",
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ WindowStyle = ProcessWindowStyle.Hidden,
+ ErrorDialog = false
+ };
+
+ using (var process = Process.Start(startInfo))
+ {
+ process.WaitForExit();
+ }
+
+ _logger.Debug("System app installed: " + app);
+ return true;
+ }
+ catch
+ {
+ _logger.Debug("System app not installed: " + app);
+ return false;
+ }
+ }
+
+ private Tuple GetPathsFromDirectory(string path)
+ {
+ // Since we can't predict the file extension, first try directly within the folder
+ // If that doesn't pan out, then do a recursive search
+ var files = Directory.GetFiles(path);
+
+ var ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase));
+ var ffprobePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase));
+
+ if (string.IsNullOrWhiteSpace(ffmpegPath) || !File.Exists(ffmpegPath))
+ {
+ files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
+
+ ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase));
+
+ if (!string.IsNullOrWhiteSpace(ffmpegPath))
+ {
+ ffprobePath = GetProbePathFromEncoderPath(ffmpegPath);
+ }
+ }
+
+ return new Tuple(ffmpegPath, ffprobePath);
+ }
+
+ private string GetProbePathFromEncoderPath(string appPath)
+ {
+ return Directory.GetFiles(Path.GetDirectoryName(appPath))
+ .FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase));
+ }
+
+ private void LogPaths()
+ {
+ _logger.Info("FFMpeg: {0}", FFMpegPath ?? "not found");
+ _logger.Info("FFProbe: {0}", FFProbePath ?? "not found");
+ }
+
+ private EncodingOptions GetEncodingOptions()
+ {
+ return ConfigurationManager.GetConfiguration("encoding");
}
private List _encoders = new List();
diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
index 3ab55168d5..82a9668218 100644
--- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
@@ -7,6 +7,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using System;
using System.IO;
+using System.Threading.Tasks;
using CommonIO;
namespace MediaBrowser.MediaEncoding.Encoder
@@ -17,7 +18,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
}
- protected override string GetCommandLineArguments(EncodingJob state)
+ protected override async Task GetCommandLineArguments(EncodingJob state)
{
// Get the output codec name
var videoCodec = EncodingJobFactory.GetVideoEncoder(state, GetEncodingOptions());
@@ -36,12 +37,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
var inputModifier = GetInputModifier(state);
+ var videoArguments = await GetVideoArguments(state, videoCodec).ConfigureAwait(false);
+
return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -threads {5} {6}{7} -y \"{8}\"",
inputModifier,
GetInputArgument(state),
keyFrame,
GetMapArgs(state),
- GetVideoArguments(state, videoCodec),
+ videoArguments,
threads,
GetAudioArguments(state),
format,
@@ -55,7 +58,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// The state.
/// The video codec.
/// System.String.
- private string GetVideoArguments(EncodingJob state, string videoCodec)
+ private async Task GetVideoArguments(EncodingJob state, string videoCodec)
{
var args = "-codec:v:0 " + videoCodec;
@@ -91,7 +94,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
- args += GetOutputSizeParam(state, videoCodec);
+ args += await GetOutputSizeParam(state, videoCodec).ConfigureAwait(false);
}
var qualityParam = GetVideoQualityParam(state, videoCodec);
@@ -104,7 +107,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
// This is for internal graphical subs
if (hasGraphicalSubs)
{
- args += GetGraphicalSubtitleParam(state, videoCodec);
+ args += await GetGraphicalSubtitleParam(state, videoCodec).ConfigureAwait(false);
}
return args;
diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
index 5576a49bd0..7943534515 100644
--- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
+++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
@@ -71,6 +71,7 @@
+
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index 44c69d4c1b..44a0f264da 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -408,7 +408,9 @@ namespace MediaBrowser.MediaEncoding.Probing
Level = streamInfo.level,
Index = streamInfo.index,
PixelFormat = streamInfo.pix_fmt,
- NalLengthSize = streamInfo.nal_length_size
+ NalLengthSize = streamInfo.nal_length_size,
+ TimeBase = streamInfo.time_base,
+ CodecTimeBase = streamInfo.codec_time_base
};
if (string.Equals(streamInfo.is_avc, "true", StringComparison.OrdinalIgnoreCase) ||
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index 8c33cc7c0b..25adbcdb0c 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -58,6 +58,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string outputFormat,
long startTimeTicks,
long? endTimeTicks,
+ bool preserveOriginalTimestamps,
CancellationToken cancellationToken)
{
var ms = new MemoryStream();
@@ -68,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var trackInfo = reader.Parse(stream, cancellationToken);
- FilterEvents(trackInfo, startTimeTicks, endTimeTicks, false);
+ FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps);
var writer = GetWriter(outputFormat);
@@ -116,6 +117,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string outputFormat,
long startTimeTicks,
long? endTimeTicks,
+ bool preserveOriginalTimestamps,
CancellationToken cancellationToken)
{
var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken)
@@ -130,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
using (var stream = subtitle.Item1)
{
- return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, cancellationToken).ConfigureAwait(false);
+ return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index ba4d1b59e8..0de9fb519c 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -230,12 +230,6 @@
Configuration\SubtitlePlaybackMode.cs
-
- Configuration\TheMovieDbOptions.cs
-
-
- Configuration\TvdbOptions.cs
-
Configuration\UnratedItem.cs
@@ -605,9 +599,6 @@
Entities\Video3DFormat.cs
-
- Entities\VideoSize.cs
-
Entities\VideoType.cs
@@ -1145,6 +1136,9 @@
Sync\SyncTarget.cs
+
+ System\Architecture.cs
+
System\LogFile.cs
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index f5d538cc47..fe0b3bcae9 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -204,12 +204,6 @@
Configuration\SubtitlePlaybackMode.cs
-
- Configuration\TheMovieDbOptions.cs
-
-
- Configuration\TvdbOptions.cs
-
Configuration\UnratedItem.cs
@@ -579,9 +573,6 @@
Entities\Video3DFormat.cs
-
- Entities\VideoSize.cs
-
Entities\VideoType.cs
@@ -1110,6 +1101,9 @@
Sync\SyncTarget.cs
+
+ System\Architecture.cs
+
System\LogFile.cs
diff --git a/MediaBrowser.Model/ApiClient/ServerCredentials.cs b/MediaBrowser.Model/ApiClient/ServerCredentials.cs
index 0f0ab65d4a..19f68445e2 100644
--- a/MediaBrowser.Model/ApiClient/ServerCredentials.cs
+++ b/MediaBrowser.Model/ApiClient/ServerCredentials.cs
@@ -57,6 +57,10 @@ namespace MediaBrowser.Model.ApiClient
{
existing.RemoteAddress = server.RemoteAddress;
}
+ if (!string.IsNullOrEmpty(server.ConnectServerId))
+ {
+ existing.ConnectServerId = server.ConnectServerId;
+ }
if (!string.IsNullOrEmpty(server.LocalAddress))
{
existing.LocalAddress = server.LocalAddress;
diff --git a/MediaBrowser.Model/ApiClient/ServerInfo.cs b/MediaBrowser.Model/ApiClient/ServerInfo.cs
index e1fa581d7b..48995e80a7 100644
--- a/MediaBrowser.Model/ApiClient/ServerInfo.cs
+++ b/MediaBrowser.Model/ApiClient/ServerInfo.cs
@@ -12,6 +12,7 @@ namespace MediaBrowser.Model.ApiClient
public String Name { get; set; }
public String Id { get; set; }
+ public String ConnectServerId { get; set; }
public String LocalAddress { get; set; }
public String RemoteAddress { get; set; }
public String ManualAddress { get; set; }
diff --git a/MediaBrowser.Model/Channels/ChannelFolderType.cs b/MediaBrowser.Model/Channels/ChannelFolderType.cs
index 9261cb5cd3..7c97afd023 100644
--- a/MediaBrowser.Model/Channels/ChannelFolderType.cs
+++ b/MediaBrowser.Model/Channels/ChannelFolderType.cs
@@ -6,6 +6,12 @@ namespace MediaBrowser.Model.Channels
MusicAlbum = 1,
- PhotoAlbum = 2
+ PhotoAlbum = 2,
+
+ MusicArtist = 3,
+
+ Series = 4,
+
+ Season = 5
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index 516d00ee6d..91d28a2969 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -6,10 +6,10 @@ namespace MediaBrowser.Model.Configuration
public int EncodingThreadCount { get; set; }
public string TranscodingTempPath { get; set; }
public double DownMixAudioBoost { get; set; }
- public bool EnableDebugLogging { get; set; }
public bool EnableThrottling { get; set; }
public int ThrottleDelaySeconds { get; set; }
public string HardwareAccelerationType { get; set; }
+ public string EncoderAppPath { get; set; }
public EncodingOptions()
{
diff --git a/MediaBrowser.Model/Configuration/FanartOptions.cs b/MediaBrowser.Model/Configuration/FanartOptions.cs
index e992abe5de..6924b25d7d 100644
--- a/MediaBrowser.Model/Configuration/FanartOptions.cs
+++ b/MediaBrowser.Model/Configuration/FanartOptions.cs
@@ -3,11 +3,6 @@ namespace MediaBrowser.Model.Configuration
{
public class FanartOptions
{
- ///
- /// Gets or sets a value indicating whether [enable automatic updates].
- ///
- /// true if [enable automatic updates]; otherwise, false.
- public bool EnableAutomaticUpdates { get; set; }
///
/// Gets or sets the user API key.
///
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 1cb19afdf2..f779fcd610 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -67,7 +67,7 @@ namespace MediaBrowser.Model.Configuration
///
/// true if [enable case sensitive item ids]; otherwise, false.
public bool EnableCaseSensitiveItemIds { get; set; }
-
+
///
/// Gets or sets the metadata path.
///
@@ -86,12 +86,6 @@ namespace MediaBrowser.Model.Configuration
/// true if [save local meta]; otherwise, false.
public bool SaveLocalMeta { get; set; }
- ///
- /// Gets or sets a value indicating whether [enable localized guids].
- ///
- /// true if [enable localized guids]; otherwise, false.
- public bool EnableLocalizedGuids { get; set; }
-
///
/// Gets or sets the preferred metadata language.
///
@@ -161,7 +155,7 @@ namespace MediaBrowser.Model.Configuration
///
/// The dashboard source path.
public string DashboardSourcePath { get; set; }
-
+
///
/// Gets or sets the image saving convention.
///
@@ -190,33 +184,39 @@ namespace MediaBrowser.Model.Configuration
public bool EnableVideoArchiveFiles { get; set; }
public int RemoteClientBitrateLimit { get; set; }
- public bool DenyIFrameEmbedding { get; set; }
-
public AutoOnOff EnableLibraryMonitor { get; set; }
public int SharingExpirationDays { get; set; }
- public bool EnableDateLastRefresh { get; set; }
-
public string[] Migrations { get; set; }
public int MigrationVersion { get; set; }
public int SchemaVersion { get; set; }
+ public int SqliteCachePages { get; set; }
public bool DownloadImagesInAdvance { get; set; }
public bool EnableAnonymousUsageReporting { get; set; }
public bool EnableStandaloneMusicKeys { get; set; }
+ public bool EnableLocalizedGuids { get; set; }
+ public bool EnableFolderView { get; set; }
+ public bool EnableGroupingIntoCollections { get; set; }
+ public bool DisplaySpecialsWithinSeasons { get; set; }
+ public bool DisplayCollectionsView { get; set; }
+ public string[] LocalNetworkAddresses { get; set; }
///
/// Initializes a new instance of the class.
///
public ServerConfiguration()
{
+ LocalNetworkAddresses = new string[] { };
Migrations = new string[] { };
+ SqliteCachePages = 10000;
- EnableLocalizedGuids = true;
EnableCustomPathSubFolders = true;
+ EnableLocalizedGuids = true;
+ DisplaySpecialsWithinSeasons = true;
ImageSavingConvention = ImageSavingConvention.Compatible;
PublicPort = 8096;
@@ -229,10 +229,8 @@ namespace MediaBrowser.Model.Configuration
EnableAnonymousUsageReporting = true;
EnableAutomaticRestart = true;
- DenyIFrameEmbedding = true;
EnableUPnP = true;
-
SharingExpirationDays = 30;
MinResumePct = 5;
MaxResumePct = 90;
diff --git a/MediaBrowser.Model/Configuration/TheMovieDbOptions.cs b/MediaBrowser.Model/Configuration/TheMovieDbOptions.cs
deleted file mode 100644
index 9a73e34764..0000000000
--- a/MediaBrowser.Model/Configuration/TheMovieDbOptions.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-namespace MediaBrowser.Model.Configuration
-{
- public class TheMovieDbOptions
- {
- ///
- /// Gets or sets a value indicating whether [enable automatic updates].
- ///
- /// true if [enable automatic updates]; otherwise, false.
- public bool EnableAutomaticUpdates { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Configuration/TvdbOptions.cs b/MediaBrowser.Model/Configuration/TvdbOptions.cs
deleted file mode 100644
index 034af609c4..0000000000
--- a/MediaBrowser.Model/Configuration/TvdbOptions.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-namespace MediaBrowser.Model.Configuration
-{
- public class TvdbOptions
- {
- ///
- /// Gets or sets a value indicating whether [enable automatic updates].
- ///
- /// true if [enable automatic updates]; otherwise, false.
- public bool EnableAutomaticUpdates { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 5f42dd2de3..69dc23b21c 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -34,14 +34,11 @@ namespace MediaBrowser.Model.Configuration
public SubtitlePlaybackMode SubtitleMode { get; set; }
public bool DisplayCollectionsView { get; set; }
- public bool DisplayFoldersView { get; set; }
public bool EnableLocalPassword { get; set; }
public string[] OrderedViews { get; set; }
- public bool IncludeTrailersInSuggestions { get; set; }
-
public string[] LatestItemsExcludes { get; set; }
public string[] PlainFolderViews { get; set; }
@@ -51,7 +48,8 @@ namespace MediaBrowser.Model.Configuration
public bool RememberAudioSelections { get; set; }
public bool RememberSubtitleSelections { get; set; }
public bool EnableNextEpisodeAutoPlay { get; set; }
-
+ public bool DisplayFoldersView { get; set; }
+
///
/// Initializes a new instance of the class.
///
@@ -69,8 +67,6 @@ namespace MediaBrowser.Model.Configuration
PlainFolderViews = new string[] { };
- IncludeTrailersInSuggestions = true;
-
GroupedFolders = new string[] { };
}
}
diff --git a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs
index 8a412ac2c6..ed18fed655 100644
--- a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs
+++ b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs
@@ -56,5 +56,25 @@ namespace MediaBrowser.Model.Dlna
MaxHeight = maxHeight
};
}
+
+ private static double GetVideoBitrateScaleFactor(string codec)
+ {
+ if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase))
+ {
+ return .5;
+ }
+ return 1;
+ }
+
+ public static int ScaleBitrate(int bitrate, string inputVideoCodec, string outputVideoCodec)
+ {
+ var inputScaleFactor = GetVideoBitrateScaleFactor(inputVideoCodec);
+ var outputScaleFactor = GetVideoBitrateScaleFactor(outputVideoCodec);
+ var scaleFactor = outputScaleFactor/inputScaleFactor;
+ var newBitrate = scaleFactor*bitrate;
+
+ return Convert.ToInt32(newBitrate);
+ }
}
}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 7721bfd150..41efa51b98 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -216,7 +216,15 @@ namespace MediaBrowser.Model.Dlna
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
playlistItem.Container = transcodingProfile.Container;
- playlistItem.AudioCodec = transcodingProfile.AudioCodec;
+
+ if (string.IsNullOrEmpty(transcodingProfile.AudioCodec))
+ {
+ playlistItem.AudioCodecs = new string[] { };
+ }
+ else
+ {
+ playlistItem.AudioCodecs = transcodingProfile.AudioCodec.Split(',');
+ }
playlistItem.SubProtocol = transcodingProfile.Protocol;
List audioCodecProfiles = new List();
@@ -439,22 +447,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
- // TODO: We should probably preserve the full list and sent it to the server that way
- string[] supportedAudioCodecs = transcodingProfile.AudioCodec.Split(',');
- string inputAudioCodec = audioStream == null ? null : audioStream.Codec;
- foreach (string supportedAudioCodec in supportedAudioCodecs)
- {
- if (StringHelper.EqualsIgnoreCase(supportedAudioCodec, inputAudioCodec))
- {
- playlistItem.AudioCodec = supportedAudioCodec;
- break;
- }
- }
-
- if (string.IsNullOrEmpty(playlistItem.AudioCodec))
- {
- playlistItem.AudioCodec = supportedAudioCodecs[0];
- }
+ playlistItem.AudioCodecs = transcodingProfile.AudioCodec.Split(',');
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps;
@@ -488,7 +481,7 @@ namespace MediaBrowser.Model.Dlna
List audioTranscodingConditions = new List();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
- if (i.Type == CodecType.VideoAudio && i.ContainsCodec(playlistItem.AudioCodec, transcodingProfile.Container))
+ if (i.Type == CodecType.VideoAudio && i.ContainsCodec(playlistItem.TargetAudioCodec, transcodingProfile.Container))
{
foreach (ProfileCondition c in i.Conditions)
{
@@ -842,17 +835,17 @@ namespace MediaBrowser.Model.Dlna
{
bool requiresConversion = !StringHelper.EqualsIgnoreCase(subtitleStream.Codec, profile.Format);
- if (requiresConversion && !allowConversion)
+ if (!requiresConversion)
{
- continue;
+ return profile;
}
- if (!requiresConversion)
+ if (!allowConversion)
{
- return profile;
+ continue;
}
- if (subtitleStream.IsTextSubtitleStream && subtitleStream.SupportsExternalStream)
+ if (subtitleStream.IsTextSubtitleStream && subtitleStream.SupportsExternalStream && subtitleStream.SupportsSubtitleConversionTo(profile.Format))
{
return profile;
}
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 313c30e2c5..43a31f6492 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -14,6 +14,11 @@ namespace MediaBrowser.Model.Dlna
///
public class StreamInfo
{
+ public StreamInfo()
+ {
+ AudioCodecs = new string[] { };
+ }
+
public string ItemId { get; set; }
public PlayMethod PlayMethod { get; set; }
@@ -32,7 +37,7 @@ namespace MediaBrowser.Model.Dlna
public bool CopyTimestamps { get; set; }
public bool ForceLiveStream { get; set; }
- public string AudioCodec { get; set; }
+ public string[] AudioCodecs { get; set; }
public int? AudioStreamIndex { get; set; }
@@ -191,12 +196,16 @@ namespace MediaBrowser.Model.Dlna
{
List list = new List();
+ string audioCodecs = item.AudioCodecs.Length == 0 ?
+ string.Empty :
+ string.Join(",", item.AudioCodecs);
+
list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty));
list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty));
list.Add(new NameValuePair("MediaSourceId", item.MediaSourceId ?? string.Empty));
list.Add(new NameValuePair("Static", item.IsDirectStream.ToString().ToLower()));
list.Add(new NameValuePair("VideoCodec", item.VideoCodec ?? string.Empty));
- list.Add(new NameValuePair("AudioCodec", item.AudioCodec ?? string.Empty));
+ list.Add(new NameValuePair("AudioCodec", audioCodecs));
list.Add(new NameValuePair("AudioStreamIndex", item.AudioStreamIndex.HasValue ? StringHelper.ToStringCultureInvariant(item.AudioStreamIndex.Value) : string.Empty));
list.Add(new NameValuePair("SubtitleStreamIndex", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? StringHelper.ToStringCultureInvariant(item.SubtitleStreamIndex.Value) : string.Empty));
list.Add(new NameValuePair("VideoBitrate", item.VideoBitrate.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoBitrate.Value) : string.Empty));
@@ -278,7 +287,7 @@ namespace MediaBrowser.Model.Dlna
// HLS will preserve timestamps so we can just grab the full subtitle stream
long startPositionTicks = StringHelper.EqualsIgnoreCase(SubProtocol, "hls")
? 0
- : (PlayMethod == PlayMethod.Transcode && !CopyTimestamps ? StartPositionTicks : 0);
+ : (PlayMethod == PlayMethod.Transcode && !CopyTimestamps ? StartPositionTicks : 0);
// First add the selected track
if (SubtitleStreamIndex.HasValue)
@@ -335,7 +344,8 @@ namespace MediaBrowser.Model.Dlna
Name = stream.Language ?? "Unknown",
Format = subtitleProfile.Format,
Index = stream.Index,
- DeliveryMethod = subtitleProfile.Method
+ DeliveryMethod = subtitleProfile.Method,
+ DisplayTitle = stream.DisplayTitle
};
if (info.DeliveryMethod == SubtitleDeliveryMethod.External)
@@ -554,9 +564,22 @@ namespace MediaBrowser.Model.Dlna
{
MediaStream stream = TargetAudioStream;
- return IsDirectStream
- ? (stream == null ? null : stream.Codec)
- : AudioCodec;
+ string inputCodec = stream == null ? null : stream.Codec;
+
+ if (IsDirectStream)
+ {
+ return inputCodec;
+ }
+
+ foreach (string codec in AudioCodecs)
+ {
+ if (StringHelper.EqualsIgnoreCase(codec, inputCodec))
+ {
+ return codec;
+ }
+ }
+
+ return AudioCodecs.Length == 0 ? null : AudioCodecs[0];
}
}
diff --git a/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs b/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs
index 61b2895fc1..7a89308dcc 100644
--- a/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs
@@ -7,6 +7,7 @@ namespace MediaBrowser.Model.Dlna
public string Name { get; set; }
public bool IsForced { get; set; }
public string Format { get; set; }
+ public string DisplayTitle { get; set; }
public int Index { get; set; }
public SubtitleDeliveryMethod DeliveryMethod { get; set; }
public bool IsExternalUrl { get; set; }
diff --git a/MediaBrowser.Model/Dto/ItemCounts.cs b/MediaBrowser.Model/Dto/ItemCounts.cs
index a3a00c3412..07ddfa1ac6 100644
--- a/MediaBrowser.Model/Dto/ItemCounts.cs
+++ b/MediaBrowser.Model/Dto/ItemCounts.cs
@@ -60,5 +60,6 @@
///
/// The book count.
public int BookCount { get; set; }
+ public int ItemCount { get; set; }
}
}
diff --git a/MediaBrowser.Model/Entities/ImageType.cs b/MediaBrowser.Model/Entities/ImageType.cs
index 18097abb44..6e0ba717f0 100644
--- a/MediaBrowser.Model/Entities/ImageType.cs
+++ b/MediaBrowser.Model/Entities/ImageType.cs
@@ -9,50 +9,50 @@ namespace MediaBrowser.Model.Entities
///
/// The primary
///
- Primary,
+ Primary = 0,
///
/// The art
///
- Art,
+ Art = 1,
///
/// The backdrop
///
- Backdrop,
+ Backdrop = 2,
///
/// The banner
///
- Banner,
+ Banner = 3,
///
/// The logo
///
- Logo,
+ Logo = 4,
///
/// The thumb
///
- Thumb,
+ Thumb = 5,
///
/// The disc
///
- Disc,
+ Disc = 6,
///
/// The box
///
- Box,
+ Box = 7,
///
/// The screenshot
///
- Screenshot,
+ Screenshot = 8,
///
/// The menu
///
- Menu,
+ Menu = 9,
///
/// The chapter image
///
- Chapter,
+ Chapter = 10,
///
/// The box rear
///
- BoxRear
+ BoxRear = 11
}
}
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 64c7d9aa6c..990de332e1 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -36,6 +36,9 @@ namespace MediaBrowser.Model.Entities
/// The comment.
public string Comment { get; set; }
+ public string TimeBase { get; set; }
+ public string CodecTimeBase { get; set; }
+
public string Title { get; set; }
public string DisplayTitle
@@ -72,15 +75,12 @@ namespace MediaBrowser.Model.Entities
{
attributes.Add(StringHelper.ToStringCultureInvariant(Channels.Value) + " ch");
}
-
- string name = string.Join(" ", attributes.ToArray());
-
if (IsDefault)
{
- name += " (D)";
+ attributes.Add("Default");
}
- return name;
+ return string.Join(" ", attributes.ToArray());
}
if (Type == MediaStreamType.Subtitle)
@@ -89,29 +89,19 @@ namespace MediaBrowser.Model.Entities
if (!string.IsNullOrEmpty(Language))
{
- attributes.Add(Language);
- }
- if (!string.IsNullOrEmpty(Codec))
- {
- attributes.Add(Codec);
+ attributes.Add(StringHelper.FirstToUpper(Language));
}
-
- string name = string.Join(" ", attributes.ToArray());
-
if (IsDefault)
{
- name += " (D)";
+ attributes.Add("Default");
}
if (IsForced)
{
- name += " (F)";
+ attributes.Add("Forced");
}
- if (IsExternal)
- {
- name += " (EXT)";
- }
+ string name = string.Join(" ", attributes.ToArray());
return name;
}
@@ -292,6 +282,36 @@ namespace MediaBrowser.Model.Entities
!StringHelper.EqualsIgnoreCase(codec, "sub");
}
+ public bool SupportsSubtitleConversionTo(string codec)
+ {
+ if (!IsTextSubtitleStream)
+ {
+ return false;
+ }
+
+ // Can't convert from this
+ if (StringHelper.EqualsIgnoreCase(Codec, "ass"))
+ {
+ return false;
+ }
+ if (StringHelper.EqualsIgnoreCase(Codec, "ssa"))
+ {
+ return false;
+ }
+
+ // Can't convert to this
+ if (StringHelper.EqualsIgnoreCase(codec, "ass"))
+ {
+ return false;
+ }
+ if (StringHelper.EqualsIgnoreCase(codec, "ssa"))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
///
/// Gets or sets a value indicating whether [supports external stream].
///
diff --git a/MediaBrowser.Model/Entities/MediaUrl.cs b/MediaBrowser.Model/Entities/MediaUrl.cs
index 24e3b14927..2e17bba8a8 100644
--- a/MediaBrowser.Model/Entities/MediaUrl.cs
+++ b/MediaBrowser.Model/Entities/MediaUrl.cs
@@ -5,6 +5,5 @@ namespace MediaBrowser.Model.Entities
{
public string Url { get; set; }
public string Name { get; set; }
- public VideoSize? VideoSize { get; set; }
}
}
diff --git a/MediaBrowser.Model/Entities/VideoSize.cs b/MediaBrowser.Model/Entities/VideoSize.cs
deleted file mode 100644
index 0100f3b904..0000000000
--- a/MediaBrowser.Model/Entities/VideoSize.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace MediaBrowser.Model.Entities
-{
- public enum VideoSize
- {
- StandardDefinition,
- HighDefinition
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index e00443d191..242a2d24e4 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -1,4 +1,6 @@
using System.Collections.Generic;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.LiveTv
{
@@ -73,11 +75,33 @@ namespace MediaBrowser.Model.LiveTv
public string[] EnabledTuners { get; set; }
public bool EnableAllTuners { get; set; }
+ public string[] NewsCategories { get; set; }
+ public string[] SportsCategories { get; set; }
+ public string[] KidsCategories { get; set; }
+ public string[] MovieCategories { get; set; }
+ public NameValuePair[] ChannelMappings { get; set; }
public ListingsProviderInfo()
{
+ NewsCategories = new string[] { "news", "journalism", "documentary", "current affairs" };
+ SportsCategories = new string[] { "sports", "basketball", "baseball", "football" };
+ KidsCategories = new string[] { "kids", "family", "children", "childrens", "disney" };
+ MovieCategories = new string[] { "movie" };
EnabledTuners = new string[] { };
EnableAllTuners = true;
+ ChannelMappings = new NameValuePair[] {};
+ }
+
+ public string GetMappedChannel(string channelNumber)
+ {
+ foreach (NameValuePair mapping in ChannelMappings)
+ {
+ if (StringHelper.EqualsIgnoreCase(mapping.Name, channelNumber))
+ {
+ return mapping.Value;
+ }
+ }
+ return channelNumber;
}
}
}
diff --git a/MediaBrowser.Model/LiveTv/RecordingQuery.cs b/MediaBrowser.Model/LiveTv/RecordingQuery.cs
index 0cf9976025..923d303f80 100644
--- a/MediaBrowser.Model/LiveTv/RecordingQuery.cs
+++ b/MediaBrowser.Model/LiveTv/RecordingQuery.cs
@@ -70,5 +70,12 @@ namespace MediaBrowser.Model.LiveTv
public bool? EnableImages { get; set; }
public int? ImageTypeLimit { get; set; }
public ImageType[] EnableImageTypes { get; set; }
+
+ public bool EnableTotalRecordCount { get; set; }
+
+ public RecordingQuery()
+ {
+ EnableTotalRecordCount = true;
+ }
}
}
diff --git a/MediaBrowser.Model/LiveTv/TimerQuery.cs b/MediaBrowser.Model/LiveTv/TimerQuery.cs
index e6ceff5300..87b6b89acd 100644
--- a/MediaBrowser.Model/LiveTv/TimerQuery.cs
+++ b/MediaBrowser.Model/LiveTv/TimerQuery.cs
@@ -13,5 +13,7 @@
///
/// The series timer identifier.
public string SeriesTimerId { get; set; }
+
+ public bool? IsActive { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 7c469b9fb9..e54273b84c 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -97,8 +97,6 @@
-
-
@@ -229,7 +227,6 @@
-
@@ -398,6 +395,7 @@
+
diff --git a/MediaBrowser.Model/Querying/ItemSortBy.cs b/MediaBrowser.Model/Querying/ItemSortBy.cs
index 9c2926b542..6f4ebd0c50 100644
--- a/MediaBrowser.Model/Querying/ItemSortBy.cs
+++ b/MediaBrowser.Model/Querying/ItemSortBy.cs
@@ -85,5 +85,6 @@ namespace MediaBrowser.Model.Querying
public const string GameSystem = "GameSystem";
public const string IsFavoriteOrLiked = "IsFavoriteOrLiked";
public const string DateLastContentAdded = "DateLastContentAdded";
+ public const string SeriesDatePlayed = "SeriesDatePlayed";
}
}
diff --git a/MediaBrowser.Model/System/Architecture.cs b/MediaBrowser.Model/System/Architecture.cs
new file mode 100644
index 0000000000..09eedddc13
--- /dev/null
+++ b/MediaBrowser.Model/System/Architecture.cs
@@ -0,0 +1,9 @@
+namespace MediaBrowser.Model.System
+{
+ public enum Architecture
+ {
+ X86 = 0,
+ X64 = 1,
+ Arm = 2
+ }
+}
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index 6b54a90d44..3d1de5b379 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -152,6 +152,10 @@ namespace MediaBrowser.Model.System
/// true if [supports automatic run at startup]; otherwise, false.
public bool SupportsAutoRunAtStartup { get; set; }
+ public string EncoderLocationType { get; set; }
+
+ public Architecture SystemArchitecture { get; set; }
+
///
/// Initializes a new instance of the class.
///
diff --git a/MediaBrowser.Providers/Books/BookMetadataService.cs b/MediaBrowser.Providers/Books/BookMetadataService.cs
index eb3335c9ab..6f4a744c29 100644
--- a/MediaBrowser.Providers/Books/BookMetadataService.cs
+++ b/MediaBrowser.Providers/Books/BookMetadataService.cs
@@ -12,10 +12,6 @@ namespace MediaBrowser.Providers.Books
{
public class BookMetadataService : MetadataService
{
- public BookMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
@@ -25,5 +21,9 @@ namespace MediaBrowser.Providers.Books
target.Item.SeriesName = source.Item.SeriesName;
}
}
+
+ public BookMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
index 9a24887812..2dacb16ca1 100644
--- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
+++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
@@ -15,10 +15,6 @@ namespace MediaBrowser.Providers.BoxSets
{
public class BoxSetMetadataService : MetadataService
{
- public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
protected override async Task BeforeSave(BoxSet item, bool isFullRefresh, ItemUpdateType currentUpdateType)
{
var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false);
@@ -54,5 +50,9 @@ namespace MediaBrowser.Providers.BoxSets
targetItem.Shares = sourceItem.Shares;
}
}
+
+ public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs
index b3e73740d9..2dce13ebc3 100644
--- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs
+++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs
@@ -83,7 +83,7 @@ namespace MediaBrowser.Providers.BoxSets
VoteCount = i.vote_count,
Width = i.width,
Height = i.height,
- Language = i.iso_639_1,
+ Language = MovieDbProvider.AdjustImageLanguage(i.iso_639_1, language),
ProviderName = Name,
Type = ImageType.Primary,
RatingType = RatingType.Score
diff --git a/MediaBrowser.Providers/Channels/ChannelMetadataService.cs b/MediaBrowser.Providers/Channels/ChannelMetadataService.cs
index 3a1d2374c8..22e196d72c 100644
--- a/MediaBrowser.Providers/Channels/ChannelMetadataService.cs
+++ b/MediaBrowser.Providers/Channels/ChannelMetadataService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.Channels
{
public class ChannelMetadataService : MetadataService
{
- public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/Chapters/ChapterManager.cs b/MediaBrowser.Providers/Chapters/ChapterManager.cs
index 6e2cd77eb3..88811c850d 100644
--- a/MediaBrowser.Providers/Chapters/ChapterManager.cs
+++ b/MediaBrowser.Providers/Chapters/ChapterManager.cs
@@ -259,7 +259,7 @@ namespace MediaBrowser.Providers.Chapters
return _itemRepo.GetChapters(new Guid(itemId));
}
- public Task SaveChapters(string itemId, IEnumerable chapters, CancellationToken cancellationToken)
+ public Task SaveChapters(string itemId, List chapters, CancellationToken cancellationToken)
{
return _itemRepo.SaveChapters(new Guid(itemId), chapters, cancellationToken);
}
diff --git a/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs b/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs
index e1de443de9..35c61b5c58 100644
--- a/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs
+++ b/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs
@@ -16,14 +16,13 @@ namespace MediaBrowser.Providers.Folders
{
public class CollectionFolderMetadataService : MetadataService
{
- public CollectionFolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager)
- : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public CollectionFolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs
deleted file mode 100644
index 08b4f64610..0000000000
--- a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Providers;
-using MediaBrowser.Providers.Genres;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Providers.Folders
-{
- public class DefaultImageProvider : IRemoteImageProvider, IHasItemChangeMonitor
- {
- private readonly IHttpClient _httpClient;
-
- public DefaultImageProvider(IHttpClient httpClient)
- {
- _httpClient = httpClient;
- }
-
- public IEnumerable GetSupportedImages(IHasImages item)
- {
- return new List
- {
- ImageType.Primary
- };
- }
-
- public Task> GetImages(IHasImages item, CancellationToken cancellationToken)
- {
- var view = item as UserView;
-
- if (view != null)
- {
- return GetImages(view.ViewType, cancellationToken);
- }
-
- var folder = (ICollectionFolder)item;
- return GetImages(folder.CollectionType, cancellationToken);
- }
-
- private Task> GetImages(string viewType, CancellationToken cancellationToken)
- {
- var url = GetImageUrl(viewType);
-
- var list = new List();
-
- if (!string.IsNullOrWhiteSpace(url))
- {
- list.AddRange(new List{
- new RemoteImageInfo
- {
- ProviderName = Name,
- Url = url,
- Type = ImageType.Primary
- }
- });
- }
-
- return Task.FromResult>(list);
- }
-
- private string GetImageUrl(string viewType)
- {
- const string urlPrefix = "https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/images/folders/";
-
- if (string.Equals(viewType, CollectionType.Books, StringComparison.OrdinalIgnoreCase))
- {
- return urlPrefix + "books.jpg";
- }
- if (string.Equals(viewType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
- {
- return urlPrefix + "games.jpg";
- }
- if (string.Equals(viewType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
- {
- //return urlPrefix + "music.jpg";
- }
- if (string.Equals(viewType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
- {
- //return urlPrefix + "photos.png";
- }
- if (string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
- {
- //return urlPrefix + "tv.jpg";
- }
- if (string.Equals(viewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
- {
- return urlPrefix + "channels.jpg";
- }
- if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
- {
- return urlPrefix + "livetv.png";
- }
- if (string.Equals(viewType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
- {
- //return urlPrefix + "movies.jpg";
- }
- if (string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
- {
- return urlPrefix + "playlists.jpg";
- }
- if (string.Equals(viewType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
- {
- //return urlPrefix + "homevideos.jpg";
- }
- if (string.Equals(viewType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
- {
- return urlPrefix + "musicvideos.jpg";
- }
- if (string.Equals(viewType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
- {
- //return urlPrefix + "collections.jpg";
- }
- if (string.IsNullOrWhiteSpace(viewType))
- {
- //return urlPrefix + "generic.jpg";
- }
-
- return null;
- }
-
- public string Name
- {
- get { return "Default Image Provider"; }
- }
-
- public bool Supports(IHasImages item)
- {
- var view = item as UserView;
-
- if (view != null)
- {
- return !string.IsNullOrWhiteSpace(GetImageUrl(view.ViewType));
- }
-
- var folder = item as ICollectionFolder;
-
- if (folder != null)
- {
- return !string.IsNullOrWhiteSpace(GetImageUrl(folder.CollectionType));
- }
-
- return false;
- }
-
- public Task GetImageResponse(string url, CancellationToken cancellationToken)
- {
- return _httpClient.GetResponse(new HttpRequestOptions
- {
- CancellationToken = cancellationToken,
- Url = url,
- ResourcePool = GenreImageProvider.ImageDownloadResourcePool
- });
- }
-
- public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
- {
- return GetSupportedImages(item).Any(i => !item.HasImage(i));
- }
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/Folders/FolderMetadataService.cs b/MediaBrowser.Providers/Folders/FolderMetadataService.cs
index e938297b76..8c4737fc4a 100644
--- a/MediaBrowser.Providers/Folders/FolderMetadataService.cs
+++ b/MediaBrowser.Providers/Folders/FolderMetadataService.cs
@@ -12,10 +12,6 @@ namespace MediaBrowser.Providers.Folders
{
public class FolderMetadataService : MetadataService
{
- public FolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
public override int Order
{
get
@@ -29,5 +25,9 @@ namespace MediaBrowser.Providers.Folders
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
+
+ public FolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/Folders/UserViewMetadataService.cs b/MediaBrowser.Providers/Folders/UserViewMetadataService.cs
index 7c298a3ed4..b8f58307a4 100644
--- a/MediaBrowser.Providers/Folders/UserViewMetadataService.cs
+++ b/MediaBrowser.Providers/Folders/UserViewMetadataService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.Folders
{
public class UserViewMetadataService : MetadataService
{
- public UserViewMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public UserViewMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs b/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs
index f80691d724..fb2244e327 100644
--- a/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs
+++ b/MediaBrowser.Providers/GameGenres/GameGenreMetadataService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.GameGenres
{
public class GameGenreMetadataService : MetadataService
{
- public GameGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public GameGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/Games/GameMetadataService.cs b/MediaBrowser.Providers/Games/GameMetadataService.cs
index 23284b84ef..a44f1d95f8 100644
--- a/MediaBrowser.Providers/Games/GameMetadataService.cs
+++ b/MediaBrowser.Providers/Games/GameMetadataService.cs
@@ -12,10 +12,6 @@ namespace MediaBrowser.Providers.Games
{
public class GameMetadataService : MetadataService
{
- public GameMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
@@ -33,5 +29,9 @@ namespace MediaBrowser.Providers.Games
targetItem.PlayersSupported = sourceItem.PlayersSupported;
}
}
+
+ public GameMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/Games/GameSystemMetadataService.cs b/MediaBrowser.Providers/Games/GameSystemMetadataService.cs
index a70b5c7fed..6cf2a45a47 100644
--- a/MediaBrowser.Providers/Games/GameSystemMetadataService.cs
+++ b/MediaBrowser.Providers/Games/GameSystemMetadataService.cs
@@ -12,10 +12,6 @@ namespace MediaBrowser.Providers.Games
{
public class GameSystemMetadataService : MetadataService
{
- public GameSystemMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
@@ -28,5 +24,9 @@ namespace MediaBrowser.Providers.Games
targetItem.GameSystemName = sourceItem.GameSystemName;
}
}
+
+ public GameSystemMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/Genres/GenreMetadataService.cs b/MediaBrowser.Providers/Genres/GenreMetadataService.cs
index 7aba931a22..d4ea3e9cf8 100644
--- a/MediaBrowser.Providers/Genres/GenreMetadataService.cs
+++ b/MediaBrowser.Providers/Genres/GenreMetadataService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.Genres
{
public class GenreMetadataService : MetadataService
{
- public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/LiveTv/AudioRecordingService.cs b/MediaBrowser.Providers/LiveTv/AudioRecordingService.cs
index 4ccbb91165..1d99a678ba 100644
--- a/MediaBrowser.Providers/LiveTv/AudioRecordingService.cs
+++ b/MediaBrowser.Providers/LiveTv/AudioRecordingService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.LiveTv
{
public class AudioRecordingService : MetadataService
{
- public AudioRecordingService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public AudioRecordingService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs b/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs
index 0b9b18bbc5..8abb996895 100644
--- a/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs
+++ b/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.LiveTv
{
public class ChannelMetadataService : MetadataService
{
- public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs
index 0bf4a1b37c..b73d82c19d 100644
--- a/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs
+++ b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.LiveTv
{
public class ProgramMetadataService : MetadataService
{
- public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/LiveTv/VideoRecordingService.cs b/MediaBrowser.Providers/LiveTv/VideoRecordingService.cs
index 47ac546a23..15530f8f99 100644
--- a/MediaBrowser.Providers/LiveTv/VideoRecordingService.cs
+++ b/MediaBrowser.Providers/LiveTv/VideoRecordingService.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.LiveTv
{
public class VideoRecordingService : MetadataService
{
- public VideoRecordingService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
- protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
+ public VideoRecordingService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
}
}
diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs
index bd1961143e..465677efb6 100644
--- a/MediaBrowser.Providers/Manager/ImageSaver.cs
+++ b/MediaBrowser.Providers/Manager/ImageSaver.cs
@@ -161,6 +161,8 @@ namespace MediaBrowser.Providers.Manager
{
var currentPath = currentImage.Path;
+ _logger.Debug("Deleting previous image {0}", currentPath);
+
_libraryMonitor.ReportFileSystemChangeBeginning(currentPath);
try
@@ -276,7 +278,7 @@ namespace MediaBrowser.Providers.Manager
/// IEnumerable{System.String}.
private string[] GetSavePaths(IHasImages item, ImageType type, int? imageIndex, string mimeType, bool saveLocally)
{
- if (_config.Configuration.ImageSavingConvention == ImageSavingConvention.Legacy || !saveLocally)
+ if (!saveLocally || (_config.Configuration.ImageSavingConvention == ImageSavingConvention.Legacy))
{
return new[] { GetStandardSavePath(item, type, imageIndex, mimeType, saveLocally) };
}
@@ -375,11 +377,11 @@ namespace MediaBrowser.Providers.Manager
}
string filename;
- var folderName = item is MusicAlbum ||
- item is MusicArtist ||
- item is PhotoAlbum ||
- (saveLocally && _config.Configuration.ImageSavingConvention == ImageSavingConvention.Legacy) ?
- "folder" :
+ var folderName = item is MusicAlbum ||
+ item is MusicArtist ||
+ item is PhotoAlbum ||
+ (saveLocally && _config.Configuration.ImageSavingConvention == ImageSavingConvention.Legacy) ?
+ "folder" :
"poster";
switch (type)
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index 7184302f19..678d495cbc 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
@@ -12,11 +11,6 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
-using MediaBrowser.Controller.Channels;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.Playlists;
using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Manager
@@ -28,95 +22,26 @@ namespace MediaBrowser.Providers.Manager
protected readonly IServerConfigurationManager ServerConfigurationManager;
protected readonly ILogger Logger;
protected readonly IProviderManager ProviderManager;
- protected readonly IProviderRepository ProviderRepo;
protected readonly IFileSystem FileSystem;
protected readonly IUserDataManager UserDataManager;
protected readonly ILibraryManager LibraryManager;
- protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager)
+ protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager)
{
ServerConfigurationManager = serverConfigurationManager;
Logger = logger;
ProviderManager = providerManager;
- ProviderRepo = providerRepo;
FileSystem = fileSystem;
UserDataManager = userDataManager;
LibraryManager = libraryManager;
}
- ///
- /// Saves the provider result.
- ///
- /// The item.
- /// The result.
- /// The directory service.
- /// Task.
- protected Task SaveProviderResult(TItemType item, MetadataStatus result, IDirectoryService directoryService)
- {
- result.ItemId = item.Id;
-
- //var locationType = item.LocationType;
-
- //if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
- //{
- // if (!string.IsNullOrWhiteSpace(item.Path))
- // {
- // var file = directoryService.GetFile(item.Path);
-
- // if ((file.Attributes & FileAttributes.Directory) != FileAttributes.Directory && file.Exists)
- // {
- // result.ItemDateModified = FileSystem.GetLastWriteTimeUtc(file);
- // }
- // }
- //}
-
- result.ItemDateModified = item.DateModified;
-
- if (EnableDateLastRefreshed(item))
- {
- return Task.FromResult(true);
- }
-
- return ProviderRepo.SaveMetadataStatus(result, CancellationToken.None);
- }
-
- ///
- /// Gets the last result.
- ///
- /// The item.
- /// ProviderResult.
- protected MetadataStatus GetLastResult(IHasMetadata item)
- {
- if (GetLastRefreshDate(item) == default(DateTime))
- {
- return new MetadataStatus { ItemId = item.Id };
- }
-
- if (EnableDateLastRefreshed(item) && item.DateModifiedDuringLastRefresh.HasValue)
- {
- return new MetadataStatus
- {
- ItemId = item.Id,
- DateLastImagesRefresh = item.DateLastRefreshed,
- DateLastMetadataRefresh = item.DateLastRefreshed,
- ItemDateModified = item.DateModifiedDuringLastRefresh.Value
- };
- }
-
- var result = ProviderRepo.GetMetadataStatus(item.Id) ?? new MetadataStatus { ItemId = item.Id };
-
- item.DateModifiedDuringLastRefresh = result.ItemDateModified;
-
- return result;
- }
-
public async Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
{
var itemOfType = (TItemType)item;
var config = ProviderManager.GetMetadataOptions(item);
var updateType = ItemUpdateType.None;
- var refreshResult = GetLastResult(item);
var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem);
var localImagesFailed = false;
@@ -153,12 +78,10 @@ namespace MediaBrowser.Providers.Manager
// TODO: If this returns true, should we instead just change metadata refresh mode to Full?
requiresRefresh = item.RequiresRefresh();
- var providers = GetProviders(item, refreshResult, refreshOptions, requiresRefresh)
+ var providers = GetProviders(item, refreshOptions, requiresRefresh)
.ToList();
- var dateLastRefresh = EnableDateLastRefreshed(item)
- ? item.DateLastRefreshed
- : refreshResult.DateLastMetadataRefresh ?? default(DateTime);
+ var dateLastRefresh = item.DateLastRefreshed;
if (providers.Count > 0 || dateLastRefresh == default(DateTime))
{
@@ -185,13 +108,11 @@ namespace MediaBrowser.Providers.Manager
updateType = updateType | result.UpdateType;
if (result.Failures == 0)
{
- refreshResult.SetDateLastMetadataRefresh(DateTime.UtcNow);
hasRefreshedMetadata = true;
}
else
{
hasRefreshedMetadata = false;
- refreshResult.SetDateLastMetadataRefresh(null);
}
}
}
@@ -199,7 +120,7 @@ namespace MediaBrowser.Providers.Manager
// Next run remote image providers, but only if local image providers didn't throw an exception
if (!localImagesFailed && refreshOptions.ImageRefreshMode != ImageRefreshMode.ValidationOnly)
{
- var providers = GetNonLocalImageProviders(item, allImageProviders, refreshResult, refreshOptions).ToList();
+ var providers = GetNonLocalImageProviders(item, allImageProviders, refreshOptions).ToList();
if (providers.Count > 0)
{
@@ -208,13 +129,11 @@ namespace MediaBrowser.Providers.Manager
updateType = updateType | result.UpdateType;
if (result.Failures == 0)
{
- refreshResult.SetDateLastImagesRefresh(DateTime.UtcNow);
hasRefreshedImages = true;
}
else
{
hasRefreshedImages = false;
- refreshResult.SetDateLastImagesRefresh(null);
}
}
}
@@ -248,11 +167,6 @@ namespace MediaBrowser.Providers.Manager
await SaveItem(metadataResult, updateType, cancellationToken).ConfigureAwait(false);
}
- if (updateType > ItemUpdateType.None || refreshResult.IsDirty)
- {
- await SaveProviderResult(itemOfType, refreshResult, refreshOptions.DirectoryService).ConfigureAwait(false);
- }
-
await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false);
return updateType;
@@ -265,61 +179,9 @@ namespace MediaBrowser.Providers.Manager
lookupInfo.Year = result.ProductionYear;
}
- private async Task FindIdentities(TIdType id, CancellationToken cancellationToken)
- {
- try
- {
- await ItemIdentifier.FindIdentities(id, ProviderManager, cancellationToken).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error in FindIdentities", ex);
- }
- }
-
private DateTime GetLastRefreshDate(IHasMetadata item)
{
- if (EnableDateLastRefreshed(item))
- {
- return item.DateLastRefreshed;
- }
-
- return item.DateLastSaved;
- }
-
- private bool EnableDateLastRefreshed(IHasMetadata item)
- {
- if (ServerConfigurationManager.Configuration.EnableDateLastRefresh)
- {
- return true;
- }
-
- if (item.DateLastRefreshed != default(DateTime))
- {
- return true;
- }
-
- if (!(item is Audio) && !(item is Video))
- {
- return true;
- }
-
- if (item is IItemByName)
- {
- return true;
- }
-
- if (item.SourceType != SourceType.Library)
- {
- return true;
- }
-
- if (item is MusicVideo)
- {
- return true;
- }
-
- return false;
+ return item.DateLastRefreshed;
}
protected async Task SaveItem(MetadataResult result, ItemUpdateType reason, CancellationToken cancellationToken)
@@ -466,14 +328,12 @@ namespace MediaBrowser.Providers.Manager
/// Gets the providers.
///
/// IEnumerable{`0}.
- protected IEnumerable GetProviders(IHasMetadata item, MetadataStatus status, MetadataRefreshOptions options, bool requiresRefresh)
+ protected IEnumerable GetProviders(IHasMetadata item, MetadataRefreshOptions options, bool requiresRefresh)
{
// Get providers to refresh
var providers = ((ProviderManager)ProviderManager).GetMetadataProviders(item).ToList();
- var dateLastRefresh = EnableDateLastRefreshed(item)
- ? item.DateLastRefreshed
- : status.DateLastMetadataRefresh ?? default(DateTime);
+ var dateLastRefresh = item.DateLastRefreshed;
// Run all if either of these flags are true
var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime) || requiresRefresh;
@@ -535,14 +395,12 @@ namespace MediaBrowser.Providers.Manager
return providers;
}
- protected virtual IEnumerable GetNonLocalImageProviders(IHasMetadata item, IEnumerable allImageProviders, MetadataStatus status, ImageRefreshOptions options)
+ protected virtual IEnumerable GetNonLocalImageProviders(IHasMetadata item, IEnumerable allImageProviders, ImageRefreshOptions options)
{
// Get providers to refresh
var providers = allImageProviders.Where(i => !(i is ILocalImageProvider)).ToList();
- var dateLastImageRefresh = EnableDateLastRefreshed(item)
- ? item.DateLastRefreshed
- : status.DateLastImagesRefresh ?? default(DateTime);
+ var dateLastImageRefresh = item.DateLastRefreshed;
// Run all if either of these flags are true
var runAllProviders = options.ImageRefreshMode == ImageRefreshMode.FullRefresh || dateLastImageRefresh == default(DateTime);
@@ -552,12 +410,6 @@ namespace MediaBrowser.Providers.Manager
providers = providers
.Where(i =>
{
- var hasChangeMonitor = i as IHasChangeMonitor;
- if (hasChangeMonitor != null)
- {
- return HasChanged(item, hasChangeMonitor, dateLastImageRefresh, options.DirectoryService);
- }
-
var hasFileChangeMonitor = i as IHasItemChangeMonitor;
if (hasFileChangeMonitor != null)
{
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index c95d58a421..0f0745d1bc 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -55,8 +55,6 @@ namespace MediaBrowser.Providers.Manager
private readonly IFileSystem _fileSystem;
private IMetadataService[] _metadataServices = { };
- private IItemIdentityProvider[] _identityProviders = { };
- private IItemIdentityConverter[] _identityConverters = { };
private IMetadataProvider[] _metadataProviders = { };
private IEnumerable _savers;
private IImageSaver[] _imageSavers;
@@ -92,22 +90,17 @@ namespace MediaBrowser.Providers.Manager
///
/// The image providers.
/// The metadata services.
- /// The identity providers.
- /// The identity converters.
/// The metadata providers.
/// The metadata savers.
/// The image savers.
/// The external ids.
public void AddParts(IEnumerable imageProviders, IEnumerable metadataServices,
- IEnumerable identityProviders, IEnumerable identityConverters,
IEnumerable metadataProviders, IEnumerable metadataSavers,
IEnumerable imageSavers, IEnumerable externalIds)
{
ImageProviders = imageProviders.ToArray();
_metadataServices = metadataServices.OrderBy(i => i.Order).ToArray();
- _identityProviders = identityProviders.ToArray();
- _identityConverters = identityConverters.ToArray();
_metadataProviders = metadataProviders.ToArray();
_imageSavers = imageSavers.ToArray();
_externalIds = externalIds.OrderBy(i => i.Name).ToArray();
@@ -301,18 +294,6 @@ namespace MediaBrowser.Providers.Manager
.ThenBy(GetDefaultOrder);
}
- public IEnumerable> GetItemIdentityProviders()
- where TLookupInfo : ItemLookupInfo
- {
- return _identityProviders.OfType>();
- }
-
- public IEnumerable> GetItemIdentityConverters()
- where TLookupInfo : ItemLookupInfo
- {
- return _identityConverters.OfType>();
- }
-
private IEnumerable GetRemoteImageProviders(IHasImages item, bool includeDisabled)
{
var options = GetMetadataOptions(item);
@@ -849,7 +830,7 @@ namespace MediaBrowser.Providers.Manager
});
}
- public IEnumerable GetExternalUrls(IHasProviderIds item)
+ public IEnumerable GetExternalUrls(BaseItem item)
{
return GetExternalIds(item)
.Select(i =>
@@ -872,7 +853,7 @@ namespace MediaBrowser.Providers.Manager
Url = string.Format(i.UrlFormatString, value)
};
- }).Where(i => i != null);
+ }).Where(i => i != null).Concat(item.GetRelatedUrls());
}
public IEnumerable GetExternalIdInfos(IHasProviderIds item)
diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs
index 59a2da4603..5f23cf69c9 100644
--- a/MediaBrowser.Providers/Manager/ProviderUtils.cs
+++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs
@@ -151,29 +151,17 @@ namespace MediaBrowser.Providers.Manager
if (!lockedFields.Contains(MetadataFields.Tags))
{
- var sourceHasTags = source as IHasTags;
- var targetHasTags = target as IHasTags;
-
- if (sourceHasTags != null && targetHasTags != null)
+ if (replaceData || target.Tags.Count == 0)
{
- if (replaceData || targetHasTags.Tags.Count == 0)
- {
- targetHasTags.Tags = sourceHasTags.Tags;
- }
+ target.Tags = source.Tags;
}
}
if (!lockedFields.Contains(MetadataFields.Keywords))
{
- var sourceHasKeywords = source as IHasKeywords;
- var targetHasKeywords = target as IHasKeywords;
-
- if (sourceHasKeywords != null && targetHasKeywords != null)
+ if (replaceData || target.Keywords.Count == 0)
{
- if (replaceData || targetHasKeywords.Keywords.Count == 0)
- {
- targetHasKeywords.Keywords = sourceHasKeywords.Keywords;
- }
+ target.Keywords = source.Keywords;
}
}
diff --git a/MediaBrowser.Providers/Manager/SeriesOrderManager.cs b/MediaBrowser.Providers/Manager/SeriesOrderManager.cs
deleted file mode 100644
index 1050bdbbd6..0000000000
--- a/MediaBrowser.Providers/Manager/SeriesOrderManager.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Providers;
-
-namespace MediaBrowser.Providers.Manager
-{
- public class SeriesOrderManager : ISeriesOrderManager
- {
- private Dictionary _providers;
-
- public void AddParts(IEnumerable orderProviders)
- {
- _providers = orderProviders
- .GroupBy(p => p.OrderType)
- .ToDictionary(g => g.Key, g => g.ToArray());
- }
-
- public async Task FindSeriesIndex(string orderType, string seriesName)
- {
- ISeriesOrderProvider[] providers;
- if (!_providers.TryGetValue(orderType, out providers))
- return null;
-
- foreach (ISeriesOrderProvider provider in providers)
- {
- int? index = await provider.FindSeriesIndex(seriesName);
- if (index != null)
- return index;
- }
-
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index f07478f986..99d8b15b69 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -89,7 +89,6 @@
-
@@ -104,7 +103,6 @@
-
@@ -145,10 +143,7 @@
-
-
-
@@ -168,7 +163,6 @@
-
@@ -182,7 +176,6 @@
-
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs b/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs
deleted file mode 100644
index 5262f8e3b1..0000000000
--- a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Providers.Music;
-using MediaBrowser.Providers.TV;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using CommonIO;
-
-namespace MediaBrowser.Providers.Movies
-{
- class FanartMovieUpdatesPostScanTask : ILibraryPostScanTask
- {
- private const string UpdatesUrl = "https://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}";
-
- ///
- /// The _HTTP client
- ///
- private readonly IHttpClient _httpClient;
- ///
- /// The _logger
- ///
- private readonly ILogger _logger;
- ///
- /// The _config
- ///
- private readonly IServerConfigurationManager _config;
- private readonly IJsonSerializer _jsonSerializer;
- private readonly IFileSystem _fileSystem;
-
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- public FanartMovieUpdatesPostScanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IFileSystem fileSystem)
- {
- _jsonSerializer = jsonSerializer;
- _config = config;
- _logger = logger;
- _httpClient = httpClient;
- _fileSystem = fileSystem;
- }
-
- ///
- /// Runs the specified progress.
- ///
- /// The progress.
- /// The cancellation token.
- /// Task.
- public async Task Run(IProgress progress, CancellationToken cancellationToken)
- {
- var options = FanartSeriesProvider.Current.GetFanartOptions();
-
- if (!options.EnableAutomaticUpdates)
- {
- progress.Report(100);
- return;
- }
-
- var path = FanartMovieImageProvider.GetMoviesDataPath(_config.CommonApplicationPaths);
-
- _fileSystem.CreateDirectory(path);
-
- var timestampFile = Path.Combine(path, "time.txt");
-
- var timestampFileInfo = _fileSystem.GetFileInfo(timestampFile);
-
- // Don't check for updates every single time
- if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 3)
- {
- return;
- }
-
- // Find out the last time we queried for updates
- var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty;
-
- var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList();
-
- // If this is our first time, don't do any updates and just record the timestamp
- if (!string.IsNullOrEmpty(lastUpdateTime))
- {
- var moviesToUpdate = await GetMovieIdsToUpdate(existingDirectories, lastUpdateTime, options, cancellationToken).ConfigureAwait(false);
-
- progress.Report(5);
-
- await UpdateMovies(moviesToUpdate, progress, cancellationToken).ConfigureAwait(false);
- }
-
- var newUpdateTime = Convert.ToInt64(DateTimeToUnixTimestamp(DateTime.UtcNow)).ToString(UsCulture);
-
- _fileSystem.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8);
-
- progress.Report(100);
- }
-
- private async Task> GetMovieIdsToUpdate(IEnumerable existingIds, string lastUpdateTime, FanartOptions options, CancellationToken cancellationToken)
- {
- var url = string.Format(UpdatesUrl, FanartArtistProvider.ApiKey, lastUpdateTime);
-
- var clientKey = options.UserApiKey;
- if (!string.IsNullOrWhiteSpace(clientKey))
- {
- url += "&client_key=" + clientKey;
- }
-
- // First get last time
- using (var stream = await _httpClient.Get(new HttpRequestOptions
- {
- Url = url,
- CancellationToken = cancellationToken,
- EnableHttpCompression = true,
- ResourcePool = FanartArtistProvider.Current.FanArtResourcePool
-
- }).ConfigureAwait(false))
- {
- using (var reader = new StreamReader(stream))
- {
- var json = await reader.ReadToEndAsync().ConfigureAwait(false);
-
- // If empty fanart will return a string of "null", rather than an empty list
- if (string.Equals(json, "null", StringComparison.OrdinalIgnoreCase))
- {
- return new List();
- }
-
- var updates = _jsonSerializer.DeserializeFromString>(json);
-
- var existingDictionary = existingIds.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
-
- return updates.SelectMany(i =>
- {
- var list = new List();
-
- if (!string.IsNullOrWhiteSpace(i.imdb_id))
- {
- list.Add(i.imdb_id);
- }
- if (!string.IsNullOrWhiteSpace(i.tmdb_id))
- {
- list.Add(i.tmdb_id);
- }
-
- return list;
-
- }).Where(existingDictionary.ContainsKey);
- }
- }
- }
-
- private async Task UpdateMovies(IEnumerable idList, IProgress progress, CancellationToken cancellationToken)
- {
- var list = idList.ToList();
- var numComplete = 0;
-
- foreach (var id in list)
- {
- _logger.Info("Updating movie " + id);
-
- await FanartMovieImageProvider.Current.DownloadMovieJson(id, cancellationToken).ConfigureAwait(false);
-
- numComplete++;
- double percent = numComplete;
- percent /= list.Count;
- percent *= 95;
-
- progress.Report(percent + 5);
- }
- }
-
- ///
- /// Dates the time to unix timestamp.
- ///
- /// The date time.
- /// System.Double.
- private static double DateTimeToUnixTimestamp(DateTime dateTime)
- {
- return (dateTime - new DateTime(1970, 1, 1).ToUniversalTime()).TotalSeconds;
- }
-
- public class RootObject
- {
- public string tmdb_id { get; set; }
- public string imdb_id { get; set; }
- public string name { get; set; }
- public string new_images { get; set; }
- public string total_images { get; set; }
- }
- }
-}
diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
index 775e6dfb9c..18f1779325 100644
--- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
@@ -24,7 +24,7 @@ using MediaBrowser.Providers.TV;
namespace MediaBrowser.Providers.Movies
{
- public class FanartMovieImageProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder
+ public class FanartMovieImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly IServerConfigurationManager _config;
@@ -241,33 +241,6 @@ namespace MediaBrowser.Providers.Movies
});
}
- public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
- {
- var options = FanartSeriesProvider.Current.GetFanartOptions();
- if (!options.EnableAutomaticUpdates)
- {
- return false;
- }
-
- var id = item.GetProviderId(MetadataProviders.Tmdb);
- if (string.IsNullOrEmpty(id))
- {
- id = item.GetProviderId(MetadataProviders.Imdb);
- }
-
- if (!string.IsNullOrEmpty(id))
- {
- // Process images
- var path = GetFanartJsonPath(id);
-
- var fileInfo = _fileSystem.GetFileInfo(path);
-
- return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
- }
-
- return false;
- }
-
///
/// Gets the movie data path.
///
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index d13716cba1..a6b6de7e51 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -314,11 +314,7 @@ namespace MediaBrowser.Providers.Movies
if (movieData.keywords != null && movieData.keywords.keywords != null)
{
- var hasTags = movie as IHasKeywords;
- if (hasTags != null)
- {
- hasTags.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList();
- }
+ movie.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList();
}
if (movieData.trailers != null && movieData.trailers.youtube != null &&
@@ -330,8 +326,7 @@ namespace MediaBrowser.Providers.Movies
hasTrailers.RemoteTrailers = movieData.trailers.youtube.Select(i => new MediaUrl
{
Url = string.Format("https://www.youtube.com/watch?v={0}", i.source),
- Name = i.name,
- VideoSize = string.Equals("hd", i.size, StringComparison.OrdinalIgnoreCase) ? VideoSize.HighDefinition : VideoSize.StandardDefinition
+ Name = i.name
}).ToList();
}
diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
index 5958c3a0ad..49f341f26f 100644
--- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
@@ -17,7 +17,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Movies
{
- class MovieDbImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor
+ class MovieDbImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IJsonSerializer _jsonSerializer;
private readonly IHttpClient _httpClient;
@@ -63,6 +63,8 @@ namespace MediaBrowser.Providers.Movies
{
var list = new List();
+ var language = item.GetPreferredMetadataLanguage();
+
var results = await FetchImages((BaseItem)item, null, _jsonSerializer, cancellationToken).ConfigureAwait(false);
if (results == null)
@@ -85,7 +87,7 @@ namespace MediaBrowser.Providers.Movies
VoteCount = i.vote_count,
Width = i.width,
Height = i.height,
- Language = i.iso_639_1,
+ Language = MovieDbProvider.AdjustImageLanguage(i.iso_639_1, language),
ProviderName = Name,
Type = ImageType.Primary,
RatingType = RatingType.Score
@@ -107,8 +109,6 @@ namespace MediaBrowser.Providers.Movies
}));
}
- var language = item.GetPreferredMetadataLanguage();
-
var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase);
return list.OrderByDescending(i =>
@@ -221,10 +221,5 @@ namespace MediaBrowser.Providers.Movies
ResourcePool = MovieDbProvider.Current.MovieDbResourcePool
});
}
-
- public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
- {
- return MovieDbProvider.Current.HasChanged(item);
- }
}
}
diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
index c588a9a690..27b61225bd 100644
--- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
@@ -267,9 +267,21 @@ namespace MediaBrowser.Providers.Movies
if (!string.IsNullOrEmpty(preferredLanguage))
{
+ preferredLanguage = NormalizeLanguage(preferredLanguage);
+
languages.Add(preferredLanguage);
+
+ if (preferredLanguage.Length == 5) // like en-US
+ {
+ // Currenty, TMDB supports 2-letter language codes only
+ // They are planning to change this in the future, thus we're
+ // supplying both codes if we're having a 5-letter code.
+ languages.Add(preferredLanguage.Substring(0, 2));
+ }
}
+
languages.Add("null");
+
if (!string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase))
{
languages.Add("en");
@@ -280,18 +292,35 @@ namespace MediaBrowser.Providers.Movies
public static string NormalizeLanguage(string language)
{
- // They require this to be uppercase
- // https://emby.media/community/index.php?/topic/32454-fr-follow-tmdbs-new-language-api-update/?p=311148
- var parts = language.Split('-');
-
- if (parts.Length == 2)
+ if (!string.IsNullOrEmpty(language))
{
- language = parts[0] + "-" + parts[1].ToUpper();
+ // They require this to be uppercase
+ // https://emby.media/community/index.php?/topic/32454-fr-follow-tmdbs-new-language-api-update/?p=311148
+ var parts = language.Split('-');
+
+ if (parts.Length == 2)
+ {
+ language = parts[0] + "-" + parts[1].ToUpper();
+ }
}
return language;
}
+ public static string AdjustImageLanguage(string imageLanguage, string requestLanguage)
+ {
+ if (!string.IsNullOrEmpty(imageLanguage)
+ && !string.IsNullOrEmpty(requestLanguage)
+ && requestLanguage.Length > 2
+ && imageLanguage.Length == 2
+ && requestLanguage.StartsWith(imageLanguage, StringComparison.OrdinalIgnoreCase))
+ {
+ return requestLanguage;
+ }
+
+ return imageLanguage;
+ }
+
///
/// Fetches the main result.
///
@@ -409,33 +438,6 @@ namespace MediaBrowser.Providers.Movies
return await _httpClient.Get(options).ConfigureAwait(false);
}
- public TheMovieDbOptions GetTheMovieDbOptions()
- {
- return _configurationManager.GetConfiguration("themoviedb");
- }
-
- public bool HasChanged(IHasMetadata item)
- {
- if (!GetTheMovieDbOptions().EnableAutomaticUpdates)
- {
- return false;
- }
-
- var tmdbId = item.GetProviderId(MetadataProviders.Tmdb);
-
- if (!String.IsNullOrEmpty(tmdbId))
- {
- // Process images
- var dataFilePath = GetDataFilePath(tmdbId, item.GetPreferredMetadataLanguage());
-
- var fileInfo = _fileSystem.GetFileInfo(dataFilePath);
-
- return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed;
- }
-
- return false;
- }
-
public void Dispose()
{
Dispose(true);
@@ -659,19 +661,4 @@ namespace MediaBrowser.Providers.Movies
});
}
}
-
- public class TmdbConfigStore : IConfigurationFactory
- {
- public IEnumerable GetConfigurations()
- {
- return new List
- {
- new ConfigurationStore
- {
- Key = "themoviedb",
- ConfigurationType = typeof(TheMovieDbOptions)
- }
- };
- }
- }
}
diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs
index ceb41178e1..ab2cd3bedd 100644
--- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies
internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669";
internal static string AcceptHeader = "application/json,image/*";
-
+
private readonly ILogger _logger;
private readonly IJsonSerializer _json;
private readonly ILibraryManager _libraryManager;
@@ -54,6 +54,11 @@ namespace MediaBrowser.Providers.Movies
var name = idInfo.Name;
var year = idInfo.Year;
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ return new List();
+ }
+
var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original";
@@ -73,7 +78,7 @@ namespace MediaBrowser.Providers.Movies
//var searchType = item is BoxSet ? "collection" : "movie";
var results = await GetSearchResults(name, searchType, year, language, tmdbImageUrl, cancellationToken).ConfigureAwait(false);
-
+
if (results.Count == 0)
{
//try in english if wasn't before
@@ -123,19 +128,23 @@ namespace MediaBrowser.Providers.Movies
});
}
- private async Task> GetSearchResults(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken)
+ private Task> GetSearchResults(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken)
{
switch (type)
{
case "tv":
- return await GetSearchResultsTv(name, year, language, baseImageUrl, cancellationToken);
+ return GetSearchResultsTv(name, year, language, baseImageUrl, cancellationToken);
default:
- return await GetSearchResultsGeneric(name, type, year, language, baseImageUrl, cancellationToken);
+ return GetSearchResultsGeneric(name, type, year, language, baseImageUrl, cancellationToken);
}
}
private async Task> GetSearchResultsGeneric(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken)
{
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentException("name");
+ }
var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, type);
@@ -189,6 +198,11 @@ namespace MediaBrowser.Providers.Movies
private async Task> GetSearchResultsTv(string name, int? year, string language, string baseImageUrl, CancellationToken cancellationToken)
{
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentException("name");
+ }
+
var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, "tv");
using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
diff --git a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
index 5fb3ea3696..1d8691ab8e 100644
--- a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
@@ -33,11 +33,6 @@ namespace MediaBrowser.Providers.Movies
get { return MovieDbProvider.Current.Name; }
}
- public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
- {
- return MovieDbProvider.Current.HasChanged(item);
- }
-
public int Order
{
get
diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs
index 3bceb976e7..a6b7bde6fa 100644
--- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs
+++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs
@@ -148,6 +148,13 @@ namespace MediaBrowser.Providers.Movies
public bool Supports(IHasProviderIds item)
{
+ // Supports images for tv movies
+ var tvProgram = item as LiveTvProgram;
+ if (tvProgram != null && tvProgram.IsMovie)
+ {
+ return true;
+ }
+
return item is Movie || item is MusicVideo || item is Series || item is Episode || item is Trailer;
}
}
diff --git a/MediaBrowser.Providers/Movies/MovieMetadataService.cs b/MediaBrowser.Providers/Movies/MovieMetadataService.cs
index e70ec00576..83be9ca6f9 100644
--- a/MediaBrowser.Providers/Movies/MovieMetadataService.cs
+++ b/MediaBrowser.Providers/Movies/MovieMetadataService.cs
@@ -13,10 +13,6 @@ namespace MediaBrowser.Providers.Movies
{
public class MovieMetadataService : MetadataService
{
- public MovieMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
protected override bool IsFullLocalMetadata(Movie item)
{
if (string.IsNullOrWhiteSpace(item.Overview))
@@ -42,15 +38,14 @@ namespace MediaBrowser.Providers.Movies
targetItem.CollectionName = sourceItem.CollectionName;
}
}
- }
- public class TrailerMetadataService : MetadataService
- {
- public TrailerMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager)
- : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
+ public MovieMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
}
+ }
+ public class TrailerMetadataService : MetadataService
+ {
protected override bool IsFullLocalMetadata(Trailer item)
{
if (string.IsNullOrWhiteSpace(item.Overview))
@@ -73,6 +68,10 @@ namespace MediaBrowser.Providers.Movies
target.Item.TrailerTypes = source.Item.TrailerTypes;
}
}
+
+ public TrailerMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
deleted file mode 100644
index 70c155ad5d..0000000000
--- a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using CommonIO;
-
-namespace MediaBrowser.Providers.Movies
-{
- public class MovieUpdatesPreScanTask : ILibraryPostScanTask
- {
- ///
- /// The updates URL
- ///
- private const string UpdatesUrl = "https://api.themoviedb.org/3/movie/changes?start_date={0}&api_key={1}&page={2}";
-
- ///
- /// The _HTTP client
- ///
- private readonly IHttpClient _httpClient;
- ///
- /// The _logger
- ///
- private readonly ILogger _logger;
- ///
- /// The _config
- ///
- private readonly IServerConfigurationManager _config;
- private readonly IJsonSerializer _json;
- private readonly IFileSystem _fileSystem;
- private readonly ILibraryManager _libraryManager;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The logger.
- /// The HTTP client.
- /// The config.
- /// The json.
- public MovieUpdatesPreScanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IJsonSerializer json, IFileSystem fileSystem, ILibraryManager libraryManager)
- {
- _logger = logger;
- _httpClient = httpClient;
- _config = config;
- _json = json;
- _fileSystem = fileSystem;
- _libraryManager = libraryManager;
- }
-
- protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- ///
- /// Runs the specified progress.
- ///
- /// The progress.
- /// The cancellation token.
- /// Task.
- public async Task Run(IProgress progress, CancellationToken cancellationToken)
- {
- if (!MovieDbProvider.Current.GetTheMovieDbOptions().EnableAutomaticUpdates)
- {
- progress.Report(100);
- return;
- }
-
- var path = MovieDbProvider.GetMoviesDataPath(_config.CommonApplicationPaths);
-
- _fileSystem.CreateDirectory(path);
-
- var timestampFile = Path.Combine(path, "time.txt");
-
- var timestampFileInfo = _fileSystem.GetFileInfo(timestampFile);
-
- // Don't check for updates every single time
- if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 7)
- {
- return;
- }
-
- // Find out the last time we queried tvdb for updates
- var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty;
-
- var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList();
-
- if (!string.IsNullOrEmpty(lastUpdateTime))
- {
- long lastUpdateTicks;
-
- if (long.TryParse(lastUpdateTime, NumberStyles.Any, UsCulture, out lastUpdateTicks))
- {
- var lastUpdateDate = new DateTime(lastUpdateTicks, DateTimeKind.Utc);
-
- // They only allow up to 14 days of updates
- if ((DateTime.UtcNow - lastUpdateDate).TotalDays > 13)
- {
- lastUpdateDate = DateTime.UtcNow.AddDays(-13);
- }
-
- var updatedIds = await GetIdsToUpdate(lastUpdateDate, 1, cancellationToken).ConfigureAwait(false);
-
- var existingDictionary = existingDirectories.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
-
- var idsToUpdate = updatedIds.Where(i => !string.IsNullOrWhiteSpace(i) && existingDictionary.ContainsKey(i));
-
- await UpdateMovies(idsToUpdate, progress, cancellationToken).ConfigureAwait(false);
- }
- }
-
- _fileSystem.WriteAllText(timestampFile, DateTime.UtcNow.Ticks.ToString(UsCulture), Encoding.UTF8);
- progress.Report(100);
- }
-
-
- ///
- /// Gets the ids to update.
- ///
- /// The last update time.
- /// The page.
- /// The cancellation token.
- /// Task{IEnumerable{System.String}}.
- private async Task> GetIdsToUpdate(DateTime lastUpdateTime, int page, CancellationToken cancellationToken)
- {
- bool hasMorePages;
- var list = new List();
-
- // First get last time
- using (var stream = await _httpClient.Get(new HttpRequestOptions
- {
- Url = string.Format(UpdatesUrl, lastUpdateTime.ToString("yyyy-MM-dd"), MovieDbProvider.ApiKey, page),
- CancellationToken = cancellationToken,
- EnableHttpCompression = true,
- ResourcePool = MovieDbProvider.Current.MovieDbResourcePool,
- AcceptHeader = MovieDbProvider.AcceptHeader
-
- }).ConfigureAwait(false))
- {
- var obj = _json.DeserializeFromStream(stream);
-
- var data = obj.results.Select(i => i.id.ToString(UsCulture));
-
- list.AddRange(data);
-
- hasMorePages = page < obj.total_pages;
- }
-
- if (hasMorePages)
- {
- var more = await GetIdsToUpdate(lastUpdateTime, page + 1, cancellationToken).ConfigureAwait(false);
-
- list.AddRange(more);
- }
-
- return list;
- }
-
- ///
- /// Updates the movies.
- ///
- /// The ids.
- /// The progress.
- /// The cancellation token.
- /// Task.
- private async Task UpdateMovies(IEnumerable ids, IProgress progress, CancellationToken cancellationToken)
- {
- var list = ids.ToList();
- var numComplete = 0;
-
- // Gather all movies into a lookup by tmdb id
- var allMovies = _libraryManager.GetItemList(new Controller.Entities.InternalItemsQuery
- {
- IncludeItemTypes = new[] {typeof (Movie).Name},
- Recursive = true
-
- }).Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb)))
- .ToLookup(i => i.GetProviderId(MetadataProviders.Tmdb));
-
- foreach (var id in list)
- {
- // Find the preferred language(s) for the movie in the library
- var languages = allMovies[id]
- .Select(i => i.GetPreferredMetadataLanguage())
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
-
- foreach (var language in languages)
- {
- try
- {
- await UpdateMovie(id, language, cancellationToken).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error updating tmdb movie id {0}, language {1}", ex, id, language);
- }
- }
-
- numComplete++;
- double percent = numComplete;
- percent /= list.Count;
- percent *= 100;
-
- progress.Report(percent);
- }
- }
-
- ///
- /// Updates the movie.
- ///
- /// The id.
- /// The preferred metadata language.
- /// The cancellation token.
- /// Task.
- private Task UpdateMovie(string id, string preferredMetadataLanguage, CancellationToken cancellationToken)
- {
- _logger.Info("Updating movie from tmdb " + id + ", language " + preferredMetadataLanguage);
-
- return MovieDbProvider.Current.DownloadMovieInfo(id, preferredMetadataLanguage, cancellationToken);
- }
-
- class Result
- {
- public int id { get; set; }
- public bool? adult { get; set; }
- }
-
- class RootObject
- {
- public List results { get; set; }
- public int page { get; set; }
- public int total_pages { get; set; }
- public int total_results { get; set; }
-
- public RootObject()
- {
- results = new List();
- }
- }
- }
-}
diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs
index 8f951723e8..4f87b2036b 100644
--- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs
+++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs
@@ -15,10 +15,6 @@ namespace MediaBrowser.Providers.Music
{
public class AlbumMetadataService : MetadataService
{
- public AlbumMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
protected override async Task BeforeSave(MusicAlbum item, bool isFullRefresh, ItemUpdateType currentUpdateType)
{
var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false);
@@ -166,5 +162,9 @@ namespace MediaBrowser.Providers.Music
targetItem.Artists = sourceItem.Artists;
}
}
+
+ public AlbumMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs
index 21e9b006bf..b2f975b131 100644
--- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs
+++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs
@@ -15,10 +15,6 @@ namespace MediaBrowser.Providers.Music
{
public class ArtistMetadataService : MetadataService
{
- public ArtistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
- {
- }
-
protected override async Task BeforeSave(MusicArtist item, bool isFullRefresh, ItemUpdateType currentUpdateType)
{
var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false);
@@ -58,5 +54,9 @@ namespace MediaBrowser.Providers.Music
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
}
+
+ public ArtistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+ {
+ }
}
}
diff --git a/MediaBrowser.Providers/Music/AudioMetadataService.cs b/MediaBrowser.Providers/Music/AudioMetadataService.cs
index 161a161938..5321281869 100644
--- a/MediaBrowser.Providers/Music/AudioMetadataService.cs
+++ b/MediaBrowser.Providers/Music/AudioMetadataService.cs
@@ -12,10 +12,6 @@ namespace MediaBrowser.Providers.Music
{
public class AudioMetadataService : MetadataService