commit
8fc7d7ba02
|
@ -33,7 +33,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<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 Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
|
|
|
@ -155,6 +155,7 @@ namespace Emby.Drawing.ImageMagick
|
|||
AutoOrientImage(originalImage);
|
||||
}
|
||||
|
||||
AddForegroundLayer(originalImage, options);
|
||||
DrawIndicator(originalImage, width, height, options);
|
||||
|
||||
originalImage.CurrentImage.CompressionQuality = quality;
|
||||
|
@ -177,6 +178,8 @@ namespace Emby.Drawing.ImageMagick
|
|||
}
|
||||
|
||||
wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0);
|
||||
|
||||
AddForegroundLayer(wand, options);
|
||||
DrawIndicator(wand, width, height, options);
|
||||
|
||||
wand.CurrentImage.CompressionQuality = quality;
|
||||
|
@ -189,6 +192,23 @@ namespace Emby.Drawing.ImageMagick
|
|||
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)
|
||||
{
|
||||
wand.CurrentImage.AutoOrientImage();
|
||||
|
|
|
@ -234,7 +234,7 @@ namespace Emby.Drawing
|
|||
var quality = options.Quality;
|
||||
|
||||
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);
|
||||
|
||||
|
@ -473,7 +473,7 @@ namespace Emby.Drawing
|
|||
/// <summary>
|
||||
/// Gets the cache file path based on a set of parameters
|
||||
/// </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;
|
||||
|
||||
|
@ -507,6 +507,11 @@ namespace Emby.Drawing
|
|||
filename += "b=" + backgroundColor;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(foregroundLayer))
|
||||
{
|
||||
filename += "fl=" + foregroundLayer;
|
||||
}
|
||||
|
||||
filename += "v=" + Version;
|
||||
|
||||
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||
</packages>
|
|
@ -1,10 +1,8 @@
|
|||
using System;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Connect;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Model.Connect;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using ServiceStack;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -75,28 +73,6 @@ namespace MediaBrowser.Api
|
|||
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
|
||||
{
|
||||
private readonly IConnectManager _connectManager;
|
||||
|
@ -108,35 +84,6 @@ namespace MediaBrowser.Api
|
|||
_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)
|
||||
{
|
||||
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")]
|
||||
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()
|
||||
{
|
||||
EnableImageEnhancers = true;
|
||||
|
|
|
@ -624,6 +624,7 @@ namespace MediaBrowser.Api.Images
|
|||
PercentPlayed = request.PercentPlayed ?? 0,
|
||||
UnplayedCount = request.UnplayedCount,
|
||||
BackgroundColor = request.BackgroundColor,
|
||||
ForegroundLayer = request.ForegroundLayer,
|
||||
SupportedOutputFormats = supportedFormats
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ using MediaBrowser.Model.Querying;
|
|||
using ServiceStack;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Api.Library
|
||||
{
|
||||
|
@ -54,7 +55,7 @@ namespace MediaBrowser.Api.Library
|
|||
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
|
||||
{
|
||||
[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")]
|
||||
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")]
|
||||
|
@ -106,9 +119,14 @@ namespace MediaBrowser.Api.Library
|
|||
{
|
||||
private readonly IFileOrganizationService _iFileOrganizationService;
|
||||
|
||||
public FileOrganizationService(IFileOrganizationService iFileOrganizationService)
|
||||
/// The _json serializer
|
||||
/// </summary>
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
|
||||
public FileOrganizationService(IFileOrganizationService iFileOrganizationService, IJsonSerializer jsonSerializer)
|
||||
{
|
||||
_iFileOrganizationService = iFileOrganizationService;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
}
|
||||
|
||||
public object Get(GetFileOrganizationActivity request)
|
||||
|
@ -145,6 +163,13 @@ namespace MediaBrowser.Api.Library
|
|||
|
||||
public void Post(OrganizeEpisode request)
|
||||
{
|
||||
var dicNewProviderIds = new Dictionary<string, string>();
|
||||
|
||||
if (request.NewSeriesProviderIds != null)
|
||||
{
|
||||
dicNewProviderIds = request.NewSeriesProviderIds;
|
||||
}
|
||||
|
||||
var task = _iFileOrganizationService.PerformEpisodeOrganization(new EpisodeFileOrganizationRequest
|
||||
{
|
||||
EndingEpisodeNumber = request.EndingEpisodeNumber,
|
||||
|
@ -152,9 +177,17 @@ namespace MediaBrowser.Api.Library
|
|||
RememberCorrection = request.RememberCorrection,
|
||||
ResultId = request.Id,
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<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 Include="MoreLinq">
|
||||
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
||||
|
@ -80,7 +80,6 @@
|
|||
<Compile Include="FilterService.cs" />
|
||||
<Compile Include="IHasDtoOptions.cs" />
|
||||
<Compile Include="Library\ChapterService.cs" />
|
||||
<Compile Include="PinLoginService.cs" />
|
||||
<Compile Include="Playback\Dash\ManifestBuilder.cs" />
|
||||
<Compile Include="Playback\Dash\MpegDashService.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;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -604,6 +604,10 @@ namespace MediaBrowser.Api.Playback
|
|||
{
|
||||
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)
|
||||
{
|
||||
var subtitlePath = state.SubtitleStream.Path;
|
||||
|
@ -621,18 +625,18 @@ namespace MediaBrowser.Api.Playback
|
|||
}
|
||||
|
||||
// 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),
|
||||
charsetParam,
|
||||
seconds.ToString(UsCulture));
|
||||
setPtsParam);
|
||||
}
|
||||
|
||||
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),
|
||||
state.InternalSubtitleStreamOffset.ToString(UsCulture),
|
||||
seconds.ToString(UsCulture));
|
||||
setPtsParam);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -865,6 +869,15 @@ namespace MediaBrowser.Api.Playback
|
|||
{
|
||||
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 + "\"";
|
||||
}
|
||||
}
|
||||
|
@ -1462,6 +1475,13 @@ namespace MediaBrowser.Api.Playback
|
|||
{
|
||||
// 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.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
|
||||
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 (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.wtv", "GET")]
|
||||
[Route("/Videos/{Id}/stream.mov", "GET")]
|
||||
[Route("/Videos/{Id}/stream.iso", "GET")]
|
||||
[Route("/Videos/{Id}/stream", "GET")]
|
||||
[Route("/Videos/{Id}/stream.ts", "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.m2ts", "HEAD")]
|
||||
[Route("/Videos/{Id}/stream.mov", "HEAD")]
|
||||
[Route("/Videos/{Id}/stream.iso", "HEAD")]
|
||||
[Route("/Videos/{Id}/stream", "HEAD")]
|
||||
[Api(Description = "Gets a video stream")]
|
||||
public class GetVideoStream : VideoStreamRequest
|
||||
|
@ -65,7 +67,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
/// </summary>
|
||||
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);
|
||||
|
||||
if (state.RunTimeTicks.HasValue)
|
||||
{
|
||||
//args += " -copyts -avoid_negative_ts disabled -start_at_zero";
|
||||
}
|
||||
|
||||
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (state.VideoStream != null && IsH264(state.VideoStream) &&
|
||||
|
@ -150,6 +148,11 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
args += " -bsf:v h264_mp4toannexb";
|
||||
}
|
||||
|
||||
if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
|
||||
{
|
||||
args += " -copyts -avoid_negative_ts disabled -start_at_zero";
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
@ -160,10 +163,22 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
|
||||
|
||||
var hasCopyTs = false;
|
||||
// Add resolution params, if specified
|
||||
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);
|
||||
|
|
|
@ -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")]
|
||||
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")]
|
||||
public bool? Cabac { get; set; }
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ using ServiceStack;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
|
||||
namespace MediaBrowser.Api.ScheduledTasks
|
||||
{
|
||||
|
@ -90,12 +91,14 @@ namespace MediaBrowser.Api.ScheduledTasks
|
|||
/// <value>The task manager.</value>
|
||||
private ITaskManager TaskManager { get; set; }
|
||||
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ScheduledTaskService" /> class.
|
||||
/// </summary>
|
||||
/// <param name="taskManager">The task manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">taskManager</exception>
|
||||
public ScheduledTaskService(ITaskManager taskManager)
|
||||
/// <exception cref="ArgumentNullException">taskManager</exception>
|
||||
public ScheduledTaskService(ITaskManager taskManager, IServerConfigurationManager config)
|
||||
{
|
||||
if (taskManager == null)
|
||||
{
|
||||
|
@ -103,6 +106,7 @@ namespace MediaBrowser.Api.ScheduledTasks
|
|||
}
|
||||
|
||||
TaskManager = taskManager;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -194,6 +198,20 @@ namespace MediaBrowser.Api.ScheduledTasks
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -415,23 +415,6 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
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
|
||||
{
|
||||
App = auth.Client,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||
</packages>
|
|
@ -49,7 +49,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<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 Include="MoreLinq">
|
||||
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MediaBrowser.Common.Implementations.Networking
|
|||
Logger = logger;
|
||||
}
|
||||
|
||||
private volatile List<IPAddress> _localIpAddresses;
|
||||
private List<IPAddress> _localIpAddresses;
|
||||
private readonly object _localIpAddressSyncLock = new object();
|
||||
|
||||
/// <summary>
|
||||
|
@ -29,24 +29,20 @@ namespace MediaBrowser.Common.Implementations.Networking
|
|||
/// <returns>IPAddress.</returns>
|
||||
public IEnumerable<IPAddress> GetLocalIpAddresses()
|
||||
{
|
||||
const int cacheMinutes = 3;
|
||||
var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
|
||||
const int cacheMinutes = 5;
|
||||
|
||||
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)
|
||||
{
|
||||
var addresses = GetLocalIpAddressesInternal().ToList();
|
||||
_localIpAddresses = addresses;
|
||||
_lastRefresh = DateTime.UtcNow;
|
||||
|
||||
_localIpAddresses = addresses;
|
||||
_lastRefresh = DateTime.UtcNow;
|
||||
|
||||
return addresses;
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
|||
Logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
|
||||
ReloadTriggerEvents(true);
|
||||
InitTriggerEvents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -233,11 +233,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
|||
/// <summary>
|
||||
/// The _triggers
|
||||
/// </summary>
|
||||
private volatile List<ITaskTrigger> _triggers;
|
||||
/// <summary>
|
||||
/// The _triggers sync lock
|
||||
/// </summary>
|
||||
private readonly object _triggersSyncLock = new object();
|
||||
private List<ITaskTrigger> _triggers;
|
||||
/// <summary>
|
||||
/// Gets the triggers that define when the task will run
|
||||
/// </summary>
|
||||
|
@ -247,17 +243,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
|||
{
|
||||
get
|
||||
{
|
||||
if (_triggers == null)
|
||||
{
|
||||
lock (_triggersSyncLock)
|
||||
{
|
||||
if (_triggers == null)
|
||||
{
|
||||
_triggers = LoadTriggers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _triggers;
|
||||
}
|
||||
set
|
||||
|
@ -303,6 +288,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
|
|||
}
|
||||
}
|
||||
|
||||
private void InitTriggerEvents()
|
||||
{
|
||||
_triggers = LoadTriggers();
|
||||
ReloadTriggerEvents(true);
|
||||
}
|
||||
|
||||
public void ReloadTriggerEvents()
|
||||
{
|
||||
ReloadTriggerEvents(false);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="NLog" version="4.2.3" 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>
|
||||
/// <returns><c>true</c> if [is authorization token valid] [the specified token]; otherwise, <c>false</c>.</returns>
|
||||
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 string BackgroundColor { get; set; }
|
||||
public string ForegroundLayer { get; set; }
|
||||
|
||||
public bool HasDefaultOptions(string originalImagePath)
|
||||
{
|
||||
|
@ -83,7 +84,8 @@ namespace MediaBrowser.Controller.Drawing
|
|||
!AddPlayedIndicator &&
|
||||
PercentPlayed.Equals(0) &&
|
||||
!UnplayedCount.HasValue &&
|
||||
string.IsNullOrEmpty(BackgroundColor);
|
||||
string.IsNullOrEmpty(BackgroundColor) &&
|
||||
string.IsNullOrEmpty(ForegroundLayer);
|
||||
}
|
||||
|
||||
private bool IsFormatSupported(string originalImagePath)
|
||||
|
|
|
@ -1359,7 +1359,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
if (!string.IsNullOrEmpty(info.Path))
|
||||
{
|
||||
var itemByPath = LibraryManager.RootFolder.FindByPath(info.Path);
|
||||
var itemByPath = LibraryManager.FindByPath(info.Path);
|
||||
|
||||
if (itemByPath == null)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasMediaSources : IHasId
|
||||
public interface IHasMediaSources : IHasUserData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the media sources.
|
||||
|
|
|
@ -45,6 +45,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
public string NameLessThan { get; set; }
|
||||
public string NameContains { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public string Person { get; set; }
|
||||
public string[] PersonIds { get; set; }
|
||||
public string[] ItemIds { get; set; }
|
||||
|
@ -96,7 +98,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public int? MinIndexNumber { get; set; }
|
||||
public double? MinCriticRating { get; set; }
|
||||
public double? MinCommunityRating { get; set; }
|
||||
|
||||
|
||||
public string[] ChannelIds { get; set; }
|
||||
|
||||
internal List<Guid> ItemIdsFromPersonFilters { get; set; }
|
||||
|
@ -112,7 +114,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
public string[] TopParentIds { get; set; }
|
||||
|
||||
public LocationType[] ExcludeLocationTypes { get; set; }
|
||||
|
||||
public string[] PresetViews { get; set; }
|
||||
|
||||
public InternalItemsQuery()
|
||||
{
|
||||
BlockUnratedItems = new UnratedItem[] { };
|
||||
|
@ -137,6 +140,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
TopParentIds = new string[] { };
|
||||
ExcludeTags = new string[] { };
|
||||
ExcludeLocationTypes = new LocationType[] { };
|
||||
PresetViews = new string[] { };
|
||||
}
|
||||
|
||||
public InternalItemsQuery(User user)
|
||||
|
@ -153,7 +157,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
ExcludeTags = policy.BlockedTags;
|
||||
|
||||
|
||||
User = user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Providers;
|
||||
using System;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
@ -6,6 +7,7 @@ using MoreLinq;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.TV
|
||||
|
@ -127,6 +129,30 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
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>
|
||||
/// Gets the episodes.
|
||||
/// </summary>
|
||||
|
|
|
@ -157,6 +157,32 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
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)
|
||||
{
|
||||
var seasons = base.GetChildren(user, true)
|
||||
|
|
|
@ -78,7 +78,17 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
|
||||
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>
|
||||
/// This is an interpreted property to indicate likes or dislikes
|
||||
/// This should never be serialized.
|
||||
|
|
|
@ -30,7 +30,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -56,6 +56,13 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <returns>Task{Person}.</returns>
|
||||
Person GetPerson(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the by path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem FindByPath(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the artist.
|
||||
/// </summary>
|
||||
|
|
|
@ -32,5 +32,12 @@ namespace MediaBrowser.Controller.Library
|
|||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
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>
|
||||
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>
|
||||
/// Gets or sets the type of the channel.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Channels;
|
||||
using System;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
@ -343,11 +344,11 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <summary>
|
||||
/// Adds the information to program dto.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="programs">The programs.</param>
|
||||
/// <param name="fields">The fields.</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>
|
||||
/// Saves the tuner host.
|
||||
/// </summary>
|
||||
|
|
|
@ -46,6 +46,9 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<List<MediaSourceInfo>>.</returns>
|
||||
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
|
||||
}
|
||||
public interface IConfigurableTunerHost
|
||||
{
|
||||
/// <summary>
|
||||
/// Validates the specified information.
|
||||
/// </summary>
|
||||
|
|
|
@ -59,6 +59,12 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <value>The clients.</value>
|
||||
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()
|
||||
{
|
||||
Clients = new List<string>();
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<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 Include="Interfaces.IO">
|
||||
<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 bool ReadInputAtNativeFramerate { get; set; }
|
||||
public SubtitleDeliveryMethod SubtitleMethod { get; set; }
|
||||
public bool CopyTimestamps { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance has fixed resolution.
|
||||
|
|
|
@ -63,7 +63,8 @@ namespace MediaBrowser.Controller.Providers
|
|||
try
|
||||
{
|
||||
// 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
|
||||
foreach (var item in list)
|
||||
|
|
|
@ -250,6 +250,13 @@ namespace MediaBrowser.Controller.Session
|
|||
/// <returns>Task{SessionInfo}.</returns>
|
||||
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>
|
||||
/// Reports the capabilities.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="morelinq" version="1.4.0" 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);
|
||||
}
|
||||
|
||||
QueryResult<BaseItem> queryResult;
|
||||
|
||||
if (folder is UserRootFolder)
|
||||
var queryResult = await folder.GetItems(new InternalItemsQuery
|
||||
{
|
||||
var views = await _userViewManager.GetUserViews(new UserViewQuery { UserId = user.Id.ToString("N"), PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music } }, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
Limit = limit,
|
||||
StartIndex = startIndex,
|
||||
SortBy = sortOrders.ToArray(),
|
||||
SortOrder = sort.SortOrder,
|
||||
User = user,
|
||||
Filter = FilterUnsupportedContent,
|
||||
PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music }
|
||||
|
||||
queryResult = new QueryResult<BaseItem>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var options = _config.GetDlnaConfiguration();
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<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 Include="MoreLinq">
|
||||
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
|
||||
|
|
|
@ -85,8 +85,6 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||
|
||||
try
|
||||
{
|
||||
var uri = new Uri(location);
|
||||
|
||||
lock (_nonRendererUrls)
|
||||
{
|
||||
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);
|
||||
|
||||
if (device.RendererCommands == null)
|
||||
|
|
|
@ -31,8 +31,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||
MaxIconWidth = 48;
|
||||
MaxIconHeight = 48;
|
||||
|
||||
MaxStreamingBitrate = 10000000;
|
||||
MaxStaticBitrate = 10000000;
|
||||
MaxStreamingBitrate = 12000000;
|
||||
MaxStaticBitrate = 12000000;
|
||||
MusicStreamingTranscodingBitrate = 128000;
|
||||
MusicSyncBitrate = 128000;
|
||||
|
||||
|
|
|
@ -119,8 +119,7 @@ namespace MediaBrowser.Dlna.Profiles
|
|||
},
|
||||
new DirectPlayProfile
|
||||
{
|
||||
Container = "mp3",
|
||||
AudioCodec = "mp3",
|
||||
Container = "mp3,flac",
|
||||
Type = DlnaProfileType.Audio
|
||||
},
|
||||
new DirectPlayProfile
|
||||
|
|
|
@ -60,8 +60,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||
new DirectPlayProfile
|
||||
{
|
||||
Container = "ts",
|
||||
VideoCodec = "h264",
|
||||
AudioCodec = "ac3",
|
||||
VideoCodec = "h264,mpeg2video",
|
||||
AudioCodec = "ac3,aac,mp3",
|
||||
Type = DlnaProfileType.Video
|
||||
},
|
||||
new DirectPlayProfile
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -41,9 +41,9 @@
|
|||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -34,9 +34,9 @@
|
|||
<DirectPlayProfile container="avi,mp4" type="Video" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -38,9 +38,9 @@
|
|||
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -40,8 +40,8 @@
|
|||
<DirectPlayProfile container="jpeg,jpg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mpeg" type="Video" videoCodec="mpeg2video" audioCodec="mp2" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -44,9 +44,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
|
|
|
@ -41,9 +41,9 @@
|
|||
<DirectPlayProfile container="" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -43,9 +43,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -38,9 +38,9 @@
|
|||
<DirectPlayProfile container="avi,mp4,mkv,ts" type="Video" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -44,9 +44,9 @@
|
|||
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -51,9 +51,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -39,9 +39,9 @@
|
|||
<DirectPlayProfile container="jpeg,gif,bmp,png" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -47,13 +47,13 @@
|
|||
<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="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" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -49,9 +49,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -48,9 +48,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="mpeg2video" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -46,9 +46,9 @@
|
|||
<DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -49,9 +49,9 @@
|
|||
<DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -51,9 +51,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -56,9 +56,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -56,9 +56,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -46,9 +46,9 @@
|
|||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="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" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -46,9 +46,9 @@
|
|||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" 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" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -41,9 +41,9 @@
|
|||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -52,9 +52,9 @@
|
|||
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Photo">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -46,9 +46,9 @@
|
|||
<DirectPlayProfile container="jpeg" type="Photo" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="asf" type="Video" videoCodec="wmv2" audioCodec="wmav2" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Bytes" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Video" container="mp4,mov">
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -37,7 +37,7 @@
|
|||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||
<XmlRootAttributes />
|
||||
<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="aac" videoCodec="h264" 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" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" videoCodec="jpeg" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles>
|
||||
<ContainerProfile type="Video" container="mp4,mov">
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
|
||||
<MaxIconWidth>48</MaxIconWidth>
|
||||
<MaxIconHeight>48</MaxIconHeight>
|
||||
<MaxStreamingBitrate>10000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>10000000</MaxStaticBitrate>
|
||||
<MaxStreamingBitrate>12000000</MaxStreamingBitrate>
|
||||
<MaxStaticBitrate>12000000</MaxStaticBitrate>
|
||||
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
|
||||
<MusicSyncBitrate>128000</MusicSyncBitrate>
|
||||
<XDlnaDoc>DMS-1.50</XDlnaDoc>
|
||||
|
@ -44,9 +44,9 @@
|
|||
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
|
||||
</DirectPlayProfiles>
|
||||
<TranscodingProfiles>
|
||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" 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" copyTimestamps="false" context="Streaming" />
|
||||
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles />
|
||||
|
|
|
@ -127,10 +127,14 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
args.EndPoint = endPoint;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,15 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
|
||||
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;
|
||||
string st;
|
||||
|
||||
|
@ -108,6 +115,59 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
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
|
||||
{
|
||||
get
|
||||
|
@ -126,7 +186,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
RestartSocketListener();
|
||||
ReloadAliveNotifier();
|
||||
|
||||
//CreateUnicastClient();
|
||||
CreateUnicastClient();
|
||||
|
||||
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
|
||||
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
||||
|
@ -146,6 +206,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
|
||||
values["HOST"] = "239.255.255.250:1900";
|
||||
values["USER-AGENT"] = "UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2";
|
||||
values["X-EMBY-SERVERID"] = _appHost.SystemId;
|
||||
|
||||
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)
|
||||
SendDatagram(msg, _ssdpEndp, localIp, true);
|
||||
|
||||
//SendUnicastRequest(msg);
|
||||
SendUnicastRequest(msg);
|
||||
}
|
||||
|
||||
public async void SendDatagram(string msg,
|
||||
|
@ -177,7 +238,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
{
|
||||
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);
|
||||
|
@ -242,8 +303,8 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
|
||||
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
|
||||
|
||||
SendDatagram(msg, endpoint, null, false, 1);
|
||||
SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 1);
|
||||
SendDatagram(msg, endpoint, null, false, 2);
|
||||
SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 2);
|
||||
//SendDatagram(header, values, endpoint, null, true);
|
||||
|
||||
if (enableDebugLogging)
|
||||
|
@ -324,20 +385,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
var args = SsdpHelper.ParseSsdpResponse(received);
|
||||
args.EndPoint = endpoint;
|
||||
|
||||
if (IsSelfNotification(args))
|
||||
{
|
||||
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);
|
||||
OnMessageReceived(args, true);
|
||||
}
|
||||
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()
|
||||
{
|
||||
_config.NamedConfigurationUpdated -= _config_ConfigurationUpdated;
|
||||
|
@ -448,7 +476,8 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
|
||||
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)
|
||||
|
@ -489,14 +518,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
_logger.ErrorException("Error creating unicast client", ex);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
UnicastSetBeginReceive();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error in UnicastSetBeginReceive", ex);
|
||||
}
|
||||
UnicastSetBeginReceive();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -522,11 +544,18 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
/// </summary>
|
||||
private void UnicastSetBeginReceive()
|
||||
{
|
||||
var ipRxEnd = new IPEndPoint(IPAddress.Any, _unicastPort);
|
||||
var udpListener = new UdpState { EndPoint = ipRxEnd };
|
||||
try
|
||||
{
|
||||
var ipRxEnd = new IPEndPoint(IPAddress.Any, _unicastPort);
|
||||
var udpListener = new UdpState { EndPoint = ipRxEnd };
|
||||
|
||||
udpListener.UdpClient = _unicastClient;
|
||||
_unicastClient.BeginReceive(UnicastReceiveCallback, udpListener);
|
||||
udpListener.UdpClient = _unicastClient;
|
||||
_unicastClient.BeginReceive(UnicastReceiveCallback, udpListener);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error in UnicastSetBeginReceive", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -540,37 +569,66 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||
var endpoint = ((UdpState)(ar.AsyncState)).EndPoint;
|
||||
if (udpClient.Client != null)
|
||||
{
|
||||
var responseBytes = udpClient.EndReceive(ar, ref endpoint);
|
||||
var args = SsdpHelper.ParseSsdpResponse(responseBytes);
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Debug("Sending unicast search request");
|
||||
|
||||
byte[] req = Encoding.ASCII.GetBytes(request);
|
||||
var ipSsdp = IPAddress.Parse(SSDPAddr);
|
||||
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"?>
|
||||
<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="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||
</packages>
|
|
@ -33,7 +33,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<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 Include="Patterns.Logging">
|
||||
<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"?>
|
||||
<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" />
|
||||
</packages>
|
|
@ -460,6 +460,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
{
|
||||
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 + "\"";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -794,6 +794,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
||||
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
|
||||
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="cancellationToken">The cancellation token.</param>
|
||||
/// <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;
|
||||
|
||||
|
@ -175,7 +175,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{MediaInfoResult}.</returns>
|
||||
/// <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,
|
||||
MediaProtocol protocol,
|
||||
bool extractChapters,
|
||||
|
@ -934,7 +934,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
_mediaEncoder._runningProcesses.Remove(this);
|
||||
}
|
||||
|
||||
process.Dispose();
|
||||
try
|
||||
{
|
||||
process.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private bool _disposed;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</Reference>
|
||||
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<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 Include="DvdLib">
|
||||
<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.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
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)
|
||||
{
|
||||
var info = new Model.MediaInfo.MediaInfo
|
||||
var info = new MediaInfo
|
||||
{
|
||||
Path = path,
|
||||
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);
|
||||
|
||||
// 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)
|
||||
if (tagStream != null && tagStream.tags != null)
|
||||
{
|
||||
var audioStream = data.streams.FirstOrDefault(i => string.Equals(i.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
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)
|
||||
foreach (var pair in tagStream.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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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))
|
||||
{
|
||||
info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
|
||||
|
@ -108,10 +171,223 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
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>
|
||||
/// Converts ffprobe stream info to our MediaStream class
|
||||
/// </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="formatInfo">The format info.</param>
|
||||
/// <returns>MediaStream.</returns>
|
||||
|
@ -176,7 +452,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
}
|
||||
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.Video;
|
||||
|
||||
|
@ -388,11 +664,11 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
return null;
|
||||
}
|
||||
|
||||
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.MediaInfo.MediaInfo data)
|
||||
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data)
|
||||
{
|
||||
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));
|
||||
|
||||
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");
|
||||
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");
|
||||
|
||||
var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists");
|
||||
|
@ -511,22 +799,12 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
// Disc number
|
||||
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 (audio.PremiereDate.HasValue && !audio.ProductionYear.HasValue)
|
||||
{
|
||||
audio.ProductionYear = audio.PremiereDate.Value.ToLocalTime().Year;
|
||||
}
|
||||
|
||||
FetchGenres(audio, tags);
|
||||
|
||||
// There's several values in tags may or may not be present
|
||||
FetchStudios(audio, tags, "organization");
|
||||
FetchStudios(audio, tags, "ensemble");
|
||||
|
@ -655,10 +933,10 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
/// <summary>
|
||||
/// Gets the studios from the tags collection
|
||||
/// </summary>
|
||||
/// <param name="audio">The audio.</param>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <param name="tags">The tags.</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);
|
||||
|
||||
|
@ -669,19 +947,19 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
foreach (var studio in studios)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
if (audio.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
|
||||
if (info.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
audio.Studios.Add(studio);
|
||||
info.Studios.Add(studio);
|
||||
}
|
||||
|
||||
audio.Studios = audio.Studios
|
||||
info.Studios = info.Studios
|
||||
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
@ -693,7 +971,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
/// </summary>
|
||||
/// <param name="info">The information.</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");
|
||||
|
||||
|
@ -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 void FetchWtvInfo(Model.MediaInfo.MediaInfo video, InternalMediaInfoResult data)
|
||||
private void FetchWtvInfo(MediaInfo video, InternalMediaInfoResult data)
|
||||
{
|
||||
if (data.format == null || data.format.tags == null)
|
||||
{
|
||||
|
@ -775,15 +1053,16 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(genres))
|
||||
{
|
||||
//genres = FFProbeHelpers.GetDictionaryValue(data.format.tags, "genre");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(genres))
|
||||
{
|
||||
video.Genres = genres.Split(new[] { ';', '/', ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
var genreList = genres.Split(new[] { ';', '/', ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||
.Select(i => i.Trim())
|
||||
.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");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||
</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>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<FodyPath>..\packages\Fody.1.19.1.0</FodyPath>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
|
@ -58,14 +57,6 @@
|
|||
<ItemGroup>
|
||||
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||
<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>
|
||||
<Compile Include="..\MediaBrowser.Model\Activity\ActivityLogEntry.cs">
|
||||
|
@ -1254,7 +1245,13 @@
|
|||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</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.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Fody" version="1.19.1.0" targetFramework="portable-win+net45+sl40+wp71" developmentDependency="true" />
|
||||
<package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="portable-net45+sl40+wp71+win" requireReinstallation="True" />
|
||||
<package id="Fody" version="1.29.2" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
|
||||
<package id="PropertyChanged.Fody" version="1.50.4" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
|
||||
</packages>
|
|
@ -182,8 +182,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
public PeopleMetadataOptions PeopleMetadataOptions { get; set; }
|
||||
public bool FindInternetTrailers { get; set; }
|
||||
|
||||
public string[] InsecureApps9 { get; set; }
|
||||
|
||||
public bool SaveMetadataHidden { get; set; }
|
||||
|
||||
public NameValuePair[] ContentTypes { get; set; }
|
||||
|
@ -206,6 +204,8 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public int MigrationVersion { get; set; }
|
||||
|
||||
public bool DownloadImagesInAdvance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||
/// </summary>
|
||||
|
@ -256,11 +256,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
PeopleMetadataOptions = new PeopleMetadataOptions();
|
||||
|
||||
InsecureApps9 = new[]
|
||||
{
|
||||
"Windows Phone"
|
||||
};
|
||||
|
||||
MetadataOptions = new[]
|
||||
{
|
||||
new MetadataOptions(1, 1280) {ItemType = "Book"},
|
||||
|
|
|
@ -48,11 +48,19 @@ namespace MediaBrowser.Model.Configuration
|
|||
public bool HidePlayedInLatest { get; set; }
|
||||
public bool DisplayChannelsInline { get; set; }
|
||||
|
||||
public bool RememberAudioSelections { get; set; }
|
||||
public bool RememberSubtitleSelections { get; set; }
|
||||
public bool EnableNextEpisodeAutoPlay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
||||
/// </summary>
|
||||
public UserConfiguration()
|
||||
{
|
||||
EnableNextEpisodeAutoPlay = true;
|
||||
RememberAudioSelections = true;
|
||||
RememberSubtitleSelections = true;
|
||||
|
||||
HidePlayedInLatest = true;
|
||||
PlayDefaultAudioTrack = true;
|
||||
|
||||
|
|
|
@ -425,6 +425,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',')[0];
|
||||
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
|
||||
playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps;
|
||||
playlistItem.SubProtocol = transcodingProfile.Protocol;
|
||||
playlistItem.AudioStreamIndex = audioStreamIndex;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
public string VideoProfile { get; set; }
|
||||
|
||||
public bool? Cabac { get; set; }
|
||||
public bool CopyTimestamps { get; set; }
|
||||
public string AudioCodec { 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("CopyTimestamps", (item.CopyTimestamps).ToString().ToLower()));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -269,7 +272,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
// HLS will preserve timestamps so we can just grab the full subtitle stream
|
||||
long startPositionTicks = StringHelper.EqualsIgnoreCase(SubProtocol, "hls")
|
||||
? 0
|
||||
: (this.PlayMethod == PlayMethod.Transcode ? StartPositionTicks : 0);
|
||||
: (PlayMethod == PlayMethod.Transcode && !CopyTimestamps ? StartPositionTicks : 0);
|
||||
|
||||
// First add the selected track
|
||||
if (SubtitleStreamIndex.HasValue)
|
||||
|
|
|
@ -29,6 +29,9 @@ namespace MediaBrowser.Model.Dlna
|
|||
[XmlAttribute("transcodeSeekInfo")]
|
||||
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
|
||||
|
||||
[XmlAttribute("copyTimestamps")]
|
||||
public bool CopyTimestamps { get; set; }
|
||||
|
||||
[XmlAttribute("context")]
|
||||
public EncodingContext Context { get; set; }
|
||||
|
||||
|
|
|
@ -34,5 +34,9 @@ namespace MediaBrowser.Model.Entities
|
|||
/// The conductor
|
||||
/// </summary>
|
||||
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
|
||||
{
|
||||
|
@ -13,5 +15,12 @@
|
|||
public int? EndingEpisodeNumber { 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>
|
||||
<PropertyChanged />
|
||||
</Weavers>
|
|
@ -15,7 +15,7 @@ namespace MediaBrowser.Model.LiveTv
|
|||
|
||||
public int PrePaddingSeconds { get; set; }
|
||||
public int PostPaddingSeconds { get; set; }
|
||||
|
||||
|
||||
public LiveTvOptions()
|
||||
{
|
||||
EnableMovieProviders = true;
|
||||
|
@ -32,6 +32,8 @@ namespace MediaBrowser.Model.LiveTv
|
|||
public bool ImportFavoritesOnly { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
public int DataVersion { get; set; }
|
||||
|
||||
public TunerHostInfo()
|
||||
{
|
||||
IsEnabled = true;
|
||||
|
@ -47,5 +49,15 @@ namespace MediaBrowser.Model.LiveTv
|
|||
public string ListingsId { get; set; }
|
||||
public string ZipCode { 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>
|
||||
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()
|
||||
{
|
||||
Clients = new List<string>();
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
<AssemblyName>MediaBrowser.Model</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<FodyPath>..\packages\Fody.1.19.1.0</FodyPath>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<ReleaseVersion>
|
||||
</ReleaseVersion>
|
||||
|
@ -442,30 +441,30 @@
|
|||
<Compile Include="Users\UserAction.cs" />
|
||||
<Compile Include="Users\UserActionType.cs" />
|
||||
<Compile Include="Users\UserPolicy.cs" />
|
||||
<None Include="Fody.targets" />
|
||||
<None Include="FodyWeavers.xml" />
|
||||
<None Include="MediaBrowser.Model.snk" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent />
|
||||
</PropertyGroup>
|
||||
<Import Project="Fody.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent />
|
||||
</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.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -9,11 +9,6 @@ namespace MediaBrowser.Model.MediaInfo
|
|||
{
|
||||
public List<ChapterInfo> Chapters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title.
|
||||
/// </summary>
|
||||
/// <value>The title.</value>
|
||||
public string Title { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the album.
|
||||
/// </summary>
|
||||
|
@ -47,10 +42,20 @@ namespace MediaBrowser.Model.MediaInfo
|
|||
/// <value>The official rating.</value>
|
||||
public string OfficialRating { get; set; }
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <value>The overview.</value>
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Fody" version="1.19.1.0" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="net45" />
|
||||
<package id="Fody" version="1.29.2" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="PropertyChanged.Fody" version="1.50.4" targetFramework="net45" developmentDependency="true" />
|
||||
</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