commit
8fc7d7ba02
|
@ -33,7 +33,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
|
|
@ -155,6 +155,7 @@ namespace Emby.Drawing.ImageMagick
|
||||||
AutoOrientImage(originalImage);
|
AutoOrientImage(originalImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddForegroundLayer(originalImage, options);
|
||||||
DrawIndicator(originalImage, width, height, options);
|
DrawIndicator(originalImage, width, height, options);
|
||||||
|
|
||||||
originalImage.CurrentImage.CompressionQuality = quality;
|
originalImage.CurrentImage.CompressionQuality = quality;
|
||||||
|
@ -177,6 +178,8 @@ namespace Emby.Drawing.ImageMagick
|
||||||
}
|
}
|
||||||
|
|
||||||
wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0);
|
wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0);
|
||||||
|
|
||||||
|
AddForegroundLayer(wand, options);
|
||||||
DrawIndicator(wand, width, height, options);
|
DrawIndicator(wand, width, height, options);
|
||||||
|
|
||||||
wand.CurrentImage.CompressionQuality = quality;
|
wand.CurrentImage.CompressionQuality = quality;
|
||||||
|
@ -189,6 +192,23 @@ namespace Emby.Drawing.ImageMagick
|
||||||
SaveDelay();
|
SaveDelay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(options.ForegroundLayer))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Double opacity;
|
||||||
|
if (!Double.TryParse(options.ForegroundLayer, out opacity)) opacity = .4;
|
||||||
|
|
||||||
|
using (var pixel = new PixelWand("#000", opacity))
|
||||||
|
using (var overlay = new MagickWand(wand.CurrentImage.Width, wand.CurrentImage.Height, pixel))
|
||||||
|
{
|
||||||
|
wand.CurrentImage.CompositeImage(overlay, CompositeOperator.OverCompositeOp, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void AutoOrientImage(MagickWand wand)
|
private void AutoOrientImage(MagickWand wand)
|
||||||
{
|
{
|
||||||
wand.CurrentImage.AutoOrientImage();
|
wand.CurrentImage.AutoOrientImage();
|
||||||
|
|
|
@ -234,7 +234,7 @@ namespace Emby.Drawing
|
||||||
var quality = options.Quality;
|
var quality = options.Quality;
|
||||||
|
|
||||||
var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]);
|
var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]);
|
||||||
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor);
|
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor, options.ForegroundLayer);
|
||||||
|
|
||||||
var semaphore = GetLock(cacheFilePath);
|
var semaphore = GetLock(cacheFilePath);
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ namespace Emby.Drawing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the cache file path based on a set of parameters
|
/// Gets the cache file path based on a set of parameters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
|
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor, string foregroundLayer)
|
||||||
{
|
{
|
||||||
var filename = originalPath;
|
var filename = originalPath;
|
||||||
|
|
||||||
|
@ -507,6 +507,11 @@ namespace Emby.Drawing
|
||||||
filename += "b=" + backgroundColor;
|
filename += "b=" + backgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(foregroundLayer))
|
||||||
|
{
|
||||||
|
filename += "fl=" + foregroundLayer;
|
||||||
|
}
|
||||||
|
|
||||||
filename += "v=" + Version;
|
filename += "v=" + Version;
|
||||||
|
|
||||||
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
|
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
|
||||||
<package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net45" />
|
<package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -1,10 +1,8 @@
|
||||||
using System;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Extensions;
|
|
||||||
using MediaBrowser.Controller.Connect;
|
using MediaBrowser.Controller.Connect;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.Connect;
|
using MediaBrowser.Model.Connect;
|
||||||
using MediaBrowser.Model.Dto;
|
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -75,28 +73,6 @@ namespace MediaBrowser.Api
|
||||||
public string ConnectUserId { get; set; }
|
public string ConnectUserId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("/Connect/Supporters", "GET")]
|
|
||||||
[Authenticated(Roles = "Admin")]
|
|
||||||
public class GetConnectSupporterSummary : IReturn<ConnectSupporterSummary>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("/Connect/Supporters", "DELETE")]
|
|
||||||
[Authenticated(Roles = "Admin")]
|
|
||||||
public class RemoveConnectSupporter : IReturnVoid
|
|
||||||
{
|
|
||||||
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
|
|
||||||
public string Id { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("/Connect/Supporters", "POST")]
|
|
||||||
[Authenticated(Roles = "Admin")]
|
|
||||||
public class AddConnectSupporter : IReturnVoid
|
|
||||||
{
|
|
||||||
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
|
||||||
public string Id { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConnectService : BaseApiService
|
public class ConnectService : BaseApiService
|
||||||
{
|
{
|
||||||
private readonly IConnectManager _connectManager;
|
private readonly IConnectManager _connectManager;
|
||||||
|
@ -108,35 +84,6 @@ namespace MediaBrowser.Api
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<object> Get(GetConnectSupporterSummary request)
|
|
||||||
{
|
|
||||||
var result = await _connectManager.GetConnectSupporterSummary().ConfigureAwait(false);
|
|
||||||
var existingConnectUserIds = result.Users.Select(i => i.Id).ToList();
|
|
||||||
|
|
||||||
result.EligibleUsers = _userManager.Users
|
|
||||||
.Where(i => !string.IsNullOrWhiteSpace(i.ConnectUserId))
|
|
||||||
.Where(i => !existingConnectUserIds.Contains(i.ConnectUserId, StringComparer.OrdinalIgnoreCase))
|
|
||||||
.OrderBy(i => i.Name)
|
|
||||||
.Select(i => _userManager.GetUserDto(i))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
return ToOptimizedResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Delete(RemoveConnectSupporter request)
|
|
||||||
{
|
|
||||||
var task = _connectManager.RemoveConnectSupporter(request.Id);
|
|
||||||
|
|
||||||
Task.WaitAll(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Post(AddConnectSupporter request)
|
|
||||||
{
|
|
||||||
var task = _connectManager.AddConnectSupporter(request.Id);
|
|
||||||
|
|
||||||
Task.WaitAll(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Post(CreateConnectLink request)
|
public object Post(CreateConnectLink request)
|
||||||
{
|
{
|
||||||
return _connectManager.LinkUser(request.Id, request.ConnectUsername);
|
return _connectManager.LinkUser(request.Id, request.ConnectUsername);
|
||||||
|
|
|
@ -66,7 +66,10 @@ namespace MediaBrowser.Api.Images
|
||||||
|
|
||||||
[ApiMember(Name = "BackgroundColor", Description = "Optional. Apply a background color for transparent images.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "BackgroundColor", Description = "Optional. Apply a background color for transparent images.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||||
public string BackgroundColor { get; set; }
|
public string BackgroundColor { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "ForegroundLayer", Description = "Optional. Apply a foreground layer on top of the image.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||||
|
public string ForegroundLayer { get; set; }
|
||||||
|
|
||||||
public ImageRequest()
|
public ImageRequest()
|
||||||
{
|
{
|
||||||
EnableImageEnhancers = true;
|
EnableImageEnhancers = true;
|
||||||
|
|
|
@ -624,6 +624,7 @@ namespace MediaBrowser.Api.Images
|
||||||
PercentPlayed = request.PercentPlayed ?? 0,
|
PercentPlayed = request.PercentPlayed ?? 0,
|
||||||
UnplayedCount = request.UnplayedCount,
|
UnplayedCount = request.UnplayedCount,
|
||||||
BackgroundColor = request.BackgroundColor,
|
BackgroundColor = request.BackgroundColor,
|
||||||
|
ForegroundLayer = request.ForegroundLayer,
|
||||||
SupportedOutputFormats = supportedFormats
|
SupportedOutputFormats = supportedFormats
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ using MediaBrowser.Model.Querying;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
|
using MediaBrowser.Model.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.Library
|
namespace MediaBrowser.Api.Library
|
||||||
{
|
{
|
||||||
|
@ -54,7 +55,7 @@ namespace MediaBrowser.Api.Library
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("/Library/FileOrganizations/{Id}/Episode/Organize", "POST", Summary = "Performs an organization")]
|
[Route("/Library/FileOrganizations/{Id}/Episode/Organize", "POST", Summary = "Performs organization of a tv episode")]
|
||||||
public class OrganizeEpisode
|
public class OrganizeEpisode
|
||||||
{
|
{
|
||||||
[ApiMember(Name = "Id", Description = "Result Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
[ApiMember(Name = "Id", Description = "Result Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||||
|
@ -74,6 +75,18 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
[ApiMember(Name = "RememberCorrection", Description = "Whether or not to apply the same correction to future episodes of the same series.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
|
[ApiMember(Name = "RememberCorrection", Description = "Whether or not to apply the same correction to future episodes of the same series.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
|
||||||
public bool RememberCorrection { get; set; }
|
public bool RememberCorrection { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "NewSeriesProviderIds", Description = "A list of provider IDs identifying a new series.", IsRequired = false, DataType = "Dictionary<string, string>", ParameterType = "query", Verb = "POST")]
|
||||||
|
public Dictionary<string, string> NewSeriesProviderIds { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "NewSeriesName", Description = "Name of a series to add.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||||
|
public string NewSeriesName { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "NewSeriesYear", Description = "Year of a series to add.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||||
|
public string NewSeriesYear { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "TargetFolder", Description = "Target Folder", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||||
|
public string TargetFolder { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("/Library/FileOrganizations/SmartMatches", "GET", Summary = "Gets smart match entries")]
|
[Route("/Library/FileOrganizations/SmartMatches", "GET", Summary = "Gets smart match entries")]
|
||||||
|
@ -106,9 +119,14 @@ namespace MediaBrowser.Api.Library
|
||||||
{
|
{
|
||||||
private readonly IFileOrganizationService _iFileOrganizationService;
|
private readonly IFileOrganizationService _iFileOrganizationService;
|
||||||
|
|
||||||
public FileOrganizationService(IFileOrganizationService iFileOrganizationService)
|
/// The _json serializer
|
||||||
|
/// </summary>
|
||||||
|
private readonly IJsonSerializer _jsonSerializer;
|
||||||
|
|
||||||
|
public FileOrganizationService(IFileOrganizationService iFileOrganizationService, IJsonSerializer jsonSerializer)
|
||||||
{
|
{
|
||||||
_iFileOrganizationService = iFileOrganizationService;
|
_iFileOrganizationService = iFileOrganizationService;
|
||||||
|
_jsonSerializer = jsonSerializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Get(GetFileOrganizationActivity request)
|
public object Get(GetFileOrganizationActivity request)
|
||||||
|
@ -145,6 +163,13 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
public void Post(OrganizeEpisode request)
|
public void Post(OrganizeEpisode request)
|
||||||
{
|
{
|
||||||
|
var dicNewProviderIds = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
if (request.NewSeriesProviderIds != null)
|
||||||
|
{
|
||||||
|
dicNewProviderIds = request.NewSeriesProviderIds;
|
||||||
|
}
|
||||||
|
|
||||||
var task = _iFileOrganizationService.PerformEpisodeOrganization(new EpisodeFileOrganizationRequest
|
var task = _iFileOrganizationService.PerformEpisodeOrganization(new EpisodeFileOrganizationRequest
|
||||||
{
|
{
|
||||||
EndingEpisodeNumber = request.EndingEpisodeNumber,
|
EndingEpisodeNumber = request.EndingEpisodeNumber,
|
||||||
|
@ -152,9 +177,17 @@ namespace MediaBrowser.Api.Library
|
||||||
RememberCorrection = request.RememberCorrection,
|
RememberCorrection = request.RememberCorrection,
|
||||||
ResultId = request.Id,
|
ResultId = request.Id,
|
||||||
SeasonNumber = request.SeasonNumber,
|
SeasonNumber = request.SeasonNumber,
|
||||||
SeriesId = request.SeriesId
|
SeriesId = request.SeriesId,
|
||||||
|
NewSeriesName = request.NewSeriesName,
|
||||||
|
NewSeriesYear = request.NewSeriesYear,
|
||||||
|
NewSeriesProviderIds = dicNewProviderIds,
|
||||||
|
TargetFolder = request.TargetFolder
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// For async processing (close dialog early instead of waiting until the file has been copied)
|
||||||
|
//var tasks = new Task[] { task };
|
||||||
|
//Task.WaitAll(tasks, 8000);
|
||||||
|
|
||||||
Task.WaitAll(task);
|
Task.WaitAll(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="MoreLinq">
|
<Reference Include="MoreLinq">
|
||||||
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
||||||
|
@ -80,7 +80,6 @@
|
||||||
<Compile Include="FilterService.cs" />
|
<Compile Include="FilterService.cs" />
|
||||||
<Compile Include="IHasDtoOptions.cs" />
|
<Compile Include="IHasDtoOptions.cs" />
|
||||||
<Compile Include="Library\ChapterService.cs" />
|
<Compile Include="Library\ChapterService.cs" />
|
||||||
<Compile Include="PinLoginService.cs" />
|
|
||||||
<Compile Include="Playback\Dash\ManifestBuilder.cs" />
|
<Compile Include="Playback\Dash\ManifestBuilder.cs" />
|
||||||
<Compile Include="Playback\Dash\MpegDashService.cs" />
|
<Compile Include="Playback\Dash\MpegDashService.cs" />
|
||||||
<Compile Include="Playback\MediaInfoService.cs" />
|
<Compile Include="Playback\MediaInfoService.cs" />
|
||||||
|
|
|
@ -1,202 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Globalization;
|
|
||||||
using MediaBrowser.Common.Extensions;
|
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Connect;
|
|
||||||
using ServiceStack;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api
|
|
||||||
{
|
|
||||||
[Route("/Auth/Pin", "POST", Summary = "Creates a pin request")]
|
|
||||||
public class CreatePinRequest : IReturn<PinCreationResult>
|
|
||||||
{
|
|
||||||
[ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
|
||||||
public string DeviceId { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("/Auth/Pin", "GET", Summary = "Gets pin status")]
|
|
||||||
public class GetPinStatusRequest : IReturn<PinStatusResult>
|
|
||||||
{
|
|
||||||
[ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
|
||||||
public string DeviceId { get; set; }
|
|
||||||
[ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
|
||||||
public string Pin { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("/Auth/Pin/Exchange", "POST", Summary = "Exchanges a pin")]
|
|
||||||
public class ExchangePinRequest : IReturn<PinExchangeResult>
|
|
||||||
{
|
|
||||||
[ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
|
||||||
public string DeviceId { get; set; }
|
|
||||||
[ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
|
||||||
public string Pin { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("/Auth/Pin/Validate", "POST", Summary = "Validates a pin")]
|
|
||||||
[Authenticated]
|
|
||||||
public class ValidatePinRequest : IReturnVoid
|
|
||||||
{
|
|
||||||
[ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
|
||||||
public string Pin { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PinLoginService : BaseApiService
|
|
||||||
{
|
|
||||||
private readonly ConcurrentDictionary<string, MyPinStatus> _activeRequests = new ConcurrentDictionary<string, MyPinStatus>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
public object Post(CreatePinRequest request)
|
|
||||||
{
|
|
||||||
var pin = GetNewPin();
|
|
||||||
|
|
||||||
var value = new MyPinStatus
|
|
||||||
{
|
|
||||||
CreationTimeUtc = DateTime.UtcNow,
|
|
||||||
IsConfirmed = false,
|
|
||||||
IsExpired = false,
|
|
||||||
Pin = pin,
|
|
||||||
DeviceId = request.DeviceId
|
|
||||||
};
|
|
||||||
|
|
||||||
_activeRequests.AddOrUpdate(pin, value, (k, v) => value);
|
|
||||||
|
|
||||||
return ToOptimizedResult(new PinCreationResult
|
|
||||||
{
|
|
||||||
DeviceId = request.DeviceId,
|
|
||||||
IsConfirmed = false,
|
|
||||||
IsExpired = false,
|
|
||||||
Pin = pin
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Get(GetPinStatusRequest request)
|
|
||||||
{
|
|
||||||
MyPinStatus status;
|
|
||||||
|
|
||||||
if (!_activeRequests.TryGetValue(request.Pin, out status))
|
|
||||||
{
|
|
||||||
throw new ResourceNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
EnsureValid(request.DeviceId, status);
|
|
||||||
|
|
||||||
return ToOptimizedResult(new PinStatusResult
|
|
||||||
{
|
|
||||||
Pin = status.Pin,
|
|
||||||
IsConfirmed = status.IsConfirmed,
|
|
||||||
IsExpired = status.IsExpired
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Post(ExchangePinRequest request)
|
|
||||||
{
|
|
||||||
MyPinStatus status;
|
|
||||||
|
|
||||||
if (!_activeRequests.TryGetValue(request.Pin, out status))
|
|
||||||
{
|
|
||||||
throw new ResourceNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
EnsureValid(request.DeviceId, status);
|
|
||||||
|
|
||||||
if (!status.IsConfirmed)
|
|
||||||
{
|
|
||||||
throw new ResourceNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ToOptimizedResult(new PinExchangeResult
|
|
||||||
{
|
|
||||||
// TODO: Add access token
|
|
||||||
UserId = status.UserId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Post(ValidatePinRequest request)
|
|
||||||
{
|
|
||||||
MyPinStatus status;
|
|
||||||
|
|
||||||
if (!_activeRequests.TryGetValue(request.Pin, out status))
|
|
||||||
{
|
|
||||||
throw new ResourceNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
EnsureValid(status);
|
|
||||||
|
|
||||||
status.IsConfirmed = true;
|
|
||||||
status.UserId = AuthorizationContext.GetAuthorizationInfo(Request).UserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureValid(string requestedDeviceId, MyPinStatus status)
|
|
||||||
{
|
|
||||||
if (!string.Equals(requestedDeviceId, status.DeviceId, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
throw new ResourceNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
EnsureValid(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureValid(MyPinStatus status)
|
|
||||||
{
|
|
||||||
if ((DateTime.UtcNow - status.CreationTimeUtc).TotalMinutes > 10)
|
|
||||||
{
|
|
||||||
status.IsExpired = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.IsExpired)
|
|
||||||
{
|
|
||||||
throw new ResourceNotFoundException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetNewPin()
|
|
||||||
{
|
|
||||||
var pin = GetNewPinInternal();
|
|
||||||
|
|
||||||
while (IsPinActive(pin))
|
|
||||||
{
|
|
||||||
pin = GetNewPinInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetNewPinInternal()
|
|
||||||
{
|
|
||||||
var length = 5;
|
|
||||||
var pin = string.Empty;
|
|
||||||
|
|
||||||
while (pin.Length < length)
|
|
||||||
{
|
|
||||||
var digit = new Random().Next(0, 9);
|
|
||||||
pin += digit.ToString(CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsPinActive(string pin)
|
|
||||||
{
|
|
||||||
MyPinStatus status;
|
|
||||||
|
|
||||||
if (!_activeRequests.TryGetValue(pin, out status))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.IsExpired)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MyPinStatus : PinStatusResult
|
|
||||||
{
|
|
||||||
public DateTime CreationTimeUtc { get; set; }
|
|
||||||
public string DeviceId { get; set; }
|
|
||||||
public string UserId { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -477,7 +477,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
var pts = string.Empty;
|
var pts = string.Empty;
|
||||||
|
|
||||||
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream)
|
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && !state.VideoRequest.CopyTimestamps)
|
||||||
{
|
{
|
||||||
var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds;
|
var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds;
|
||||||
|
|
||||||
|
@ -604,6 +604,10 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
var seconds = Math.Round(TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds);
|
var seconds = Math.Round(TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds);
|
||||||
|
|
||||||
|
var setPtsParam = state.VideoRequest.CopyTimestamps
|
||||||
|
? string.Empty
|
||||||
|
: string.Format(",setpts=PTS -{0}/TB", seconds.ToString(UsCulture));
|
||||||
|
|
||||||
if (state.SubtitleStream.IsExternal)
|
if (state.SubtitleStream.IsExternal)
|
||||||
{
|
{
|
||||||
var subtitlePath = state.SubtitleStream.Path;
|
var subtitlePath = state.SubtitleStream.Path;
|
||||||
|
@ -621,18 +625,18 @@ namespace MediaBrowser.Api.Playback
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Perhaps also use original_size=1920x800 ??
|
// TODO: Perhaps also use original_size=1920x800 ??
|
||||||
return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB",
|
return string.Format("subtitles=filename='{0}'{1}{2}",
|
||||||
MediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
|
MediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
|
||||||
charsetParam,
|
charsetParam,
|
||||||
seconds.ToString(UsCulture));
|
setPtsParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaPath = state.MediaPath ?? string.Empty;
|
var mediaPath = state.MediaPath ?? string.Empty;
|
||||||
|
|
||||||
return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB",
|
return string.Format("subtitles='{0}:si={1}'{2}",
|
||||||
MediaEncoder.EscapeSubtitleFilterPath(mediaPath),
|
MediaEncoder.EscapeSubtitleFilterPath(mediaPath),
|
||||||
state.InternalSubtitleStreamOffset.ToString(UsCulture),
|
state.InternalSubtitleStreamOffset.ToString(UsCulture),
|
||||||
seconds.ToString(UsCulture));
|
setPtsParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -865,6 +869,15 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
|
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
|
||||||
{
|
{
|
||||||
|
if (state.VideoStream != null && state.VideoStream.Width.HasValue)
|
||||||
|
{
|
||||||
|
// This is hacky but not sure how to get the exact subtitle resolution
|
||||||
|
double height = state.VideoStream.Width.Value;
|
||||||
|
height /= 16;
|
||||||
|
height *= 9;
|
||||||
|
|
||||||
|
arg += string.Format(" -canvas_size {0}:{1}", state.VideoStream.Width.Value.ToString(CultureInfo.InvariantCulture), Convert.ToInt32(height).ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
arg += " -i \"" + state.SubtitleStream.Path + "\"";
|
arg += " -i \"" + state.SubtitleStream.Path + "\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1462,6 +1475,13 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
// Duplicating ItemId because of MediaMonkey
|
// Duplicating ItemId because of MediaMonkey
|
||||||
}
|
}
|
||||||
|
else if (i == 24)
|
||||||
|
{
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.CopyTimestamps = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2021,6 +2041,11 @@ namespace MediaBrowser.Api.Playback
|
||||||
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
||||||
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
|
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
|
||||||
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||||
|
|
||||||
|
if (state.VideoRequest != null)
|
||||||
|
{
|
||||||
|
state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2184,9 +2209,9 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
if (state.VideoRequest != null)
|
if (state.VideoRequest != null)
|
||||||
{
|
{
|
||||||
if (string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase) && state.VideoRequest.CopyTimestamps)
|
||||||
{
|
{
|
||||||
//inputModifier += " -noaccurate_seek";
|
inputModifier += " -noaccurate_seek";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
[Route("/Videos/{Id}/stream.wmv", "GET")]
|
[Route("/Videos/{Id}/stream.wmv", "GET")]
|
||||||
[Route("/Videos/{Id}/stream.wtv", "GET")]
|
[Route("/Videos/{Id}/stream.wtv", "GET")]
|
||||||
[Route("/Videos/{Id}/stream.mov", "GET")]
|
[Route("/Videos/{Id}/stream.mov", "GET")]
|
||||||
|
[Route("/Videos/{Id}/stream.iso", "GET")]
|
||||||
[Route("/Videos/{Id}/stream", "GET")]
|
[Route("/Videos/{Id}/stream", "GET")]
|
||||||
[Route("/Videos/{Id}/stream.ts", "HEAD")]
|
[Route("/Videos/{Id}/stream.ts", "HEAD")]
|
||||||
[Route("/Videos/{Id}/stream.webm", "HEAD")]
|
[Route("/Videos/{Id}/stream.webm", "HEAD")]
|
||||||
|
@ -53,6 +54,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
[Route("/Videos/{Id}/stream.wtv", "HEAD")]
|
[Route("/Videos/{Id}/stream.wtv", "HEAD")]
|
||||||
[Route("/Videos/{Id}/stream.m2ts", "HEAD")]
|
[Route("/Videos/{Id}/stream.m2ts", "HEAD")]
|
||||||
[Route("/Videos/{Id}/stream.mov", "HEAD")]
|
[Route("/Videos/{Id}/stream.mov", "HEAD")]
|
||||||
|
[Route("/Videos/{Id}/stream.iso", "HEAD")]
|
||||||
[Route("/Videos/{Id}/stream", "HEAD")]
|
[Route("/Videos/{Id}/stream", "HEAD")]
|
||||||
[Api(Description = "Gets a video stream")]
|
[Api(Description = "Gets a video stream")]
|
||||||
public class GetVideoStream : VideoStreamRequest
|
public class GetVideoStream : VideoStreamRequest
|
||||||
|
@ -65,7 +67,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class VideoService : BaseProgressiveStreamingService
|
public class VideoService : BaseProgressiveStreamingService
|
||||||
{
|
{
|
||||||
public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
|
public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient)
|
||||||
|
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,11 +140,6 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
|
|
||||||
var isOutputMkv = string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase);
|
var isOutputMkv = string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
if (state.RunTimeTicks.HasValue)
|
|
||||||
{
|
|
||||||
//args += " -copyts -avoid_negative_ts disabled -start_at_zero";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (state.VideoStream != null && IsH264(state.VideoStream) &&
|
if (state.VideoStream != null && IsH264(state.VideoStream) &&
|
||||||
|
@ -150,6 +148,11 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
args += " -bsf:v h264_mp4toannexb";
|
args += " -bsf:v h264_mp4toannexb";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
|
||||||
|
{
|
||||||
|
args += " -copyts -avoid_negative_ts disabled -start_at_zero";
|
||||||
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,10 +163,22 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
|
|
||||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
|
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
|
||||||
|
|
||||||
|
var hasCopyTs = false;
|
||||||
// Add resolution params, if specified
|
// Add resolution params, if specified
|
||||||
if (!hasGraphicalSubs)
|
if (!hasGraphicalSubs)
|
||||||
{
|
{
|
||||||
args += GetOutputSizeParam(state, videoCodec);
|
var outputSizeParam = GetOutputSizeParam(state, videoCodec);
|
||||||
|
args += outputSizeParam;
|
||||||
|
hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
|
||||||
|
{
|
||||||
|
if (!hasCopyTs)
|
||||||
|
{
|
||||||
|
args += " -copyts";
|
||||||
|
}
|
||||||
|
args += " -avoid_negative_ts disabled -start_at_zero";
|
||||||
}
|
}
|
||||||
|
|
||||||
var qualityParam = GetVideoQualityParam(state, videoCodec);
|
var qualityParam = GetVideoQualityParam(state, videoCodec);
|
||||||
|
|
|
@ -187,6 +187,9 @@ namespace MediaBrowser.Api.Playback
|
||||||
[ApiMember(Name = "EnableAutoStreamCopy", Description = "Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "EnableAutoStreamCopy", Description = "Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||||
public bool EnableAutoStreamCopy { get; set; }
|
public bool EnableAutoStreamCopy { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "CopyTimestamps", Description = "Whether or not to copy timestamps when transcoding with an offset. Defaults to false.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||||
|
public bool CopyTimestamps { get; set; }
|
||||||
|
|
||||||
[ApiMember(Name = "Cabac", Description = "Enable if cabac encoding is required", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "Cabac", Description = "Enable if cabac encoding is required", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||||
public bool? Cabac { get; set; }
|
public bool? Cabac { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ using ServiceStack;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.ScheduledTasks
|
namespace MediaBrowser.Api.ScheduledTasks
|
||||||
{
|
{
|
||||||
|
@ -90,12 +91,14 @@ namespace MediaBrowser.Api.ScheduledTasks
|
||||||
/// <value>The task manager.</value>
|
/// <value>The task manager.</value>
|
||||||
private ITaskManager TaskManager { get; set; }
|
private ITaskManager TaskManager { get; set; }
|
||||||
|
|
||||||
|
private readonly IServerConfigurationManager _config;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ScheduledTaskService" /> class.
|
/// Initializes a new instance of the <see cref="ScheduledTaskService" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="taskManager">The task manager.</param>
|
/// <param name="taskManager">The task manager.</param>
|
||||||
/// <exception cref="System.ArgumentNullException">taskManager</exception>
|
/// <exception cref="ArgumentNullException">taskManager</exception>
|
||||||
public ScheduledTaskService(ITaskManager taskManager)
|
public ScheduledTaskService(ITaskManager taskManager, IServerConfigurationManager config)
|
||||||
{
|
{
|
||||||
if (taskManager == null)
|
if (taskManager == null)
|
||||||
{
|
{
|
||||||
|
@ -103,6 +106,7 @@ namespace MediaBrowser.Api.ScheduledTasks
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskManager = taskManager;
|
TaskManager = taskManager;
|
||||||
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -194,6 +198,20 @@ namespace MediaBrowser.Api.ScheduledTasks
|
||||||
throw new ResourceNotFoundException("Task not found");
|
throw new ResourceNotFoundException("Task not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasKey = task.ScheduledTask as IHasKey;
|
||||||
|
if (hasKey != null)
|
||||||
|
{
|
||||||
|
if (string.Equals(hasKey.Key, "SystemUpdateTask", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// This is a hack for now just to get the update application function to work when auto-update is disabled
|
||||||
|
if (!_config.Configuration.EnableAutoUpdate)
|
||||||
|
{
|
||||||
|
_config.Configuration.EnableAutoUpdate = true;
|
||||||
|
_config.SaveConfiguration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TaskManager.Execute(task);
|
TaskManager.Execute(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -415,23 +415,6 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
|
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(auth.Client))
|
|
||||||
{
|
|
||||||
auth.Client = "Unknown app";
|
|
||||||
}
|
|
||||||
if (string.IsNullOrWhiteSpace(auth.Device))
|
|
||||||
{
|
|
||||||
auth.Device = "Unknown device";
|
|
||||||
}
|
|
||||||
if (string.IsNullOrWhiteSpace(auth.Version))
|
|
||||||
{
|
|
||||||
auth.Version = "Unknown version";
|
|
||||||
}
|
|
||||||
if (string.IsNullOrWhiteSpace(auth.DeviceId))
|
|
||||||
{
|
|
||||||
auth.DeviceId = "Unknown device id";
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = await _sessionMananger.AuthenticateNewSession(new AuthenticationRequest
|
var result = await _sessionMananger.AuthenticateNewSession(new AuthenticationRequest
|
||||||
{
|
{
|
||||||
App = auth.Client,
|
App = auth.Client,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
|
||||||
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -49,7 +49,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="MoreLinq">
|
<Reference Include="MoreLinq">
|
||||||
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace MediaBrowser.Common.Implementations.Networking
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private volatile List<IPAddress> _localIpAddresses;
|
private List<IPAddress> _localIpAddresses;
|
||||||
private readonly object _localIpAddressSyncLock = new object();
|
private readonly object _localIpAddressSyncLock = new object();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -29,24 +29,20 @@ namespace MediaBrowser.Common.Implementations.Networking
|
||||||
/// <returns>IPAddress.</returns>
|
/// <returns>IPAddress.</returns>
|
||||||
public IEnumerable<IPAddress> GetLocalIpAddresses()
|
public IEnumerable<IPAddress> GetLocalIpAddresses()
|
||||||
{
|
{
|
||||||
const int cacheMinutes = 3;
|
const int cacheMinutes = 5;
|
||||||
var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
|
|
||||||
|
|
||||||
if (_localIpAddresses == null || forceRefresh)
|
lock (_localIpAddressSyncLock)
|
||||||
{
|
{
|
||||||
lock (_localIpAddressSyncLock)
|
var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
|
||||||
|
|
||||||
|
if (_localIpAddresses == null || forceRefresh)
|
||||||
{
|
{
|
||||||
forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
|
var addresses = GetLocalIpAddressesInternal().ToList();
|
||||||
|
|
||||||
if (_localIpAddresses == null || forceRefresh)
|
_localIpAddresses = addresses;
|
||||||
{
|
_lastRefresh = DateTime.UtcNow;
|
||||||
var addresses = GetLocalIpAddressesInternal().ToList();
|
|
||||||
|
|
||||||
_localIpAddresses = addresses;
|
return addresses;
|
||||||
_lastRefresh = DateTime.UtcNow;
|
|
||||||
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
|
||||||
ReloadTriggerEvents(true);
|
InitTriggerEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -233,11 +233,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _triggers
|
/// The _triggers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private volatile List<ITaskTrigger> _triggers;
|
private List<ITaskTrigger> _triggers;
|
||||||
/// <summary>
|
|
||||||
/// The _triggers sync lock
|
|
||||||
/// </summary>
|
|
||||||
private readonly object _triggersSyncLock = new object();
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the triggers that define when the task will run
|
/// Gets the triggers that define when the task will run
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -247,17 +243,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_triggers == null)
|
|
||||||
{
|
|
||||||
lock (_triggersSyncLock)
|
|
||||||
{
|
|
||||||
if (_triggers == null)
|
|
||||||
{
|
|
||||||
_triggers = LoadTriggers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _triggers;
|
return _triggers;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
|
@ -303,6 +288,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitTriggerEvents()
|
||||||
|
{
|
||||||
|
_triggers = LoadTriggers();
|
||||||
|
ReloadTriggerEvents(true);
|
||||||
|
}
|
||||||
|
|
||||||
public void ReloadTriggerEvents()
|
public void ReloadTriggerEvents()
|
||||||
{
|
{
|
||||||
ReloadTriggerEvents(false);
|
ReloadTriggerEvents(false);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
|
||||||
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
||||||
<package id="NLog" version="4.2.3" targetFramework="net45" />
|
<package id="NLog" version="4.2.3" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
|
|
|
@ -76,25 +76,5 @@ namespace MediaBrowser.Controller.Connect
|
||||||
/// <param name="token">The token.</param>
|
/// <param name="token">The token.</param>
|
||||||
/// <returns><c>true</c> if [is authorization token valid] [the specified token]; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if [is authorization token valid] [the specified token]; otherwise, <c>false</c>.</returns>
|
||||||
bool IsAuthorizationTokenValid(string token);
|
bool IsAuthorizationTokenValid(string token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the connect supporter summary.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Task<ConnectSupporterSummary>.</returns>
|
|
||||||
Task<ConnectSupporterSummary> GetConnectSupporterSummary();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the connect supporter.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The identifier.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
Task RemoveConnectSupporter(string id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds the connect supporter.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The identifier.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
Task AddConnectSupporter(string id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||||
public double PercentPlayed { get; set; }
|
public double PercentPlayed { get; set; }
|
||||||
|
|
||||||
public string BackgroundColor { get; set; }
|
public string BackgroundColor { get; set; }
|
||||||
|
public string ForegroundLayer { get; set; }
|
||||||
|
|
||||||
public bool HasDefaultOptions(string originalImagePath)
|
public bool HasDefaultOptions(string originalImagePath)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +84,8 @@ namespace MediaBrowser.Controller.Drawing
|
||||||
!AddPlayedIndicator &&
|
!AddPlayedIndicator &&
|
||||||
PercentPlayed.Equals(0) &&
|
PercentPlayed.Equals(0) &&
|
||||||
!UnplayedCount.HasValue &&
|
!UnplayedCount.HasValue &&
|
||||||
string.IsNullOrEmpty(BackgroundColor);
|
string.IsNullOrEmpty(BackgroundColor) &&
|
||||||
|
string.IsNullOrEmpty(ForegroundLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsFormatSupported(string originalImagePath)
|
private bool IsFormatSupported(string originalImagePath)
|
||||||
|
|
|
@ -1359,7 +1359,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(info.Path))
|
if (!string.IsNullOrEmpty(info.Path))
|
||||||
{
|
{
|
||||||
var itemByPath = LibraryManager.RootFolder.FindByPath(info.Path);
|
var itemByPath = LibraryManager.FindByPath(info.Path);
|
||||||
|
|
||||||
if (itemByPath == null)
|
if (itemByPath == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
public interface IHasMediaSources : IHasId
|
public interface IHasMediaSources : IHasUserData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the media sources.
|
/// Gets the media sources.
|
||||||
|
|
|
@ -45,6 +45,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public string NameLessThan { get; set; }
|
public string NameLessThan { get; set; }
|
||||||
public string NameContains { get; set; }
|
public string NameContains { get; set; }
|
||||||
|
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
public string Person { get; set; }
|
public string Person { get; set; }
|
||||||
public string[] PersonIds { get; set; }
|
public string[] PersonIds { get; set; }
|
||||||
public string[] ItemIds { get; set; }
|
public string[] ItemIds { get; set; }
|
||||||
|
@ -96,7 +98,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public int? MinIndexNumber { get; set; }
|
public int? MinIndexNumber { get; set; }
|
||||||
public double? MinCriticRating { get; set; }
|
public double? MinCriticRating { get; set; }
|
||||||
public double? MinCommunityRating { get; set; }
|
public double? MinCommunityRating { get; set; }
|
||||||
|
|
||||||
public string[] ChannelIds { get; set; }
|
public string[] ChannelIds { get; set; }
|
||||||
|
|
||||||
internal List<Guid> ItemIdsFromPersonFilters { get; set; }
|
internal List<Guid> ItemIdsFromPersonFilters { get; set; }
|
||||||
|
@ -112,7 +114,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public string[] TopParentIds { get; set; }
|
public string[] TopParentIds { get; set; }
|
||||||
|
|
||||||
public LocationType[] ExcludeLocationTypes { get; set; }
|
public LocationType[] ExcludeLocationTypes { get; set; }
|
||||||
|
public string[] PresetViews { get; set; }
|
||||||
|
|
||||||
public InternalItemsQuery()
|
public InternalItemsQuery()
|
||||||
{
|
{
|
||||||
BlockUnratedItems = new UnratedItem[] { };
|
BlockUnratedItems = new UnratedItem[] { };
|
||||||
|
@ -137,6 +140,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
TopParentIds = new string[] { };
|
TopParentIds = new string[] { };
|
||||||
ExcludeTags = new string[] { };
|
ExcludeTags = new string[] { };
|
||||||
ExcludeLocationTypes = new LocationType[] { };
|
ExcludeLocationTypes = new LocationType[] { };
|
||||||
|
PresetViews = new string[] { };
|
||||||
}
|
}
|
||||||
|
|
||||||
public InternalItemsQuery(User user)
|
public InternalItemsQuery(User user)
|
||||||
|
@ -153,7 +157,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
|
|
||||||
ExcludeTags = policy.BlockedTags;
|
ExcludeTags = policy.BlockedTags;
|
||||||
|
|
||||||
User = user;
|
User = user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller.Providers;
|
using System;
|
||||||
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Users;
|
using MediaBrowser.Model.Users;
|
||||||
|
@ -6,6 +7,7 @@ using MoreLinq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities.TV
|
namespace MediaBrowser.Controller.Entities.TV
|
||||||
|
@ -127,6 +129,30 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
get { return (IndexNumber ?? -1) == 0; }
|
get { return (IndexNumber ?? -1) == 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
|
||||||
|
{
|
||||||
|
var user = query.User;
|
||||||
|
|
||||||
|
Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
|
||||||
|
|
||||||
|
IEnumerable<BaseItem> items;
|
||||||
|
|
||||||
|
if (query.User == null)
|
||||||
|
{
|
||||||
|
items = query.Recursive
|
||||||
|
? GetRecursiveChildren(filter)
|
||||||
|
: Children.Where(filter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items = GetEpisodes(query.User).Where(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = PostFilterAndSort(items, query);
|
||||||
|
|
||||||
|
return Task.FromResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the episodes.
|
/// Gets the episodes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -157,6 +157,32 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
return GetSeasons(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
return GetSeasons(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
|
||||||
|
{
|
||||||
|
var user = query.User;
|
||||||
|
|
||||||
|
Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
|
||||||
|
|
||||||
|
IEnumerable<BaseItem> items;
|
||||||
|
|
||||||
|
if (query.User == null)
|
||||||
|
{
|
||||||
|
items = query.Recursive
|
||||||
|
? GetRecursiveChildren(filter)
|
||||||
|
: Children.Where(filter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items = query.Recursive
|
||||||
|
? GetRecursiveChildren(user, filter)
|
||||||
|
: GetSeasons(user).Where(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = PostFilterAndSort(items, query);
|
||||||
|
|
||||||
|
return Task.FromResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<Season> GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired)
|
public IEnumerable<Season> GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired)
|
||||||
{
|
{
|
||||||
var seasons = base.GetChildren(user, true)
|
var seasons = base.GetChildren(user, true)
|
||||||
|
|
|
@ -78,7 +78,17 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
|
||||||
public bool Played { get; set; }
|
public bool Played { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the index of the audio stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The index of the audio stream.</value>
|
||||||
|
public int? AudioStreamIndex { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the index of the subtitle stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The index of the subtitle stream.</value>
|
||||||
|
public int? SubtitleStreamIndex { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is an interpreted property to indicate likes or dislikes
|
/// This is an interpreted property to indicate likes or dislikes
|
||||||
/// This should never be serialized.
|
/// This should never be serialized.
|
||||||
|
|
|
@ -30,7 +30,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
var result = await UserViewManager.GetUserViews(new UserViewQuery
|
var result = await UserViewManager.GetUserViews(new UserViewQuery
|
||||||
{
|
{
|
||||||
UserId = query.User.Id.ToString("N")
|
UserId = query.User.Id.ToString("N"),
|
||||||
|
PresetViews = query.PresetViews
|
||||||
|
|
||||||
}, CancellationToken.None).ConfigureAwait(false);
|
}, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,13 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// <returns>Task{Person}.</returns>
|
/// <returns>Task{Person}.</returns>
|
||||||
Person GetPerson(string name);
|
Person GetPerson(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the by path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path.</param>
|
||||||
|
/// <returns>BaseItem.</returns>
|
||||||
|
BaseItem FindByPath(string path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the artist.
|
/// Gets the artist.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -32,5 +32,12 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path.</param>
|
/// <param name="path">The path.</param>
|
||||||
void ReportFileSystemChanged(string path);
|
void ReportFileSystemChanged(string path);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether [is path locked] [the specified path].
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path.</param>
|
||||||
|
/// <returns><c>true</c> if [is path locked] [the specified path]; otherwise, <c>false</c>.</returns>
|
||||||
|
bool IsPathLocked(string path);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,12 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <value>The id of the channel.</value>
|
/// <value>The id of the channel.</value>
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the tuner host identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The tuner host identifier.</value>
|
||||||
|
public string TunerHostId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the type of the channel.
|
/// Gets or sets the type of the channel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller.Channels;
|
using System;
|
||||||
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
|
@ -343,11 +344,11 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the information to program dto.
|
/// Adds the information to program dto.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="programs">The programs.</param>
|
||||||
/// <param name="dto">The dto.</param>
|
|
||||||
/// <param name="fields">The fields.</param>
|
/// <param name="fields">The fields.</param>
|
||||||
/// <param name="user">The user.</param>
|
/// <param name="user">The user.</param>
|
||||||
void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, List<ItemFields> fields, User user = null);
|
/// <returns>Task.</returns>
|
||||||
|
Task AddInfoToProgramDto(List<Tuple<BaseItem,BaseItemDto>> programs, List<ItemFields> fields, User user = null);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the tuner host.
|
/// Saves the tuner host.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -46,6 +46,9 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task<List<MediaSourceInfo>>.</returns>
|
/// <returns>Task<List<MediaSourceInfo>>.</returns>
|
||||||
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
|
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
|
public interface IConfigurableTunerHost
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates the specified information.
|
/// Validates the specified information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -59,6 +59,12 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <value>The clients.</value>
|
/// <value>The clients.</value>
|
||||||
public List<string> Clients { get; set; }
|
public List<string> Clients { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this instance can reset.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if this instance can reset; otherwise, <c>false</c>.</value>
|
||||||
|
public bool CanReset { get; set; }
|
||||||
|
|
||||||
public LiveTvTunerInfo()
|
public LiveTvTunerInfo()
|
||||||
{
|
{
|
||||||
Clients = new List<string>();
|
Clients = new List<string>();
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Interfaces.IO">
|
<Reference Include="Interfaces.IO">
|
||||||
<HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
|
<HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
public int? CpuCoreLimit { get; set; }
|
public int? CpuCoreLimit { get; set; }
|
||||||
public bool ReadInputAtNativeFramerate { get; set; }
|
public bool ReadInputAtNativeFramerate { get; set; }
|
||||||
public SubtitleDeliveryMethod SubtitleMethod { get; set; }
|
public SubtitleDeliveryMethod SubtitleMethod { get; set; }
|
||||||
|
public bool CopyTimestamps { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this instance has fixed resolution.
|
/// Gets a value indicating whether this instance has fixed resolution.
|
||||||
|
|
|
@ -63,7 +63,8 @@ namespace MediaBrowser.Controller.Providers
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// using EnumerateFileSystemInfos doesn't handle reparse points (symlinks)
|
// using EnumerateFileSystemInfos doesn't handle reparse points (symlinks)
|
||||||
var list = _fileSystem.GetFileSystemEntries(path);
|
var list = _fileSystem.GetFileSystemEntries(path)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
// Seeing dupes on some users file system for some reason
|
// Seeing dupes on some users file system for some reason
|
||||||
foreach (var item in list)
|
foreach (var item in list)
|
||||||
|
|
|
@ -250,6 +250,13 @@ namespace MediaBrowser.Controller.Session
|
||||||
/// <returns>Task{SessionInfo}.</returns>
|
/// <returns>Task{SessionInfo}.</returns>
|
||||||
Task<AuthenticationResult> AuthenticateNewSession(AuthenticationRequest request);
|
Task<AuthenticationResult> AuthenticateNewSession(AuthenticationRequest request);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the new session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">The request.</param>
|
||||||
|
/// <returns>Task<AuthenticationResult>.</returns>
|
||||||
|
Task<AuthenticationResult> CreateNewSession(AuthenticationRequest request);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reports the capabilities.
|
/// Reports the capabilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
|
||||||
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
|
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
|
||||||
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
|
|
|
@ -453,32 +453,17 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
||||||
sortOrders.Add(ItemSortBy.SortName);
|
sortOrders.Add(ItemSortBy.SortName);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryResult<BaseItem> queryResult;
|
var queryResult = await folder.GetItems(new InternalItemsQuery
|
||||||
|
|
||||||
if (folder is UserRootFolder)
|
|
||||||
{
|
{
|
||||||
var views = await _userViewManager.GetUserViews(new UserViewQuery { UserId = user.Id.ToString("N"), PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music } }, CancellationToken.None)
|
Limit = limit,
|
||||||
.ConfigureAwait(false);
|
StartIndex = startIndex,
|
||||||
|
SortBy = sortOrders.ToArray(),
|
||||||
|
SortOrder = sort.SortOrder,
|
||||||
|
User = user,
|
||||||
|
Filter = FilterUnsupportedContent,
|
||||||
|
PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music }
|
||||||
|
|
||||||
queryResult = new QueryResult<BaseItem>
|
}).ConfigureAwait(false);
|
||||||
{
|
|
||||||
Items = views.Cast<BaseItem>().ToArray()
|
|
||||||
};
|
|
||||||
queryResult.TotalRecordCount = queryResult.Items.Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
queryResult = await folder.GetItems(new InternalItemsQuery
|
|
||||||
{
|
|
||||||
Limit = limit,
|
|
||||||
StartIndex = startIndex,
|
|
||||||
SortBy = sortOrders.ToArray(),
|
|
||||||
SortOrder = sort.SortOrder,
|
|
||||||
User = user,
|
|
||||||
Filter = FilterUnsupportedContent
|
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = _config.GetDlnaConfiguration();
|
var options = _config.GetDlnaConfiguration();
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="MoreLinq">
|
<Reference Include="MoreLinq">
|
||||||
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
||||||
|
|
|
@ -85,8 +85,6 @@ namespace MediaBrowser.Dlna.PlayTo
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var uri = new Uri(location);
|
|
||||||
|
|
||||||
lock (_nonRendererUrls)
|
lock (_nonRendererUrls)
|
||||||
{
|
{
|
||||||
if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10)
|
if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10)
|
||||||
|
@ -101,6 +99,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var uri = new Uri(location);
|
||||||
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
|
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
|
||||||
|
|
||||||
if (device.RendererCommands == null)
|
if (device.RendererCommands == null)
|
||||||
|
|
|
@ -31,8 +31,8 @@ namespace MediaBrowser.Dlna.Profiles
|
||||||
MaxIconWidth = 48;
|
MaxIconWidth = 48;
|
||||||
MaxIconHeight = 48;
|
MaxIconHeight = 48;
|
||||||
|
|
||||||
MaxStreamingBitrate = 10000000;
|
MaxStreamingBitrate = 12000000;
|
||||||
MaxStaticBitrate = 10000000;
|
MaxStaticBitrate = 12000000;
|
||||||
MusicStreamingTranscodingBitrate = 128000;
|
MusicStreamingTranscodingBitrate = 128000;
|
||||||
MusicSyncBitrate = 128000;
|
MusicSyncBitrate = 128000;
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,7 @@ namespace MediaBrowser.Dlna.Profiles
|
||||||
},
|
},
|
||||||
new DirectPlayProfile
|
new DirectPlayProfile
|
||||||
{
|
{
|
||||||
Container = "mp3",
|
Container = "mp3,flac",
|
||||||
AudioCodec = "mp3",
|
|
||||||
Type = DlnaProfileType.Audio
|
Type = DlnaProfileType.Audio
|
||||||
},
|
},
|
||||||
new DirectPlayProfile
|
new DirectPlayProfile
|
||||||
|
|
|
@ -60,8 +60,8 @@ namespace MediaBrowser.Dlna.Profiles
|
||||||
new DirectPlayProfile
|
new DirectPlayProfile
|
||||||
{
|
{
|
||||||
Container = "ts",
|
Container = "ts",
|
||||||
VideoCodec = "h264",
|
VideoCodec = "h264,mpeg2video",
|
||||||
AudioCodec = "ac3",
|
AudioCodec = "ac3,aac,mp3",
|
||||||
Type = DlnaProfileType.Video
|
Type = DlnaProfileType.Video
|
||||||
},
|
},
|
||||||
new DirectPlayProfile
|
new DirectPlayProfile
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -41,9 +41,9 @@
|
||||||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -34,9 +34,9 @@
|
||||||
<DirectPlayProfile container="avi,mp4" type="Video" />
|
<DirectPlayProfile container="avi,mp4" type="Video" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -38,9 +38,9 @@
|
||||||
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
|
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -40,8 +40,8 @@
|
||||||
<DirectPlayProfile container="jpeg,jpg" type="Photo" />
|
<DirectPlayProfile container="jpeg,jpg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mpeg" type="Video" videoCodec="mpeg2video" audioCodec="mp2" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mpeg" type="Video" videoCodec="mpeg2video" audioCodec="mp2" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles>
|
<CodecProfiles>
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -44,9 +44,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles>
|
<CodecProfiles>
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
<DirectPlayProfile container="" type="Photo" />
|
<DirectPlayProfile container="" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -43,9 +43,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -38,9 +38,9 @@
|
||||||
<DirectPlayProfile container="avi,mp4,mkv,ts" type="Video" />
|
<DirectPlayProfile container="avi,mp4,mkv,ts" type="Video" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -44,9 +44,9 @@
|
||||||
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
|
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -51,9 +51,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -39,9 +39,9 @@
|
||||||
<DirectPlayProfile container="jpeg,gif,bmp,png" type="Photo" />
|
<DirectPlayProfile container="jpeg,gif,bmp,png" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles>
|
<CodecProfiles>
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -47,13 +47,13 @@
|
||||||
<DirectPlayProfile container="vro,vob" audioCodec="ac3,mp2,mp3" videoCodec="mpeg1video,mpeg2video" type="Video" />
|
<DirectPlayProfile container="vro,vob" audioCodec="ac3,mp2,mp3" videoCodec="mpeg1video,mpeg2video" type="Video" />
|
||||||
<DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3,eac3" videoCodec="mpeg2video,h264,vc1" type="Video" />
|
<DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3,eac3" videoCodec="mpeg2video,h264,vc1" type="Video" />
|
||||||
<DirectPlayProfile container="asf" audioCodec="wmav2,wmavoice" videoCodec="wmv2,wmv3" type="Video" />
|
<DirectPlayProfile container="asf" audioCodec="wmav2,wmavoice" videoCodec="wmv2,wmv3" type="Video" />
|
||||||
<DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
|
<DirectPlayProfile container="mp3,flac" type="Audio" />
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -49,9 +49,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -48,9 +48,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="mpeg2video" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="mpeg2video" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -46,9 +46,9 @@
|
||||||
<DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
|
<DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -49,9 +49,9 @@
|
||||||
<DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
|
<DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -51,9 +51,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -46,9 +46,9 @@
|
||||||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac,mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac,mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -46,9 +46,9 @@
|
||||||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -41,9 +41,9 @@
|
||||||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -52,9 +52,9 @@
|
||||||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Photo">
|
<ContainerProfile type="Photo">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -46,9 +46,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="asf" type="Video" videoCodec="wmv2" audioCodec="wmav2" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Bytes" context="Streaming" />
|
<TranscodingProfile container="asf" type="Video" videoCodec="wmv2" audioCodec="wmav2" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Bytes" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Video" container="mp4,mov">
|
<ContainerProfile type="Video" container="mp4,mov">
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="ts" audioCodec="ac3" videoCodec="h264" type="Video" />
|
<DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264,mpeg2video" type="Video" />
|
||||||
<DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" />
|
<DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" />
|
||||||
<DirectPlayProfile container="avi" audioCodec="aac" videoCodec="h264" type="Video" />
|
<DirectPlayProfile container="avi" audioCodec="aac" videoCodec="h264" type="Video" />
|
||||||
<DirectPlayProfile container="mp4,mov,mkv" audioCodec="aac,ac3" videoCodec="h264,mpeg4,mpeg2video" type="Video" />
|
<DirectPlayProfile container="mp4,mov,mkv" audioCodec="aac,ac3" videoCodec="h264,mpeg4,mpeg2video" type="Video" />
|
||||||
|
@ -47,9 +47,9 @@
|
||||||
<DirectPlayProfile container="jpeg" type="Photo" />
|
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" videoCodec="jpeg" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" videoCodec="jpeg" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles>
|
<ContainerProfiles>
|
||||||
<ContainerProfile type="Video" container="mp4,mov">
|
<ContainerProfile type="Video" container="mp4,mov">
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||||
<MaxIconWidth>48</MaxIconWidth>
|
<MaxIconWidth>48</MaxIconWidth>
|
||||||
<MaxIconHeight>48</MaxIconHeight>
|
<MaxIconHeight>48</MaxIconHeight>
|
||||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||||
|
@ -44,9 +44,9 @@
|
||||||
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
|
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
|
|
|
@ -127,10 +127,14 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
args.EndPoint = endPoint;
|
args.EndPoint = endPoint;
|
||||||
args.LocalEndPoint = new IPEndPoint(localIp, 0);
|
args.LocalEndPoint = new IPEndPoint(localIp, 0);
|
||||||
|
|
||||||
if (!_ssdpHandler.IsSelfNotification(args))
|
if (_ssdpHandler.IgnoreMessage(args, true))
|
||||||
{
|
{
|
||||||
TryCreateDevice(args);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ssdpHandler.LogMessageReceived(args, true);
|
||||||
|
|
||||||
|
TryCreateDevice(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,14 +221,6 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.GetDlnaConfiguration().EnableDebugLog)
|
|
||||||
{
|
|
||||||
var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
|
|
||||||
var headerText = string.Join(",", headerTexts.ToArray());
|
|
||||||
|
|
||||||
_logger.Debug("{0} Device message received from {1}. Headers: {2}", args.Method, args.EndPoint, headerText);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(DeviceDiscovered, this, args, _logger);
|
EventHelper.FireEventIfNotNull(DeviceDiscovered, this, args, _logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,8 +86,15 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
|
|
||||||
public event EventHandler<SsdpMessageEventArgs> MessageReceived;
|
public event EventHandler<SsdpMessageEventArgs> MessageReceived;
|
||||||
|
|
||||||
private async void OnMessageReceived(SsdpMessageEventArgs args)
|
private async void OnMessageReceived(SsdpMessageEventArgs args, bool isMulticast)
|
||||||
{
|
{
|
||||||
|
if (IgnoreMessage(args, isMulticast))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessageReceived(args, isMulticast);
|
||||||
|
|
||||||
var headers = args.Headers;
|
var headers = args.Headers;
|
||||||
string st;
|
string st;
|
||||||
|
|
||||||
|
@ -108,6 +115,59 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
EventHelper.FireEventIfNotNull(MessageReceived, this, args, _logger);
|
EventHelper.FireEventIfNotNull(MessageReceived, this, args, _logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void LogMessageReceived(SsdpMessageEventArgs args, bool isMulticast)
|
||||||
|
{
|
||||||
|
var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLog;
|
||||||
|
|
||||||
|
if (enableDebugLogging)
|
||||||
|
{
|
||||||
|
var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
|
||||||
|
var headerText = string.Join(",", headerTexts.ToArray());
|
||||||
|
|
||||||
|
var protocol = isMulticast ? "Multicast" : "Unicast";
|
||||||
|
var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
|
||||||
|
_logger.Debug("{0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool IgnoreMessage(SsdpMessageEventArgs args, bool isMulticast)
|
||||||
|
{
|
||||||
|
string usn;
|
||||||
|
if (args.Headers.TryGetValue("USN", out usn))
|
||||||
|
{
|
||||||
|
// USN=uuid:b67df29b5c379445fde78c3774ab518d::urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1
|
||||||
|
if (RegisteredDevices.Select(i => i.USN).Contains(usn, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
//var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
|
||||||
|
//var headerText = string.Join(",", headerTexts.ToArray());
|
||||||
|
|
||||||
|
//var protocol = isMulticast ? "Multicast" : "Unicast";
|
||||||
|
//var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
|
||||||
|
//_logger.Debug("IGNORING {0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string serverId;
|
||||||
|
if (args.Headers.TryGetValue("X-EMBY-SERVERID", out serverId))
|
||||||
|
{
|
||||||
|
if (string.Equals(serverId, _appHost.SystemId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
//var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
|
||||||
|
//var headerText = string.Join(",", headerTexts.ToArray());
|
||||||
|
|
||||||
|
//var protocol = isMulticast ? "Multicast" : "Unicast";
|
||||||
|
//var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
|
||||||
|
//_logger.Debug("IGNORING {0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<UpnpDevice> RegisteredDevices
|
public IEnumerable<UpnpDevice> RegisteredDevices
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -126,7 +186,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
RestartSocketListener();
|
RestartSocketListener();
|
||||||
ReloadAliveNotifier();
|
ReloadAliveNotifier();
|
||||||
|
|
||||||
//CreateUnicastClient();
|
CreateUnicastClient();
|
||||||
|
|
||||||
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
|
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
|
||||||
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
||||||
|
@ -146,6 +206,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
|
|
||||||
values["HOST"] = "239.255.255.250:1900";
|
values["HOST"] = "239.255.255.250:1900";
|
||||||
values["USER-AGENT"] = "UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2";
|
values["USER-AGENT"] = "UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2";
|
||||||
|
values["X-EMBY-SERVERID"] = _appHost.SystemId;
|
||||||
|
|
||||||
values["MAN"] = "\"ssdp:discover\"";
|
values["MAN"] = "\"ssdp:discover\"";
|
||||||
|
|
||||||
|
@ -162,7 +223,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
// UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2)
|
// UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2)
|
||||||
SendDatagram(msg, _ssdpEndp, localIp, true);
|
SendDatagram(msg, _ssdpEndp, localIp, true);
|
||||||
|
|
||||||
//SendUnicastRequest(msg);
|
SendUnicastRequest(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void SendDatagram(string msg,
|
public async void SendDatagram(string msg,
|
||||||
|
@ -177,7 +238,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
await Task.Delay(200).ConfigureAwait(false);
|
await Task.Delay(500).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dgram = new Datagram(endpoint, localAddress, _logger, msg, isBroadcast, enableDebugLogging);
|
var dgram = new Datagram(endpoint, localAddress, _logger, msg, isBroadcast, enableDebugLogging);
|
||||||
|
@ -242,8 +303,8 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
|
|
||||||
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
|
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
|
||||||
|
|
||||||
SendDatagram(msg, endpoint, null, false, 1);
|
SendDatagram(msg, endpoint, null, false, 2);
|
||||||
SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 1);
|
SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 2);
|
||||||
//SendDatagram(header, values, endpoint, null, true);
|
//SendDatagram(header, values, endpoint, null, true);
|
||||||
|
|
||||||
if (enableDebugLogging)
|
if (enableDebugLogging)
|
||||||
|
@ -324,20 +385,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
var args = SsdpHelper.ParseSsdpResponse(received);
|
var args = SsdpHelper.ParseSsdpResponse(received);
|
||||||
args.EndPoint = endpoint;
|
args.EndPoint = endpoint;
|
||||||
|
|
||||||
if (IsSelfNotification(args))
|
OnMessageReceived(args, true);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enableDebugLogging)
|
|
||||||
{
|
|
||||||
var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
|
|
||||||
var headerText = string.Join(",", headerTexts.ToArray());
|
|
||||||
|
|
||||||
_logger.Debug("{0} message received from {1} on {3}. Headers: {2}", args.Method, args.EndPoint, headerText, _multicastSocket.LocalEndPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnMessageReceived(args);
|
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException)
|
catch (ObjectDisposedException)
|
||||||
{
|
{
|
||||||
|
@ -357,26 +405,6 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool IsSelfNotification(SsdpMessageEventArgs args)
|
|
||||||
{
|
|
||||||
// Avoid responding to self search messages
|
|
||||||
//string serverId;
|
|
||||||
//if (args.Headers.TryGetValue("X-EMBYSERVERID", out serverId) &&
|
|
||||||
// string.Equals(serverId, _appHost.SystemId, StringComparison.OrdinalIgnoreCase))
|
|
||||||
//{
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
string server;
|
|
||||||
args.Headers.TryGetValue("SERVER", out server);
|
|
||||||
|
|
||||||
if (string.Equals(server, _serverSignature, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_config.NamedConfigurationUpdated -= _config_ConfigurationUpdated;
|
_config.NamedConfigurationUpdated -= _config_ConfigurationUpdated;
|
||||||
|
@ -448,7 +476,8 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
|
|
||||||
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
|
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
|
||||||
|
|
||||||
SendDatagram(msg, _ssdpEndp, new IPEndPoint(dev.Address, 0), true);
|
SendDatagram(msg, _ssdpEndp, new IPEndPoint(dev.Address, 0), true, 1);
|
||||||
|
//SendUnicastRequest(msg, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterNotification(string uuid, Uri descriptionUri, IPAddress address, IEnumerable<string> services)
|
public void RegisterNotification(string uuid, Uri descriptionUri, IPAddress address, IEnumerable<string> services)
|
||||||
|
@ -489,14 +518,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
_logger.ErrorException("Error creating unicast client", ex);
|
_logger.ErrorException("Error creating unicast client", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
UnicastSetBeginReceive();
|
||||||
{
|
|
||||||
UnicastSetBeginReceive();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException("Error in UnicastSetBeginReceive", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,11 +544,18 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UnicastSetBeginReceive()
|
private void UnicastSetBeginReceive()
|
||||||
{
|
{
|
||||||
var ipRxEnd = new IPEndPoint(IPAddress.Any, _unicastPort);
|
try
|
||||||
var udpListener = new UdpState { EndPoint = ipRxEnd };
|
{
|
||||||
|
var ipRxEnd = new IPEndPoint(IPAddress.Any, _unicastPort);
|
||||||
|
var udpListener = new UdpState { EndPoint = ipRxEnd };
|
||||||
|
|
||||||
udpListener.UdpClient = _unicastClient;
|
udpListener.UdpClient = _unicastClient;
|
||||||
_unicastClient.BeginReceive(UnicastReceiveCallback, udpListener);
|
_unicastClient.BeginReceive(UnicastReceiveCallback, udpListener);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Error in UnicastSetBeginReceive", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -540,37 +569,66 @@ namespace MediaBrowser.Dlna.Ssdp
|
||||||
var endpoint = ((UdpState)(ar.AsyncState)).EndPoint;
|
var endpoint = ((UdpState)(ar.AsyncState)).EndPoint;
|
||||||
if (udpClient.Client != null)
|
if (udpClient.Client != null)
|
||||||
{
|
{
|
||||||
var responseBytes = udpClient.EndReceive(ar, ref endpoint);
|
try
|
||||||
var args = SsdpHelper.ParseSsdpResponse(responseBytes);
|
{
|
||||||
|
var responseBytes = udpClient.EndReceive(ar, ref endpoint);
|
||||||
|
var args = SsdpHelper.ParseSsdpResponse(responseBytes);
|
||||||
|
|
||||||
args.EndPoint = endpoint;
|
args.EndPoint = endpoint;
|
||||||
|
|
||||||
OnMessageReceived(args);
|
OnMessageReceived(args, false);
|
||||||
|
|
||||||
UnicastSetBeginReceive();
|
UnicastSetBeginReceive();
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (SocketException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SendUnicastRequest(string request)
|
private void SendUnicastRequest(string request, int sendCount = 3)
|
||||||
{
|
{
|
||||||
if (_unicastClient == null)
|
if (_unicastClient == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Sending unicast search request");
|
|
||||||
|
|
||||||
byte[] req = Encoding.ASCII.GetBytes(request);
|
|
||||||
var ipSsdp = IPAddress.Parse(SSDPAddr);
|
var ipSsdp = IPAddress.Parse(SSDPAddr);
|
||||||
var ipTxEnd = new IPEndPoint(ipSsdp, SSDPPort);
|
var ipTxEnd = new IPEndPoint(ipSsdp, SSDPPort);
|
||||||
|
|
||||||
for (var i = 0; i < 3; i++)
|
SendUnicastRequest(request, ipTxEnd, sendCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void SendUnicastRequest(string request, IPEndPoint toEndPoint, int sendCount = 3)
|
||||||
|
{
|
||||||
|
if (_unicastClient == null)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//_logger.Debug("Sending unicast request");
|
||||||
|
|
||||||
|
byte[] req = Encoding.ASCII.GetBytes(request);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (var i = 0; i < sendCount; i++)
|
||||||
{
|
{
|
||||||
await Task.Delay(50).ConfigureAwait(false);
|
if (i > 0)
|
||||||
|
{
|
||||||
|
await Task.Delay(50).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
_unicastClient.Send(req, req.Length, toEndPoint);
|
||||||
}
|
}
|
||||||
_unicastClient.Send(req, req.Length, ipTxEnd);
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Error in SendUnicastRequest", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
|
||||||
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -33,7 +33,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Patterns.Logging">
|
<Reference Include="Patterns.Logging">
|
||||||
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
|
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -460,6 +460,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
{
|
{
|
||||||
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
|
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
|
||||||
{
|
{
|
||||||
|
if (state.VideoStream != null && state.VideoStream.Width.HasValue)
|
||||||
|
{
|
||||||
|
// This is hacky but not sure how to get the exact subtitle resolution
|
||||||
|
double height = state.VideoStream.Width.Value;
|
||||||
|
height /= 16;
|
||||||
|
height *= 9;
|
||||||
|
|
||||||
|
arg += string.Format(" -canvas_size {0}:{1}", state.VideoStream.Width.Value.ToString(CultureInfo.InvariantCulture), Convert.ToInt32(height).ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
arg += " -i \"" + state.SubtitleStream.Path + "\"";
|
arg += " -i \"" + state.SubtitleStream.Path + "\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -794,6 +794,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
||||||
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
|
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
|
||||||
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||||
|
|
||||||
|
state.Options.CopyTimestamps = transcodingProfile.CopyTimestamps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
/// <param name="request">The request.</param>
|
/// <param name="request">The request.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public Task<Model.MediaInfo.MediaInfo> GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken)
|
public Task<MediaInfo> GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var extractChapters = request.MediaType == DlnaProfileType.Video && request.ExtractChapters;
|
var extractChapters = request.MediaType == DlnaProfileType.Video && request.ExtractChapters;
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task{MediaInfoResult}.</returns>
|
/// <returns>Task{MediaInfoResult}.</returns>
|
||||||
/// <exception cref="System.ApplicationException">ffprobe failed - streams and format are both null.</exception>
|
/// <exception cref="System.ApplicationException">ffprobe failed - streams and format are both null.</exception>
|
||||||
private async Task<Model.MediaInfo.MediaInfo> GetMediaInfoInternal(string inputPath,
|
private async Task<MediaInfo> GetMediaInfoInternal(string inputPath,
|
||||||
string primaryPath,
|
string primaryPath,
|
||||||
MediaProtocol protocol,
|
MediaProtocol protocol,
|
||||||
bool extractChapters,
|
bool extractChapters,
|
||||||
|
@ -934,7 +934,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
_mediaEncoder._runningProcesses.Remove(this);
|
_mediaEncoder._runningProcesses.Remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
process.Dispose();
|
try
|
||||||
|
{
|
||||||
|
process.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="DvdLib">
|
<Reference Include="DvdLib">
|
||||||
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
|
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
|
||||||
|
|
|
@ -7,7 +7,10 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
|
|
||||||
|
@ -27,7 +30,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
|
|
||||||
public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol)
|
public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol)
|
||||||
{
|
{
|
||||||
var info = new Model.MediaInfo.MediaInfo
|
var info = new MediaInfo
|
||||||
{
|
{
|
||||||
Path = path,
|
Path = path,
|
||||||
Protocol = protocol
|
Protocol = protocol
|
||||||
|
@ -56,40 +59,100 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAudio)
|
var tags = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var tagStreamType = isAudio ? "audio" : "video";
|
||||||
|
|
||||||
|
if (data.streams != null)
|
||||||
{
|
{
|
||||||
SetAudioRuntimeTicks(data, info);
|
var tagStream = data.streams.FirstOrDefault(i => string.Equals(i.codec_type, tagStreamType, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
var tags = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
if (tagStream != null && tagStream.tags != null)
|
||||||
|
|
||||||
// tags are normally located under data.format, but we've seen some cases with ogg where they're part of the audio stream
|
|
||||||
// so let's create a combined list of both
|
|
||||||
|
|
||||||
if (data.streams != null)
|
|
||||||
{
|
{
|
||||||
var audioStream = data.streams.FirstOrDefault(i => string.Equals(i.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
|
foreach (var pair in tagStream.tags)
|
||||||
|
|
||||||
if (audioStream != null && audioStream.tags != null)
|
|
||||||
{
|
|
||||||
foreach (var pair in audioStream.tags)
|
|
||||||
{
|
|
||||||
tags[pair.Key] = pair.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.format != null && data.format.tags != null)
|
|
||||||
{
|
|
||||||
foreach (var pair in data.format.tags)
|
|
||||||
{
|
{
|
||||||
tags[pair.Key] = pair.Value;
|
tags[pair.Key] = pair.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.format != null && data.format.tags != null)
|
||||||
|
{
|
||||||
|
foreach (var pair in data.format.tags)
|
||||||
|
{
|
||||||
|
tags[pair.Key] = pair.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FetchGenres(info, tags);
|
||||||
|
var shortOverview = FFProbeHelpers.GetDictionaryValue(tags, "description");
|
||||||
|
var overview = FFProbeHelpers.GetDictionaryValue(tags, "synopsis");
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(overview))
|
||||||
|
{
|
||||||
|
overview = shortOverview;
|
||||||
|
shortOverview = null;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(overview))
|
||||||
|
{
|
||||||
|
overview = FFProbeHelpers.GetDictionaryValue(tags, "desc");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(overview))
|
||||||
|
{
|
||||||
|
info.Overview = overview;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(shortOverview))
|
||||||
|
{
|
||||||
|
info.ShortOverview = shortOverview;
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = FFProbeHelpers.GetDictionaryValue(tags, "title");
|
||||||
|
if (!string.IsNullOrWhiteSpace(title))
|
||||||
|
{
|
||||||
|
info.Name = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date");
|
||||||
|
|
||||||
|
// Several different forms of retaildate
|
||||||
|
info.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ??
|
||||||
|
FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ??
|
||||||
|
FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ??
|
||||||
|
FFProbeHelpers.GetDictionaryDateTime(tags, "date");
|
||||||
|
|
||||||
|
if (isAudio)
|
||||||
|
{
|
||||||
|
SetAudioRuntimeTicks(data, info);
|
||||||
|
|
||||||
|
// tags are normally located under data.format, but we've seen some cases with ogg where they're part of the info stream
|
||||||
|
// so let's create a combined list of both
|
||||||
|
|
||||||
SetAudioInfoFromTags(info, tags);
|
SetAudioInfoFromTags(info, tags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
FetchStudios(info, tags, "copyright");
|
||||||
|
|
||||||
|
var iTunEXTC = FFProbeHelpers.GetDictionaryValue(tags, "iTunEXTC");
|
||||||
|
if (!string.IsNullOrWhiteSpace(iTunEXTC))
|
||||||
|
{
|
||||||
|
var parts = iTunEXTC.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
// Example
|
||||||
|
// mpaa|G|100|For crude humor
|
||||||
|
if (parts.Length == 4)
|
||||||
|
{
|
||||||
|
info.OfficialRating = parts[1];
|
||||||
|
info.OfficialRatingDescription = parts[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var itunesXml = FFProbeHelpers.GetDictionaryValue(tags, "iTunMOVI");
|
||||||
|
if (!string.IsNullOrWhiteSpace(itunesXml))
|
||||||
|
{
|
||||||
|
FetchFromItunesInfo(itunesXml, info);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.format != null && !string.IsNullOrEmpty(data.format.duration))
|
if (data.format != null && !string.IsNullOrEmpty(data.format.duration))
|
||||||
{
|
{
|
||||||
info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
|
info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
|
||||||
|
@ -108,10 +171,223 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FetchFromItunesInfo(string xml, MediaInfo info)
|
||||||
|
{
|
||||||
|
// Make things simpler and strip out the dtd
|
||||||
|
xml = xml.Substring(xml.IndexOf("<plist", StringComparison.OrdinalIgnoreCase));
|
||||||
|
xml = "<?xml version=\"1.0\"?>" + xml;
|
||||||
|
|
||||||
|
// <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>cast</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blender Foundation</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Janus Bager Kristensen</string>\n\t\t</dict>\n\t</array>\n\t<key>directors</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Sacha Goedegebure</string>\n\t\t</dict>\n\t</array>\n\t<key>studio</key>\n\t<string>Blender Foundation</string>\n</dict>\n</plist>\n
|
||||||
|
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
|
||||||
|
{
|
||||||
|
using (var streamReader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
// Use XmlReader for best performance
|
||||||
|
using (var reader = XmlReader.Create(streamReader))
|
||||||
|
{
|
||||||
|
reader.MoveToContent();
|
||||||
|
|
||||||
|
// Loop through each element
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if (reader.NodeType == XmlNodeType.Element)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "dict":
|
||||||
|
using (var subtree = reader.ReadSubtree())
|
||||||
|
{
|
||||||
|
ReadFromDictNode(subtree, info);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReadFromDictNode(XmlReader reader, MediaInfo info)
|
||||||
|
{
|
||||||
|
reader.MoveToContent();
|
||||||
|
|
||||||
|
string currentKey = null;
|
||||||
|
List<NameValuePair> pairs = new List<NameValuePair>();
|
||||||
|
|
||||||
|
// Loop through each element
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if (reader.NodeType == XmlNodeType.Element)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "key":
|
||||||
|
if (!string.IsNullOrWhiteSpace(currentKey))
|
||||||
|
{
|
||||||
|
ProcessPairs(currentKey, pairs, info);
|
||||||
|
}
|
||||||
|
currentKey = reader.ReadElementContentAsString();
|
||||||
|
pairs = new List<NameValuePair>();
|
||||||
|
break;
|
||||||
|
case "string":
|
||||||
|
var value = reader.ReadElementContentAsString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
pairs.Add(new NameValuePair
|
||||||
|
{
|
||||||
|
Name = value,
|
||||||
|
Value = value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "array":
|
||||||
|
if (!string.IsNullOrWhiteSpace(currentKey))
|
||||||
|
{
|
||||||
|
using (var subtree = reader.ReadSubtree())
|
||||||
|
{
|
||||||
|
pairs.AddRange(ReadValueArray(subtree));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<NameValuePair> ReadValueArray(XmlReader reader)
|
||||||
|
{
|
||||||
|
reader.MoveToContent();
|
||||||
|
|
||||||
|
List<NameValuePair> pairs = new List<NameValuePair>();
|
||||||
|
|
||||||
|
// Loop through each element
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if (reader.NodeType == XmlNodeType.Element)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "dict":
|
||||||
|
using (var subtree = reader.ReadSubtree())
|
||||||
|
{
|
||||||
|
var dict = GetNameValuePair(subtree);
|
||||||
|
if (dict != null)
|
||||||
|
{
|
||||||
|
pairs.Add(dict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessPairs(string key, List<NameValuePair> pairs, MediaInfo info)
|
||||||
|
{
|
||||||
|
if (string.Equals(key, "studio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
foreach (var pair in pairs)
|
||||||
|
{
|
||||||
|
info.Studios.Add(pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
info.Studios = info.Studios
|
||||||
|
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (string.Equals(key, "screenwriters", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
foreach (var pair in pairs)
|
||||||
|
{
|
||||||
|
info.People.Add(new BaseItemPerson
|
||||||
|
{
|
||||||
|
Name = pair.Value,
|
||||||
|
Type = PersonType.Writer
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.Equals(key, "producers", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
foreach (var pair in pairs)
|
||||||
|
{
|
||||||
|
info.People.Add(new BaseItemPerson
|
||||||
|
{
|
||||||
|
Name = pair.Value,
|
||||||
|
Type = PersonType.Producer
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.Equals(key, "directors", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
foreach (var pair in pairs)
|
||||||
|
{
|
||||||
|
info.People.Add(new BaseItemPerson
|
||||||
|
{
|
||||||
|
Name = pair.Value,
|
||||||
|
Type = PersonType.Director
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NameValuePair GetNameValuePair(XmlReader reader)
|
||||||
|
{
|
||||||
|
reader.MoveToContent();
|
||||||
|
|
||||||
|
string name = null;
|
||||||
|
string value = null;
|
||||||
|
|
||||||
|
// Loop through each element
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if (reader.NodeType == XmlNodeType.Element)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "key":
|
||||||
|
name = reader.ReadElementContentAsString();
|
||||||
|
break;
|
||||||
|
case "string":
|
||||||
|
value = reader.ReadElementContentAsString();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(name) ||
|
||||||
|
string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NameValuePair
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Value = value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts ffprobe stream info to our MediaStream class
|
/// Converts ffprobe stream info to our MediaStream class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="isAudio">if set to <c>true</c> [is audio].</param>
|
/// <param name="isAudio">if set to <c>true</c> [is info].</param>
|
||||||
/// <param name="streamInfo">The stream info.</param>
|
/// <param name="streamInfo">The stream info.</param>
|
||||||
/// <param name="formatInfo">The format info.</param>
|
/// <param name="formatInfo">The format info.</param>
|
||||||
/// <returns>MediaStream.</returns>
|
/// <returns>MediaStream.</returns>
|
||||||
|
@ -176,7 +452,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
}
|
}
|
||||||
else if (string.Equals(streamInfo.codec_type, "video", StringComparison.OrdinalIgnoreCase))
|
else if (string.Equals(streamInfo.codec_type, "video", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
stream.Type = isAudio || string.Equals(stream.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase)
|
stream.Type = isAudio || string.Equals(stream.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase) || string.Equals(stream.Codec, "gif", StringComparison.OrdinalIgnoreCase)
|
||||||
? MediaStreamType.EmbeddedImage
|
? MediaStreamType.EmbeddedImage
|
||||||
: MediaStreamType.Video;
|
: MediaStreamType.Video;
|
||||||
|
|
||||||
|
@ -388,11 +664,11 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.MediaInfo.MediaInfo data)
|
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data)
|
||||||
{
|
{
|
||||||
if (result.streams != null)
|
if (result.streams != null)
|
||||||
{
|
{
|
||||||
// Get the first audio stream
|
// Get the first info stream
|
||||||
var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
|
var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
if (stream != null)
|
if (stream != null)
|
||||||
|
@ -430,16 +706,8 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAudioInfoFromTags(Model.MediaInfo.MediaInfo audio, Dictionary<string, string> tags)
|
private void SetAudioInfoFromTags(MediaInfo audio, Dictionary<string, string> tags)
|
||||||
{
|
{
|
||||||
var title = FFProbeHelpers.GetDictionaryValue(tags, "title");
|
|
||||||
|
|
||||||
// Only set Name if title was found in the dictionary
|
|
||||||
if (!string.IsNullOrEmpty(title))
|
|
||||||
{
|
|
||||||
audio.Title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer");
|
var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer");
|
||||||
if (!string.IsNullOrWhiteSpace(composer))
|
if (!string.IsNullOrWhiteSpace(composer))
|
||||||
{
|
{
|
||||||
|
@ -458,6 +726,26 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lyricist = FFProbeHelpers.GetDictionaryValue(tags, "lyricist");
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(lyricist))
|
||||||
|
{
|
||||||
|
foreach (var person in Split(lyricist, false))
|
||||||
|
{
|
||||||
|
audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Lyricist });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for writer some music is tagged that way as alternative to composer/lyricist
|
||||||
|
var writer = FFProbeHelpers.GetDictionaryValue(tags, "writer");
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(writer))
|
||||||
|
{
|
||||||
|
foreach (var person in Split(writer, false))
|
||||||
|
{
|
||||||
|
audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Writer });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album");
|
audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album");
|
||||||
|
|
||||||
var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists");
|
var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists");
|
||||||
|
@ -511,22 +799,12 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
// Disc number
|
// Disc number
|
||||||
audio.ParentIndexNumber = GetDictionaryDiscValue(tags, "disc");
|
audio.ParentIndexNumber = GetDictionaryDiscValue(tags, "disc");
|
||||||
|
|
||||||
audio.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date");
|
|
||||||
|
|
||||||
// Several different forms of retaildate
|
|
||||||
audio.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ??
|
|
||||||
FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ??
|
|
||||||
FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ??
|
|
||||||
FFProbeHelpers.GetDictionaryDateTime(tags, "date");
|
|
||||||
|
|
||||||
// If we don't have a ProductionYear try and get it from PremiereDate
|
// If we don't have a ProductionYear try and get it from PremiereDate
|
||||||
if (audio.PremiereDate.HasValue && !audio.ProductionYear.HasValue)
|
if (audio.PremiereDate.HasValue && !audio.ProductionYear.HasValue)
|
||||||
{
|
{
|
||||||
audio.ProductionYear = audio.PremiereDate.Value.ToLocalTime().Year;
|
audio.ProductionYear = audio.PremiereDate.Value.ToLocalTime().Year;
|
||||||
}
|
}
|
||||||
|
|
||||||
FetchGenres(audio, tags);
|
|
||||||
|
|
||||||
// There's several values in tags may or may not be present
|
// There's several values in tags may or may not be present
|
||||||
FetchStudios(audio, tags, "organization");
|
FetchStudios(audio, tags, "organization");
|
||||||
FetchStudios(audio, tags, "ensemble");
|
FetchStudios(audio, tags, "ensemble");
|
||||||
|
@ -655,10 +933,10 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the studios from the tags collection
|
/// Gets the studios from the tags collection
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="audio">The audio.</param>
|
/// <param name="info">The info.</param>
|
||||||
/// <param name="tags">The tags.</param>
|
/// <param name="tags">The tags.</param>
|
||||||
/// <param name="tagName">Name of the tag.</param>
|
/// <param name="tagName">Name of the tag.</param>
|
||||||
private void FetchStudios(Model.MediaInfo.MediaInfo audio, Dictionary<string, string> tags, string tagName)
|
private void FetchStudios(MediaInfo info, Dictionary<string, string> tags, string tagName)
|
||||||
{
|
{
|
||||||
var val = FFProbeHelpers.GetDictionaryValue(tags, tagName);
|
var val = FFProbeHelpers.GetDictionaryValue(tags, tagName);
|
||||||
|
|
||||||
|
@ -669,19 +947,19 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
foreach (var studio in studios)
|
foreach (var studio in studios)
|
||||||
{
|
{
|
||||||
// Sometimes the artist name is listed here, account for that
|
// Sometimes the artist name is listed here, account for that
|
||||||
if (audio.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase))
|
if (info.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (audio.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
|
if (info.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio.Studios.Add(studio);
|
info.Studios.Add(studio);
|
||||||
}
|
}
|
||||||
|
|
||||||
audio.Studios = audio.Studios
|
info.Studios = info.Studios
|
||||||
.Where(i => !string.IsNullOrWhiteSpace(i))
|
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -693,7 +971,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="info">The information.</param>
|
/// <param name="info">The information.</param>
|
||||||
/// <param name="tags">The tags.</param>
|
/// <param name="tags">The tags.</param>
|
||||||
private void FetchGenres(Model.MediaInfo.MediaInfo info, Dictionary<string, string> tags)
|
private void FetchGenres(MediaInfo info, Dictionary<string, string> tags)
|
||||||
{
|
{
|
||||||
var val = FFProbeHelpers.GetDictionaryValue(tags, "genre");
|
var val = FFProbeHelpers.GetDictionaryValue(tags, "genre");
|
||||||
|
|
||||||
|
@ -764,7 +1042,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
|
|
||||||
private const int MaxSubtitleDescriptionExtractionLength = 100; // When extracting subtitles, the maximum length to consider (to avoid invalid filenames)
|
private const int MaxSubtitleDescriptionExtractionLength = 100; // When extracting subtitles, the maximum length to consider (to avoid invalid filenames)
|
||||||
|
|
||||||
private void FetchWtvInfo(Model.MediaInfo.MediaInfo video, InternalMediaInfoResult data)
|
private void FetchWtvInfo(MediaInfo video, InternalMediaInfoResult data)
|
||||||
{
|
{
|
||||||
if (data.format == null || data.format.tags == null)
|
if (data.format == null || data.format.tags == null)
|
||||||
{
|
{
|
||||||
|
@ -775,15 +1053,16 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(genres))
|
if (!string.IsNullOrWhiteSpace(genres))
|
||||||
{
|
{
|
||||||
//genres = FFProbeHelpers.GetDictionaryValue(data.format.tags, "genre");
|
var genreList = genres.Split(new[] { ';', '/', ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(genres))
|
|
||||||
{
|
|
||||||
video.Genres = genres.Split(new[] { ';', '/', ',' }, StringSplitOptions.RemoveEmptyEntries)
|
|
||||||
.Where(i => !string.IsNullOrWhiteSpace(i))
|
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||||
.Select(i => i.Trim())
|
.Select(i => i.Trim())
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
// If this is empty then don't overwrite genres that might have been fetched earlier
|
||||||
|
if (genreList.Count > 0)
|
||||||
|
{
|
||||||
|
video.Genres = genreList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var officialRating = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/ParentalRating");
|
var officialRating = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/ParentalRating");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
|
||||||
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
|
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -1,89 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Choose>
|
|
||||||
<When Condition="$(NCrunchOriginalSolutionDir) != '' And $(NCrunchOriginalSolutionDir) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodySolutionDir>$(NCrunchOriginalSolutionDir)</FodySolutionDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<When Condition="$(SolutionDir) != '' And $(SolutionDir) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodySolutionDir>$(SolutionDir)</FodySolutionDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<When Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodySolutionDir>$(MSBuildProjectDirectory)\..\</FodySolutionDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
</Choose>
|
|
||||||
<Choose>
|
|
||||||
<When Condition="$(KeyOriginatorFile) != '' And $(KeyOriginatorFile) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodyKeyFilePath>$(KeyOriginatorFile)</FodyKeyFilePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<When Condition="$(AssemblyOriginatorKeyFile) != '' And $(AssemblyOriginatorKeyFile) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodyKeyFilePath>$(AssemblyOriginatorKeyFile)</FodyKeyFilePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<Otherwise >
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodyKeyFilePath></FodyKeyFilePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Otherwise>
|
|
||||||
</Choose>
|
|
||||||
<PropertyGroup>
|
|
||||||
<IntermediateDir>$(ProjectDir)$(IntermediateOutputPath)</IntermediateDir>
|
|
||||||
<FodyMessageImportance Condition="$(FodyMessageImportance) == '' Or $(FodyMessageImportance) == '*Undefined*'">Low</FodyMessageImportance>
|
|
||||||
<FodySignAssembly Condition="$(FodySignAssembly) == '' Or $(FodySignAssembly) == '*Undefined*'">$(SignAssembly)</FodySignAssembly>
|
|
||||||
<FodyPath Condition="$(FodyPath) == '' Or $(FodyPath) == '*Undefined*'">$(MSBuildThisFileDirectory)</FodyPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<UsingTask
|
|
||||||
TaskName="Fody.WeavingTask"
|
|
||||||
AssemblyFile="$(FodyPath)\Fody.dll" />
|
|
||||||
<Target
|
|
||||||
AfterTargets="AfterCompile"
|
|
||||||
Name="WinFodyTarget"
|
|
||||||
Condition=" '$(OS)' == 'Windows_NT'">
|
|
||||||
|
|
||||||
<Fody.WeavingTask
|
|
||||||
AssemblyPath="@(IntermediateAssembly)"
|
|
||||||
IntermediateDir="$(IntermediateDir)"
|
|
||||||
KeyFilePath="$(FodyKeyFilePath)"
|
|
||||||
MessageImportance="$(FodyMessageImportance)"
|
|
||||||
ProjectDirectory="$(ProjectDir)"
|
|
||||||
SolutionDir="$(FodySolutionDir)"
|
|
||||||
References="@(ReferencePath)"
|
|
||||||
SignAssembly="$(FodySignAssembly)"
|
|
||||||
ReferenceCopyLocalPaths="@(ReferenceCopyLocalPaths)"
|
|
||||||
DefineConstants="$(DefineConstants)"
|
|
||||||
/>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target
|
|
||||||
AfterTargets="AfterBuild"
|
|
||||||
Name="NonWinFodyTarget"
|
|
||||||
Condition=" '$(OS)' != 'Windows_NT'">
|
|
||||||
<Fody.WeavingTask
|
|
||||||
AssemblyPath="$(TargetPath)"
|
|
||||||
IntermediateDir="$(IntermediateDir)"
|
|
||||||
KeyFilePath="$(FodyKeyFilePath)"
|
|
||||||
MessageImportance="$(FodyMessageImportance)"
|
|
||||||
ProjectDirectory="$(ProjectDir)"
|
|
||||||
SolutionDir="$(FodySolutionDir)"
|
|
||||||
References="@(ReferencePath)"
|
|
||||||
SignAssembly="$(FodySignAssembly)"
|
|
||||||
ReferenceCopyLocalPaths="$(ReferenceCopyLocalPaths)"
|
|
||||||
DefineConstants="$(DefineConstants)"
|
|
||||||
/>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
|
|
||||||
<!--Support for ncrunch-->
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="$(FodyPath)\*.*" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -15,7 +15,6 @@
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||||
<FodyPath>..\packages\Fody.1.19.1.0</FodyPath>
|
|
||||||
<FileUpgradeFlags>
|
<FileUpgradeFlags>
|
||||||
</FileUpgradeFlags>
|
</FileUpgradeFlags>
|
||||||
<UpgradeBackupLocation>
|
<UpgradeBackupLocation>
|
||||||
|
@ -58,14 +57,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- A reference to the entire .NET Framework is automatically included -->
|
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
<None Include="Fody.targets" />
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="PropertyChanged">
|
|
||||||
<HintPath>..\packages\PropertyChanged.Fody.1.41.0.0\Lib\portable-net4+sl4+wp7+win8+MonoAndroid16+MonoTouch40\PropertyChanged.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\MediaBrowser.Model\Activity\ActivityLogEntry.cs">
|
<Compile Include="..\MediaBrowser.Model\Activity\ActivityLogEntry.cs">
|
||||||
|
@ -1254,7 +1245,13 @@
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="Fody.targets" />
|
<Import Project="..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets'))" />
|
||||||
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Fody" version="1.19.1.0" targetFramework="portable-win+net45+sl40+wp71" developmentDependency="true" />
|
<package id="Fody" version="1.29.2" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
|
||||||
<package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="portable-net45+sl40+wp71+win" requireReinstallation="True" />
|
<package id="PropertyChanged.Fody" version="1.50.4" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
|
||||||
</packages>
|
</packages>
|
|
@ -182,8 +182,6 @@ namespace MediaBrowser.Model.Configuration
|
||||||
public PeopleMetadataOptions PeopleMetadataOptions { get; set; }
|
public PeopleMetadataOptions PeopleMetadataOptions { get; set; }
|
||||||
public bool FindInternetTrailers { get; set; }
|
public bool FindInternetTrailers { get; set; }
|
||||||
|
|
||||||
public string[] InsecureApps9 { get; set; }
|
|
||||||
|
|
||||||
public bool SaveMetadataHidden { get; set; }
|
public bool SaveMetadataHidden { get; set; }
|
||||||
|
|
||||||
public NameValuePair[] ContentTypes { get; set; }
|
public NameValuePair[] ContentTypes { get; set; }
|
||||||
|
@ -206,6 +204,8 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
public int MigrationVersion { get; set; }
|
public int MigrationVersion { get; set; }
|
||||||
|
|
||||||
|
public bool DownloadImagesInAdvance { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -256,11 +256,6 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
PeopleMetadataOptions = new PeopleMetadataOptions();
|
PeopleMetadataOptions = new PeopleMetadataOptions();
|
||||||
|
|
||||||
InsecureApps9 = new[]
|
|
||||||
{
|
|
||||||
"Windows Phone"
|
|
||||||
};
|
|
||||||
|
|
||||||
MetadataOptions = new[]
|
MetadataOptions = new[]
|
||||||
{
|
{
|
||||||
new MetadataOptions(1, 1280) {ItemType = "Book"},
|
new MetadataOptions(1, 1280) {ItemType = "Book"},
|
||||||
|
|
|
@ -48,11 +48,19 @@ namespace MediaBrowser.Model.Configuration
|
||||||
public bool HidePlayedInLatest { get; set; }
|
public bool HidePlayedInLatest { get; set; }
|
||||||
public bool DisplayChannelsInline { get; set; }
|
public bool DisplayChannelsInline { get; set; }
|
||||||
|
|
||||||
|
public bool RememberAudioSelections { get; set; }
|
||||||
|
public bool RememberSubtitleSelections { get; set; }
|
||||||
|
public bool EnableNextEpisodeAutoPlay { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UserConfiguration()
|
public UserConfiguration()
|
||||||
{
|
{
|
||||||
|
EnableNextEpisodeAutoPlay = true;
|
||||||
|
RememberAudioSelections = true;
|
||||||
|
RememberSubtitleSelections = true;
|
||||||
|
|
||||||
HidePlayedInLatest = true;
|
HidePlayedInLatest = true;
|
||||||
PlayDefaultAudioTrack = true;
|
PlayDefaultAudioTrack = true;
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||||
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',')[0];
|
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',')[0];
|
||||||
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
|
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
|
||||||
|
playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps;
|
||||||
playlistItem.SubProtocol = transcodingProfile.Protocol;
|
playlistItem.SubProtocol = transcodingProfile.Protocol;
|
||||||
playlistItem.AudioStreamIndex = audioStreamIndex;
|
playlistItem.AudioStreamIndex = audioStreamIndex;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
public string VideoProfile { get; set; }
|
public string VideoProfile { get; set; }
|
||||||
|
|
||||||
public bool? Cabac { get; set; }
|
public bool? Cabac { get; set; }
|
||||||
|
public bool CopyTimestamps { get; set; }
|
||||||
public string AudioCodec { get; set; }
|
public string AudioCodec { get; set; }
|
||||||
|
|
||||||
public int? AudioStreamIndex { get; set; }
|
public int? AudioStreamIndex { get; set; }
|
||||||
|
@ -231,6 +232,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
list.Add(new NameValuePair("ItemId", item.ItemId));
|
list.Add(new NameValuePair("ItemId", item.ItemId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list.Add(new NameValuePair("CopyTimestamps", (item.CopyTimestamps).ToString().ToLower()));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +272,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
// HLS will preserve timestamps so we can just grab the full subtitle stream
|
// HLS will preserve timestamps so we can just grab the full subtitle stream
|
||||||
long startPositionTicks = StringHelper.EqualsIgnoreCase(SubProtocol, "hls")
|
long startPositionTicks = StringHelper.EqualsIgnoreCase(SubProtocol, "hls")
|
||||||
? 0
|
? 0
|
||||||
: (this.PlayMethod == PlayMethod.Transcode ? StartPositionTicks : 0);
|
: (PlayMethod == PlayMethod.Transcode && !CopyTimestamps ? StartPositionTicks : 0);
|
||||||
|
|
||||||
// First add the selected track
|
// First add the selected track
|
||||||
if (SubtitleStreamIndex.HasValue)
|
if (SubtitleStreamIndex.HasValue)
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace MediaBrowser.Model.Dlna
|
||||||
[XmlAttribute("transcodeSeekInfo")]
|
[XmlAttribute("transcodeSeekInfo")]
|
||||||
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
|
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
|
||||||
|
|
||||||
|
[XmlAttribute("copyTimestamps")]
|
||||||
|
public bool CopyTimestamps { get; set; }
|
||||||
|
|
||||||
[XmlAttribute("context")]
|
[XmlAttribute("context")]
|
||||||
public EncodingContext Context { get; set; }
|
public EncodingContext Context { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -34,5 +34,9 @@ namespace MediaBrowser.Model.Entities
|
||||||
/// The conductor
|
/// The conductor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string Conductor = "Conductor";
|
public const string Conductor = "Conductor";
|
||||||
|
/// <summary>
|
||||||
|
/// The lyricist
|
||||||
|
/// </summary>
|
||||||
|
public const string Lyricist = "Lyricist";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace MediaBrowser.Model.FileOrganization
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Model.FileOrganization
|
||||||
{
|
{
|
||||||
public class EpisodeFileOrganizationRequest
|
public class EpisodeFileOrganizationRequest
|
||||||
{
|
{
|
||||||
|
@ -13,5 +15,12 @@
|
||||||
public int? EndingEpisodeNumber { get; set; }
|
public int? EndingEpisodeNumber { get; set; }
|
||||||
|
|
||||||
public bool RememberCorrection { get; set; }
|
public bool RememberCorrection { get; set; }
|
||||||
|
public string NewSeriesName { get; set; }
|
||||||
|
|
||||||
|
public string NewSeriesYear { get; set; }
|
||||||
|
|
||||||
|
public string TargetFolder { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<string, string> NewSeriesProviderIds { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,89 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Choose>
|
|
||||||
<When Condition="$(NCrunchOriginalSolutionDir) != '' And $(NCrunchOriginalSolutionDir) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodySolutionDir>$(NCrunchOriginalSolutionDir)</FodySolutionDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<When Condition="$(SolutionDir) != '' And $(SolutionDir) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodySolutionDir>$(SolutionDir)</FodySolutionDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<When Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodySolutionDir>$(MSBuildProjectDirectory)\..\</FodySolutionDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
</Choose>
|
|
||||||
<Choose>
|
|
||||||
<When Condition="$(KeyOriginatorFile) != '' And $(KeyOriginatorFile) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodyKeyFilePath>$(KeyOriginatorFile)</FodyKeyFilePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<When Condition="$(AssemblyOriginatorKeyFile) != '' And $(AssemblyOriginatorKeyFile) != '*Undefined*'">
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodyKeyFilePath>$(AssemblyOriginatorKeyFile)</FodyKeyFilePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</When>
|
|
||||||
<Otherwise >
|
|
||||||
<PropertyGroup>
|
|
||||||
<FodyKeyFilePath></FodyKeyFilePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Otherwise>
|
|
||||||
</Choose>
|
|
||||||
<PropertyGroup>
|
|
||||||
<IntermediateDir>$(ProjectDir)$(IntermediateOutputPath)</IntermediateDir>
|
|
||||||
<FodyMessageImportance Condition="$(FodyMessageImportance) == '' Or $(FodyMessageImportance) == '*Undefined*'">Low</FodyMessageImportance>
|
|
||||||
<FodySignAssembly Condition="$(FodySignAssembly) == '' Or $(FodySignAssembly) == '*Undefined*'">$(SignAssembly)</FodySignAssembly>
|
|
||||||
<FodyPath Condition="$(FodyPath) == '' Or $(FodyPath) == '*Undefined*'">$(MSBuildThisFileDirectory)</FodyPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<UsingTask
|
|
||||||
TaskName="Fody.WeavingTask"
|
|
||||||
AssemblyFile="$(FodyPath)\Fody.dll" />
|
|
||||||
<Target
|
|
||||||
AfterTargets="AfterCompile"
|
|
||||||
Name="WinFodyTarget"
|
|
||||||
Condition=" '$(OS)' == 'Windows_NT'">
|
|
||||||
|
|
||||||
<Fody.WeavingTask
|
|
||||||
AssemblyPath="@(IntermediateAssembly)"
|
|
||||||
IntermediateDir="$(IntermediateDir)"
|
|
||||||
KeyFilePath="$(FodyKeyFilePath)"
|
|
||||||
MessageImportance="$(FodyMessageImportance)"
|
|
||||||
ProjectDirectory="$(ProjectDir)"
|
|
||||||
SolutionDir="$(FodySolutionDir)"
|
|
||||||
References="@(ReferencePath)"
|
|
||||||
SignAssembly="$(FodySignAssembly)"
|
|
||||||
ReferenceCopyLocalPaths="@(ReferenceCopyLocalPaths)"
|
|
||||||
DefineConstants="$(DefineConstants)"
|
|
||||||
/>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target
|
|
||||||
AfterTargets="AfterBuild"
|
|
||||||
Name="NonWinFodyTarget"
|
|
||||||
Condition=" '$(OS)' != 'Windows_NT'">
|
|
||||||
<Fody.WeavingTask
|
|
||||||
AssemblyPath="$(TargetPath)"
|
|
||||||
IntermediateDir="$(IntermediateDir)"
|
|
||||||
KeyFilePath="$(FodyKeyFilePath)"
|
|
||||||
MessageImportance="$(FodyMessageImportance)"
|
|
||||||
ProjectDirectory="$(ProjectDir)"
|
|
||||||
SolutionDir="$(FodySolutionDir)"
|
|
||||||
References="@(ReferencePath)"
|
|
||||||
SignAssembly="$(FodySignAssembly)"
|
|
||||||
ReferenceCopyLocalPaths="$(ReferenceCopyLocalPaths)"
|
|
||||||
DefineConstants="$(DefineConstants)"
|
|
||||||
/>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
|
|
||||||
<!--Support for ncrunch-->
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="$(FodyPath)\*.*" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Weavers>
|
<Weavers>
|
||||||
<PropertyChanged />
|
<PropertyChanged />
|
||||||
</Weavers>
|
</Weavers>
|
|
@ -15,7 +15,7 @@ namespace MediaBrowser.Model.LiveTv
|
||||||
|
|
||||||
public int PrePaddingSeconds { get; set; }
|
public int PrePaddingSeconds { get; set; }
|
||||||
public int PostPaddingSeconds { get; set; }
|
public int PostPaddingSeconds { get; set; }
|
||||||
|
|
||||||
public LiveTvOptions()
|
public LiveTvOptions()
|
||||||
{
|
{
|
||||||
EnableMovieProviders = true;
|
EnableMovieProviders = true;
|
||||||
|
@ -32,6 +32,8 @@ namespace MediaBrowser.Model.LiveTv
|
||||||
public bool ImportFavoritesOnly { get; set; }
|
public bool ImportFavoritesOnly { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
|
public int DataVersion { get; set; }
|
||||||
|
|
||||||
public TunerHostInfo()
|
public TunerHostInfo()
|
||||||
{
|
{
|
||||||
IsEnabled = true;
|
IsEnabled = true;
|
||||||
|
@ -47,5 +49,15 @@ namespace MediaBrowser.Model.LiveTv
|
||||||
public string ListingsId { get; set; }
|
public string ListingsId { get; set; }
|
||||||
public string ZipCode { get; set; }
|
public string ZipCode { get; set; }
|
||||||
public string Country { get; set; }
|
public string Country { get; set; }
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
|
public string[] EnabledTuners { get; set; }
|
||||||
|
public bool EnableAllTuners { get; set; }
|
||||||
|
|
||||||
|
public ListingsProviderInfo()
|
||||||
|
{
|
||||||
|
EnabledTuners = new string[] { };
|
||||||
|
EnableAllTuners = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -64,6 +64,12 @@ namespace MediaBrowser.Model.LiveTv
|
||||||
/// <value>The clients.</value>
|
/// <value>The clients.</value>
|
||||||
public List<string> Clients { get; set; }
|
public List<string> Clients { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this instance can reset.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if this instance can reset; otherwise, <c>false</c>.</value>
|
||||||
|
public bool CanReset { get; set; }
|
||||||
|
|
||||||
public LiveTvTunerInfoDto()
|
public LiveTvTunerInfoDto()
|
||||||
{
|
{
|
||||||
Clients = new List<string>();
|
Clients = new List<string>();
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
<AssemblyName>MediaBrowser.Model</AssemblyName>
|
<AssemblyName>MediaBrowser.Model</AssemblyName>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||||
<FodyPath>..\packages\Fody.1.19.1.0</FodyPath>
|
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<ReleaseVersion>
|
<ReleaseVersion>
|
||||||
</ReleaseVersion>
|
</ReleaseVersion>
|
||||||
|
@ -442,30 +441,30 @@
|
||||||
<Compile Include="Users\UserAction.cs" />
|
<Compile Include="Users\UserAction.cs" />
|
||||||
<Compile Include="Users\UserActionType.cs" />
|
<Compile Include="Users\UserActionType.cs" />
|
||||||
<Compile Include="Users\UserPolicy.cs" />
|
<Compile Include="Users\UserPolicy.cs" />
|
||||||
<None Include="Fody.targets" />
|
|
||||||
<None Include="FodyWeavers.xml" />
|
<None Include="FodyWeavers.xml" />
|
||||||
<None Include="MediaBrowser.Model.snk" />
|
<None Include="MediaBrowser.Model.snk" />
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Runtime.Serialization" />
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
<Reference Include="PropertyChanged">
|
|
||||||
<HintPath>..\packages\PropertyChanged.Fody.1.41.0.0\Lib\NET35\PropertyChanged.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent />
|
<PostBuildEvent />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="Fody.targets" />
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent />
|
<PostBuildEvent />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<Import Project="..\packages\Fody.1.29.2\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\dotnet\Fody.targets'))" />
|
||||||
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
@ -9,11 +9,6 @@ namespace MediaBrowser.Model.MediaInfo
|
||||||
{
|
{
|
||||||
public List<ChapterInfo> Chapters { get; set; }
|
public List<ChapterInfo> Chapters { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the title.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The title.</value>
|
|
||||||
public string Title { get; set; }
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the album.
|
/// Gets or sets the album.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -47,10 +42,20 @@ namespace MediaBrowser.Model.MediaInfo
|
||||||
/// <value>The official rating.</value>
|
/// <value>The official rating.</value>
|
||||||
public string OfficialRating { get; set; }
|
public string OfficialRating { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Gets or sets the official rating description.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The official rating description.</value>
|
||||||
|
public string OfficialRatingDescription { get; set; }
|
||||||
|
/// <summary>
|
||||||
/// Gets or sets the overview.
|
/// Gets or sets the overview.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The overview.</value>
|
/// <value>The overview.</value>
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the short overview.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The short overview.</value>
|
||||||
|
public string ShortOverview { get; set; }
|
||||||
|
|
||||||
public MediaInfo()
|
public MediaInfo()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Fody" version="1.19.1.0" targetFramework="net45" developmentDependency="true" />
|
<package id="Fody" version="1.29.2" targetFramework="net45" developmentDependency="true" />
|
||||||
<package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="net45" />
|
<package id="PropertyChanged.Fody" version="1.50.4" targetFramework="net45" developmentDependency="true" />
|
||||||
</packages>
|
</packages>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user