added dvdlib for better dvd runtimes

This commit is contained in:
Luke Pulverenti 2014-01-11 00:49:18 -05:00
parent ec4000404d
commit ef8b02d285
16 changed files with 80 additions and 228 deletions

View file

@ -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
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; }
/// <summary>
/// The raw Http Request Input Stream
/// </summary>
/// <value>The request stream.</value>
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
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[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
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[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
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[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
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[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<List<ImageInfo>>
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[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<string>(2);
request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue<string>(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
};
}
}
}

View file

@ -90,7 +90,6 @@
<Compile Include="Library\LibraryHelpers.cs" />
<Compile Include="Library\LibraryService.cs" />
<Compile Include="Library\LibraryStructureService.cs" />
<Compile Include="LiveTv\LiveTvImageService.cs" />
<Compile Include="LiveTv\LiveTvService.cs" />
<Compile Include="LocalizationService.cs" />
<Compile Include="MoviesService.cs" />

View file

@ -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);
}
}
/// <summary>

View file

@ -327,5 +327,11 @@ namespace MediaBrowser.Controller.Library
/// <param name="paths">The paths.</param>
/// <returns>IEnumerable{System.String}.</returns>
IEnumerable<string> NormalizeRootPathList(IEnumerable<string> paths);
/// <summary>
/// Registers the item.
/// </summary>
/// <param name="item">The item.</param>
void RegisterItem(BaseItem item);
}
}

View file

@ -4,7 +4,7 @@
<Files>
<File FileName="MediaBrowser.Server.Mono\app.config" Line="1" Column="1" />
<File FileName="MediaBrowser.ServerApplication\ApplicationHost.cs" Line="1" Column="1" />
<File FileName="MediaBrowser.Server.Mono\Native\NativeApp.cs" Line="12" Column="23" />
<File FileName="MediaBrowser.Server.Mono\Native\NativeApp.cs" Line="1" Column="1" />
<File FileName="MediaBrowser.Server.Mono\Program.cs" Line="36" Column="34" />
</Files>
</MonoDevelop.Ide.Workbench>

View file

@ -45,6 +45,12 @@
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="BDInfo">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.7\lib\net35\BDInfo.dll</HintPath>
</Reference>
<Reference Include="DvdLib">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.7\lib\net35\DvdLib.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />

View file

@ -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<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
{
var video = (Video)item;

View file

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MediaBrowser.BdInfo" version="1.0.0.7" targetFramework="net45" />
<package id="morelinq" version="1.0.16006" targetFramework="net45" />
</packages>

View file

@ -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);
}
return hasOptions;
private async Task<object> GetStaticResultTask(Task<IHasOptions> optionsTask,
IEnumerable<KeyValuePair<string, string>> responseHeaders)
{
var options = await optionsTask.ConfigureAwait(false);
AddResponseHeaders(options, responseHeaders);
return options;
}
/// <summary>

View file

@ -407,6 +407,11 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
RegisterItem(item);
}
public void RegisterItem(BaseItem item)
{
LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
}

View file

@ -30,21 +30,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly ILogger _logger;
private readonly IItemRepository _itemRepo;
private readonly IUserManager _userManager;
private readonly ILibraryManager _libraryManager;
private readonly LiveTvDtoService _tvDtoService;
private readonly List<ILiveTvService> _services = new List<ILiveTvService>();
private Dictionary<Guid, LiveTvChannel> _channels = new Dictionary<Guid, LiveTvChannel>();
private List<Guid> _channelIdList = new List<Guid>();
private Dictionary<Guid, LiveTvProgram> _programs = new Dictionary<Guid, LiveTvProgram>();
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager)
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager)
{
_appPaths = appPaths;
_fileSystem = fileSystem;
_logger = logger;
_itemRepo = itemRepo;
_userManager = userManager;
_libraryManager = libraryManager;
_tvDtoService = new LiveTvDtoService(dtoService, userDataManager, imageProcessor, logger, _itemRepo);
}
@ -75,7 +77,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
IEnumerable<LiveTvChannel> channels = _channels.Values;
var channels = _channelIdList.Select(_libraryManager.GetItemById)
.Where(i => i != null)
.OfType<LiveTvChannel>();
if (user != null)
{
@ -144,10 +148,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private LiveTvChannel GetInternalChannel(Guid id)
{
LiveTvChannel channel = null;
_channels.TryGetValue(id, out channel);
return channel;
return _libraryManager.GetItemById(id) as LiveTvChannel;
}
public LiveTvProgram GetInternalProgram(string id)
@ -320,6 +321,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false);
_libraryManager.RegisterItem((BaseItem)item);
return item;
}
@ -477,6 +480,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, cancellationToken).ConfigureAwait(false);
list.Add(item);
_libraryManager.RegisterItem(item);
}
catch (OperationCanceledException)
{
@ -493,7 +498,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(5 * percent + 10);
}
_channels = list.ToDictionary(i => i.Id);
_channelIdList = list.Select(i => i.Id).ToList();
progress.Report(15);
numComplete = 0;

View file

@ -48,6 +48,13 @@
<Reference Include="Alchemy">
<HintPath>..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll</HintPath>
</Reference>
<Reference Include="BDInfo, Version=1.0.5124.611, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.7\lib\net35\BDInfo.dll</HintPath>
</Reference>
<Reference Include="DvdLib">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.7\lib\net35\DvdLib.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Api.Swagger">
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath>
</Reference>
@ -68,9 +75,6 @@
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll</HintPath>
</Reference>
<Reference Include="BDInfo">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.5\lib\net20\BDInfo.dll</HintPath>
</Reference>
<Reference Include="System.Data.SQLite" Condition=" '$(ConfigurationName)' == 'Release Mono' ">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\System.Data.SQLite.ManagedOnly\x86\1.0.90.0\net40\System.Data.SQLite.dll</HintPath>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Alchemy" version="2.2.1" targetFramework="net45" />
<package id="MediaBrowser.BdInfo" version="1.0.0.5" targetFramework="net45" />
<package id="MediaBrowser.BdInfo" version="1.0.0.7" targetFramework="net45" />
<package id="morelinq" version="1.0.16006" targetFramework="net45" />
<package id="System.Data.SQLite.x86" version="1.0.90.0" targetFramework="net45" />
</packages>

View file

@ -285,7 +285,7 @@ namespace MediaBrowser.ServerApplication
DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor);
RegisterSingleInstance(DtoService);
LiveTvManager = new LiveTvManager(ApplicationPaths, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager);
LiveTvManager = new LiveTvManager(ApplicationPaths, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager);
RegisterSingleInstance(LiveTvManager);
progress.Report(15);

View file

@ -1594,9 +1594,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
if (itemType == "Artist") {
url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images");
}
else if (itemType == "Channel") {
url = self.getUrl("LiveTv/Channels/" + itemId + "/Images");
}
else if (itemType == "Genre") {
url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images");
} else if (itemType == "GameGenre") {
@ -1667,9 +1664,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
if (itemType == "Artist") {
url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options);
}
else if (itemType == "Channel") {
url = self.getUrl("LiveTv/Channels/" + itemId + "/Images/" + imageType + "/" + imageIndex + "/Index", options);
}
else if (itemType == "Genre") {
url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images/" + imageType + "/" + imageIndex + "/Index", options);
} else if (itemType == "GameGenre") {
@ -1701,9 +1695,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
if (itemType == "Artist") {
url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images");
}
else if (itemType == "Channel") {
url = self.getUrl("LiveTv/Channels/" + itemId + "/Images");
}
else if (itemType == "Genre") {
url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images");
} else if (itemType == "GameGenre") {
@ -1838,9 +1829,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
if (itemType == "Artist") {
url = self.getUrl("Artists/" + self.encodeName(itemName) + "/Images");
}
else if (itemType == "Channel") {
url = self.getUrl("LiveTv/Channels/" + itemId + "/Images");
}
else if (itemType == "Genre") {
url = self.getUrl("Genres/" + self.encodeName(itemName) + "/Images");
} else if (itemType == "GameGenre") {

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.223" targetFramework="net45" />
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.224" targetFramework="net45" />
</packages>