diff --git a/MediaBrowser.Api/LiveTv/LiveTvImageService.cs b/MediaBrowser.Api/LiveTv/LiveTvImageService.cs
deleted file mode 100644
index 65c4e5e23a..0000000000
--- a/MediaBrowser.Api/LiveTv/LiveTvImageService.cs
+++ /dev/null
@@ -1,195 +0,0 @@
-using MediaBrowser.Api.Images;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Controller.Drawing;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using ServiceStack;
-using ServiceStack.Text.Controller;
-using ServiceStack.Web;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Api.LiveTv
-{
- [Route("/LiveTv/Channels/{Id}/Images/{Type}", "POST")]
- [Route("/LiveTv/Channels/{Id}/Images/{Type}/{Index}", "POST")]
- [Api(Description = "Posts an item image")]
- public class PostChannelImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
-
- ///
- /// The raw Http Request Input Stream
- ///
- /// The request stream.
- public Stream RequestStream { get; set; }
- }
-
- [Route("/LiveTv/Channels/{Id}/Images/{Type}", "DELETE")]
- [Route("/LiveTv/Channels/{Id}/Images/{Type}/{Index}", "DELETE")]
- [Api(Description = "Deletes an item image")]
- public class DeleteChannelImage : DeleteImageRequest, IReturnVoid
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
- }
- [Route("/LiveTv/Channels/{Id}/Images/{Type}", "GET")]
- [Route("/LiveTv/Channels/{Id}/Images/{Type}/{Index}", "GET")]
- [Api(Description = "Gets an item image")]
- public class GetChannelImage : ImageRequest
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/LiveTv/Recordings/{Id}/Images/{Type}", "GET")]
- [Route("/LiveTv/Recordings/{Id}/Images/{Type}/{Index}", "GET")]
- [Api(Description = "Gets an item image")]
- public class GetRecordingImage : ImageRequest
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/LiveTv/Programs/{Id}/Images/{Type}", "GET")]
- [Route("/LiveTv/Programs/{Id}/Images/{Type}/{Index}", "GET")]
- [Api(Description = "Gets an item image")]
- public class GetProgramImage : ImageRequest
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "Program Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/LiveTv/Channels/{Id}/Images", "GET")]
- [Api(Description = "Gets information about an item's images")]
- public class GetChannelImageInfos : IReturn>
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- public class LiveTvImageService : BaseApiService
- {
- private readonly ILiveTvManager _liveTv;
-
- private readonly IUserManager _userManager;
-
- private readonly ILibraryManager _libraryManager;
-
- private readonly IApplicationPaths _appPaths;
-
- private readonly IProviderManager _providerManager;
-
- private readonly IItemRepository _itemRepo;
- private readonly IDtoService _dtoService;
- private readonly IImageProcessor _imageProcessor;
-
- public LiveTvImageService(ILiveTvManager liveTv, IUserManager userManager, ILibraryManager libraryManager, IApplicationPaths appPaths, IProviderManager providerManager, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor)
- {
- _liveTv = liveTv;
- _userManager = userManager;
- _libraryManager = libraryManager;
- _appPaths = appPaths;
- _providerManager = providerManager;
- _itemRepo = itemRepo;
- _dtoService = dtoService;
- _imageProcessor = imageProcessor;
- }
-
- public object Get(GetChannelImageInfos request)
- {
- var item = _liveTv.GetInternalChannel(request.Id);
-
- var result = GetImageService().GetItemImageInfos(item);
-
- return ToOptimizedResult(result);
- }
-
- public object Get(GetChannelImage request)
- {
- var item = _liveTv.GetInternalChannel(request.Id);
-
- return GetImageService().GetImage(request, item);
- }
-
- public object Get(GetRecordingImage request)
- {
- var item = _liveTv.GetInternalRecording(request.Id, CancellationToken.None).Result;
-
- return GetImageService().GetImage(request, item);
- }
-
- public object Get(GetProgramImage request)
- {
- var item = _liveTv.GetInternalProgram(request.Id);
-
- return GetImageService().GetImage(request, item);
- }
-
- public void Post(PostChannelImage request)
- {
- var pathInfo = PathInfo.Parse(Request.PathInfo);
- var id = pathInfo.GetArgumentValue(2);
-
- request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue(4), true);
-
- var item = _liveTv.GetInternalChannel(id);
-
- var task = GetImageService().PostImage(item, request.RequestStream, request.Type, Request.ContentType);
-
- Task.WaitAll(task);
- }
-
- public void Delete(DeleteChannelImage request)
- {
- var item = _liveTv.GetInternalChannel(request.Id);
-
- var task = item.DeleteImage(request.Type, request.Index);
-
- Task.WaitAll(task);
- }
-
- private ImageService GetImageService()
- {
- return new ImageService(_userManager, _libraryManager, _appPaths, _providerManager, _itemRepo, _dtoService,
- _imageProcessor)
- {
- ResultFactory = ResultFactory,
- Request = Request
- };
- }
- }
-}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 4fc989fc50..409d152f79 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -90,7 +90,6 @@
-
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 440632825e..0ae96effde 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -163,6 +163,11 @@ namespace MediaBrowser.Api.Playback.Progressive
{
responseHeaders["ContentFeatures.DLNA.ORG"] = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
}
+
+ foreach (var item in responseHeaders)
+ {
+ Request.Response.AddHeader(item.Key, item.Value);
+ }
}
///
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 036ac7e81e..c3a87fc317 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -327,5 +327,11 @@ namespace MediaBrowser.Controller.Library
/// The paths.
/// IEnumerable{System.String}.
IEnumerable NormalizeRootPathList(IEnumerable paths);
+
+ ///
+ /// Registers the item.
+ ///
+ /// The item.
+ void RegisterItem(BaseItem item);
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs
index da74b9ccd0..a65710851f 100644
--- a/MediaBrowser.Mono.userprefs
+++ b/MediaBrowser.Mono.userprefs
@@ -4,7 +4,7 @@
-
+
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 6b87f1dfed..e686e7eda0 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -45,6 +45,12 @@
v4.5
+
+ ..\packages\MediaBrowser.BdInfo.1.0.0.7\lib\net35\BDInfo.dll
+
+
+ ..\packages\MediaBrowser.BdInfo.1.0.0.7\lib\net35\DvdLib.dll
+
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs
index 8e07bc2667..e386c78a4a 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.MediaInfo;
+using DvdLib.Ifo;
+using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Localization;
@@ -132,12 +133,30 @@ namespace MediaBrowser.Providers.MediaInfo
if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
{
- PopulateDvdStreamFiles(item, mount);
+ FetchFromDvdLib(item, mount);
}
base.OnPreFetch(item, mount);
}
+ private void FetchFromDvdLib(Video item, IIsoMount mount)
+ {
+ var path = mount == null ? item.Path : mount.MountedPath;
+ var dvd = new Dvd(path);
+
+ item.RunTimeTicks = dvd.Titles.Select(GetRuntime).Max();
+
+ PopulateDvdStreamFiles(item, mount);
+ }
+
+ private long GetRuntime(Title title)
+ {
+ return title.ProgramChains
+ .Select(i => (TimeSpan)i.PlaybackTime)
+ .Select(i => i.Ticks)
+ .Sum();
+ }
+
public override async Task FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
{
var video = (Video)item;
diff --git a/MediaBrowser.Providers/packages.config b/MediaBrowser.Providers/packages.config
index f40bfae21f..4a4fef846f 100644
--- a/MediaBrowser.Providers/packages.config
+++ b/MediaBrowser.Providers/packages.config
@@ -1,4 +1,5 @@
+
\ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
index 798632af7a..2419320a54 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -360,11 +360,19 @@ namespace MediaBrowser.Server.Implementations.HttpServer
var compress = ShouldCompressResponse(requestContext, contentType);
- var hasOptions = GetStaticResult(requestContext, responseHeaders, contentType, factoryFn, compress, isHeadRequest).Result;
+ var hasOptions = GetStaticResult(requestContext, responseHeaders, contentType, factoryFn, compress, isHeadRequest);
- AddResponseHeaders(hasOptions, responseHeaders);
+ return GetStaticResultTask(hasOptions, responseHeaders);
+ }
+
+ private async Task