mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-31 14:33:54 -04:00
Merge remote-tracking branch 'upstream/master' into docker
This commit is contained in:
commit
e01f932f4b
@ -122,53 +122,12 @@ namespace MediaBrowser.Api
|
|||||||
return ToOptimizedResult(result);
|
return ToOptimizedResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string XbmcMetadata = "Xbmc Nfo";
|
|
||||||
const string MediaBrowserMetadata = "Media Browser Xml";
|
|
||||||
|
|
||||||
public void Post(AutoSetMetadataOptions request)
|
public void Post(AutoSetMetadataOptions request)
|
||||||
{
|
{
|
||||||
var service = AutoDetectMetadataService();
|
_configurationManager.DisableMetadataService("Media Browser Xml");
|
||||||
|
|
||||||
Logger.Info("Setting preferred metadata format to " + service);
|
|
||||||
|
|
||||||
var serviceToDisable = string.Equals(service, XbmcMetadata) ?
|
|
||||||
MediaBrowserMetadata :
|
|
||||||
XbmcMetadata;
|
|
||||||
|
|
||||||
_configurationManager.DisableMetadataService(serviceToDisable);
|
|
||||||
_configurationManager.SaveConfiguration();
|
_configurationManager.SaveConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string AutoDetectMetadataService()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var paths = _libraryManager.GetDefaultVirtualFolders()
|
|
||||||
.SelectMany(i => i.Locations)
|
|
||||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
||||||
.Select(i => new DirectoryInfo(i))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (paths.SelectMany(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories))
|
|
||||||
.Any())
|
|
||||||
{
|
|
||||||
return XbmcMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paths.SelectMany(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories))
|
|
||||||
.Any(i => string.Equals(i.Name, "series.xml", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "movie.xml", StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
return MediaBrowserMetadata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return XbmcMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Posts the specified configuraiton.
|
/// Posts the specified configuraiton.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -44,8 +44,8 @@ namespace MediaBrowser.Api.Devices
|
|||||||
[ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[ApiMember(Name = "FullPath", Description = "FullPath", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||||
public string FullPath { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
public Stream RequestStream { get; set; }
|
public Stream RequestStream { get; set; }
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ namespace MediaBrowser.Api.Devices
|
|||||||
{
|
{
|
||||||
var deviceId = Request.QueryString["DeviceId"];
|
var deviceId = Request.QueryString["DeviceId"];
|
||||||
var album = Request.QueryString["Album"];
|
var album = Request.QueryString["Album"];
|
||||||
var fullPath = Request.QueryString["FullPath"];
|
var id = Request.QueryString["Id"];
|
||||||
var name = Request.QueryString["Name"];
|
var name = Request.QueryString["Name"];
|
||||||
|
|
||||||
var task = _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo
|
var task = _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo
|
||||||
@ -140,7 +140,7 @@ namespace MediaBrowser.Api.Devices
|
|||||||
MimeType = Request.ContentType,
|
MimeType = Request.ContentType,
|
||||||
Album = album,
|
Album = album,
|
||||||
Name = name,
|
Name = name,
|
||||||
FullPath = fullPath
|
Id = id
|
||||||
});
|
});
|
||||||
|
|
||||||
Task.WaitAll(task);
|
Task.WaitAll(task);
|
||||||
|
@ -237,7 +237,7 @@ namespace MediaBrowser.Api
|
|||||||
|
|
||||||
if (musicVideo != null)
|
if (musicVideo != null)
|
||||||
{
|
{
|
||||||
musicVideo.Artist = request.Artists[0];
|
musicVideo.Artists = request.Artists.ToList();
|
||||||
musicVideo.Album = request.Album;
|
musicVideo.Album = request.Album;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Api.UserLibrary;
|
||||||
|
using MediaBrowser.Controller.Channels;
|
||||||
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
using MediaBrowser.Model.Channels;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Model.Querying;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.Movies
|
namespace MediaBrowser.Api.Movies
|
||||||
{
|
{
|
||||||
@ -16,6 +26,17 @@ namespace MediaBrowser.Api.Movies
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("/Trailers", "GET", Summary = "Finds movies and trailers similar to a given trailer.")]
|
||||||
|
public class Getrailers : BaseItemsRequest, IReturn<ItemsResult>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the user id.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The user id.</value>
|
||||||
|
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||||
|
public Guid? UserId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class TrailersService
|
/// Class TrailersService
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -38,6 +59,7 @@ namespace MediaBrowser.Api.Movies
|
|||||||
|
|
||||||
private readonly IItemRepository _itemRepo;
|
private readonly IItemRepository _itemRepo;
|
||||||
private readonly IDtoService _dtoService;
|
private readonly IDtoService _dtoService;
|
||||||
|
private readonly IChannelManager _channelManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TrailersService"/> class.
|
/// Initializes a new instance of the <see cref="TrailersService"/> class.
|
||||||
@ -45,13 +67,14 @@ namespace MediaBrowser.Api.Movies
|
|||||||
/// <param name="userManager">The user manager.</param>
|
/// <param name="userManager">The user manager.</param>
|
||||||
/// <param name="userDataRepository">The user data repository.</param>
|
/// <param name="userDataRepository">The user data repository.</param>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService)
|
public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService, IChannelManager channelManager)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_userDataRepository = userDataRepository;
|
_userDataRepository = userDataRepository;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_itemRepo = itemRepo;
|
_itemRepo = itemRepo;
|
||||||
_dtoService = dtoService;
|
_dtoService = dtoService;
|
||||||
|
_channelManager = channelManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -75,5 +98,71 @@ namespace MediaBrowser.Api.Movies
|
|||||||
|
|
||||||
return ToOptimizedSerializedResultUsingCache(result);
|
return ToOptimizedSerializedResultUsingCache(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<object> Get(Getrailers request)
|
||||||
|
{
|
||||||
|
var user = request.UserId.HasValue ? _userManager.GetUserById(request.UserId.Value) : null;
|
||||||
|
var result = await GetAllTrailers(user).ConfigureAwait(false);
|
||||||
|
|
||||||
|
IEnumerable<BaseItem> items = result.Items;
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
|
// Run them starting with the ones that are likely to reduce the list the most
|
||||||
|
foreach (var filter in request.GetFilters().OrderByDescending(f => (int)f))
|
||||||
|
{
|
||||||
|
items = ItemsService.ApplyFilter(items, filter, user, _userDataRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
items = _libraryManager.Sort(items, user, request.GetOrderBy(), request.SortOrder ?? SortOrder.Ascending);
|
||||||
|
|
||||||
|
var itemsArray = items.ToList();
|
||||||
|
|
||||||
|
var pagedItems = ApplyPaging(request, itemsArray);
|
||||||
|
|
||||||
|
var fields = request.GetItemFields().ToList();
|
||||||
|
|
||||||
|
var returnItems = pagedItems.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray();
|
||||||
|
|
||||||
|
return new ItemsResult
|
||||||
|
{
|
||||||
|
TotalRecordCount = itemsArray.Count,
|
||||||
|
Items = returnItems
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<BaseItem> ApplyPaging(Getrailers request, IEnumerable<BaseItem> items)
|
||||||
|
{
|
||||||
|
// Start at
|
||||||
|
if (request.StartIndex.HasValue)
|
||||||
|
{
|
||||||
|
items = items.Skip(request.StartIndex.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return limit
|
||||||
|
if (request.Limit.HasValue)
|
||||||
|
{
|
||||||
|
items = items.Take(request.Limit.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<QueryResult<BaseItem>> GetAllTrailers(User user)
|
||||||
|
{
|
||||||
|
var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery
|
||||||
|
{
|
||||||
|
ContentTypes = new[] { ChannelMediaContentType.MovieExtra },
|
||||||
|
ExtraTypes = new[] { ExtraType.Trailer },
|
||||||
|
UserId = user.Id.ToString("N")
|
||||||
|
|
||||||
|
}, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
|
return new QueryResult<BaseItem>
|
||||||
|
{
|
||||||
|
Items = trailerResult.Items,
|
||||||
|
TotalRecordCount = trailerResult.TotalRecordCount
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -714,8 +714,10 @@ namespace MediaBrowser.Api.Playback
|
|||||||
/// <returns><c>true</c> if the specified stream is H264; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the specified stream is H264; otherwise, <c>false</c>.</returns>
|
||||||
protected bool IsH264(MediaStream stream)
|
protected bool IsH264(MediaStream stream)
|
||||||
{
|
{
|
||||||
return stream.Codec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 ||
|
var codec = stream.Codec ?? string.Empty;
|
||||||
stream.Codec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1;
|
|
||||||
|
return codec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||||
|
codec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1976,6 +1978,7 @@ namespace MediaBrowser.Api.Playback
|
|||||||
state.TargetPacketLength,
|
state.TargetPacketLength,
|
||||||
state.TargetTimestamp,
|
state.TargetTimestamp,
|
||||||
state.IsTargetAnamorphic,
|
state.IsTargetAnamorphic,
|
||||||
|
state.IsTargetCabac,
|
||||||
state.TargetRefFrames);
|
state.TargetRefFrames);
|
||||||
|
|
||||||
if (mediaProfile != null)
|
if (mediaProfile != null)
|
||||||
@ -2065,6 +2068,7 @@ namespace MediaBrowser.Api.Playback
|
|||||||
state.TargetPacketLength,
|
state.TargetPacketLength,
|
||||||
state.TranscodeSeekInfo,
|
state.TranscodeSeekInfo,
|
||||||
state.IsTargetAnamorphic,
|
state.IsTargetAnamorphic,
|
||||||
|
state.IsTargetCabac,
|
||||||
state.TargetRefFrames
|
state.TargetRefFrames
|
||||||
|
|
||||||
).FirstOrDefault() ?? string.Empty;
|
).FirstOrDefault() ?? string.Empty;
|
||||||
|
@ -367,16 +367,6 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||||||
{
|
{
|
||||||
var state = await GetState(request, CancellationToken.None).ConfigureAwait(false);
|
var state = await GetState(request, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
if (string.Equals(request.AudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Audio codec copy is not allowed here.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(request.VideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Video codec copy is not allowed here.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(request.MediaSourceId))
|
if (string.IsNullOrEmpty(request.MediaSourceId))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("MediaSourceId is required");
|
throw new ArgumentException("MediaSourceId is required");
|
||||||
@ -511,7 +501,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||||||
|
|
||||||
private void AppendPlaylist(StringBuilder builder, string url, int bitrate, string subtitleGroup)
|
private void AppendPlaylist(StringBuilder builder, string url, int bitrate, string subtitleGroup)
|
||||||
{
|
{
|
||||||
var header = "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + bitrate.ToString(UsCulture);
|
var header = "#EXT-X-STREAM-INF:BANDWIDTH=" + bitrate.ToString(UsCulture);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(subtitleGroup))
|
if (!string.IsNullOrWhiteSpace(subtitleGroup))
|
||||||
{
|
{
|
||||||
@ -638,7 +628,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||||||
// See if we can save come cpu cycles by avoiding encoding
|
// See if we can save come cpu cycles by avoiding encoding
|
||||||
if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
|
return state.VideoStream != null && IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
|
||||||
}
|
}
|
||||||
|
|
||||||
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
|
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
|
||||||
|
@ -139,7 +139,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||||||
// See if we can save come cpu cycles by avoiding encoding
|
// See if we can save come cpu cycles by avoiding encoding
|
||||||
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
|
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
|
return state.VideoStream != null && IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
|
||||||
}
|
}
|
||||||
|
|
||||||
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
|
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Threading;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Common.IO;
|
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using ServiceStack.Web;
|
using ServiceStack.Web;
|
||||||
using System;
|
using System;
|
||||||
@ -49,9 +48,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||||||
/// <param name="responseStream">The response stream.</param>
|
/// <param name="responseStream">The response stream.</param>
|
||||||
public void WriteTo(Stream responseStream)
|
public void WriteTo(Stream responseStream)
|
||||||
{
|
{
|
||||||
var task = WriteToAsync(responseStream);
|
WriteToInternal(responseStream);
|
||||||
|
|
||||||
Task.WaitAll(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -59,12 +56,12 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="responseStream">The response stream.</param>
|
/// <param name="responseStream">The response stream.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task WriteToAsync(Stream responseStream)
|
private void WriteToInternal(Stream responseStream)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await new ProgressiveFileCopier(_fileSystem, _job)
|
new ProgressiveFileCopier(_fileSystem, _job)
|
||||||
.StreamFile(Path, responseStream).ConfigureAwait(false);
|
.StreamFile(Path, responseStream);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -95,16 +92,16 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||||||
_job = job;
|
_job = job;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StreamFile(string path, Stream outputStream)
|
public void StreamFile(string path, Stream outputStream)
|
||||||
{
|
{
|
||||||
var eofCount = 0;
|
var eofCount = 0;
|
||||||
long position = 0;
|
long position = 0;
|
||||||
|
|
||||||
using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
|
using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, false))
|
||||||
{
|
{
|
||||||
while (eofCount < 15)
|
while (eofCount < 15)
|
||||||
{
|
{
|
||||||
await CopyToAsyncInternal(fs, outputStream, 81920, CancellationToken.None).ConfigureAwait(false);
|
CopyToInternal(fs, outputStream, 81920);
|
||||||
|
|
||||||
var fsPosition = fs.Position;
|
var fsPosition = fs.Position;
|
||||||
|
|
||||||
@ -118,7 +115,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||||||
{
|
{
|
||||||
eofCount++;
|
eofCount++;
|
||||||
}
|
}
|
||||||
await Task.Delay(100).ConfigureAwait(false);
|
var task = Task.Delay(100);
|
||||||
|
Task.WaitAll(task);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -130,13 +128,13 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CopyToAsyncInternal(Stream source, Stream destination, int bufferSize, CancellationToken cancellationToken)
|
private void CopyToInternal(Stream source, Stream destination, int bufferSize)
|
||||||
{
|
{
|
||||||
byte[] array = new byte[bufferSize];
|
byte[] array = new byte[bufferSize];
|
||||||
int count;
|
int count;
|
||||||
while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
|
while ((count = source.Read(array, 0, array.Length)) != 0)
|
||||||
{
|
{
|
||||||
await destination.WriteAsync(array, 0, count, cancellationToken).ConfigureAwait(false);
|
destination.Write(array, 0, count);
|
||||||
|
|
||||||
_bytesWritten += count;
|
_bytesWritten += count;
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
using ServiceStack.Web;
|
using ServiceStack.Web;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api.Playback
|
namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
@ -41,22 +40,7 @@ namespace MediaBrowser.Api.Playback
|
|||||||
/// <param name="responseStream">The response stream.</param>
|
/// <param name="responseStream">The response stream.</param>
|
||||||
public void WriteTo(Stream responseStream)
|
public void WriteTo(Stream responseStream)
|
||||||
{
|
{
|
||||||
var task = WriteToAsync(responseStream);
|
_response.Content.CopyTo(responseStream, 819200);
|
||||||
|
|
||||||
Task.WaitAll(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes to async.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="responseStream">The response stream.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
public async Task WriteToAsync(Stream responseStream)
|
|
||||||
{
|
|
||||||
using (_response)
|
|
||||||
{
|
|
||||||
await _response.Content.CopyToAsync(responseStream, 819200).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,12 @@ namespace MediaBrowser.Api.Playback
|
|||||||
|
|
||||||
public bool ReadInputAtNativeFramerate
|
public bool ReadInputAtNativeFramerate
|
||||||
{
|
{
|
||||||
get { return InputProtocol == MediaProtocol.Rtmp || string.Equals(InputContainer, "wtv", StringComparison.OrdinalIgnoreCase); }
|
get {
|
||||||
|
|
||||||
|
return InputProtocol == MediaProtocol.Rtmp ||
|
||||||
|
string.Equals(InputContainer, "wtv", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
!string.IsNullOrEmpty(LiveTvStreamId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportStreamTimestamp InputTimestamp { get; set; }
|
public TransportStreamTimestamp InputTimestamp { get; set; }
|
||||||
@ -413,5 +418,18 @@ namespace MediaBrowser.Api.Playback
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool? IsTargetCabac
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Request.Static)
|
||||||
|
{
|
||||||
|
return VideoStream == null ? null : VideoStream.IsCabac;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using MediaBrowser.Controller.Collections;
|
using System.Threading;
|
||||||
|
using MediaBrowser.Controller.Collections;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
@ -8,6 +9,7 @@ using MediaBrowser.Controller.Library;
|
|||||||
using MediaBrowser.Controller.Localization;
|
using MediaBrowser.Controller.Localization;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
|
using MediaBrowser.Model.Channels;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
|
@ -296,6 +296,16 @@ namespace MediaBrowser.Common.Implementations
|
|||||||
logger.Info("64-Bit Process: {0}", Environment.Is64BitProcess);
|
logger.Info("64-Bit Process: {0}", Environment.Is64BitProcess);
|
||||||
logger.Info("Program data path: {0}", appPaths.ProgramDataPath);
|
logger.Info("Program data path: {0}", appPaths.ProgramDataPath);
|
||||||
|
|
||||||
|
Type type = Type.GetType("Mono.Runtime");
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
MethodInfo displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
|
if (displayName != null)
|
||||||
|
{
|
||||||
|
logger.Info("Mono: " + displayName.Invoke(null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.Info("Application Path: {0}", appPaths.ApplicationPath);
|
logger.Info("Application Path: {0}", appPaths.ApplicationPath);
|
||||||
|
|
||||||
logger.Info("*** When reporting issues please include the entire log file. ***".ToUpper());
|
logger.Info("*** When reporting issues please include the entire log file. ***".ToUpper());
|
||||||
|
@ -123,7 +123,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
request.Method = method;
|
request.Method = method;
|
||||||
request.Timeout = 20000;
|
request.Timeout = options.TimeoutMs;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(options.Host))
|
if (!string.IsNullOrEmpty(options.Host))
|
||||||
{
|
{
|
||||||
@ -390,7 +390,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||||||
|
|
||||||
if (!options.BufferContent)
|
if (!options.BufferContent)
|
||||||
{
|
{
|
||||||
var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false);
|
var response = await GetResponseAsync(httpWebRequest, TimeSpan.FromMilliseconds(options.TimeoutMs)).ConfigureAwait(false);
|
||||||
|
|
||||||
var httpResponse = (HttpWebResponse)response;
|
var httpResponse = (HttpWebResponse)response;
|
||||||
|
|
||||||
@ -401,7 +401,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||||||
return GetResponseInfo(httpResponse, httpResponse.GetResponseStream(), GetContentLength(httpResponse), httpResponse);
|
return GetResponseInfo(httpResponse, httpResponse.GetResponseStream(), GetContentLength(httpResponse), httpResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
|
using (var response = await GetResponseAsync(httpWebRequest, TimeSpan.FromMilliseconds(options.TimeoutMs)).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var httpResponse = (HttpWebResponse)response;
|
var httpResponse = (HttpWebResponse)response;
|
||||||
|
|
||||||
@ -434,21 +434,9 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||||||
|
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
|
||||||
|
|
||||||
throw new HttpException(ex.Message, ex);
|
|
||||||
}
|
|
||||||
catch (WebException ex)
|
|
||||||
{
|
|
||||||
throw GetException(ex, options);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
throw GetException(ex, options);
|
||||||
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -636,21 +624,10 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||||||
return GetResponseInfo(httpResponse, tempFile, contentLength);
|
return GetResponseInfo(httpResponse, tempFile, contentLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException ex)
|
|
||||||
{
|
|
||||||
throw GetTempFileException(ex, options, tempFile);
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
throw GetTempFileException(ex, options, tempFile);
|
|
||||||
}
|
|
||||||
catch (WebException ex)
|
|
||||||
{
|
|
||||||
throw GetTempFileException(ex, options, tempFile);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw GetTempFileException(ex, options, tempFile);
|
DeleteTempFile(tempFile);
|
||||||
|
throw GetException(ex, options);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -675,45 +652,26 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||||||
|
|
||||||
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
/// <summary>
|
private Exception GetException(Exception ex, HttpRequestOptions options)
|
||||||
/// Handles the temp file exception.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ex">The ex.</param>
|
|
||||||
/// <param name="options">The options.</param>
|
|
||||||
/// <param name="tempFile">The temp file.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
/// <exception cref="HttpException"></exception>
|
|
||||||
private Exception GetTempFileException(Exception ex, HttpRequestOptions options, string tempFile)
|
|
||||||
{
|
{
|
||||||
var operationCanceledException = ex as OperationCanceledException;
|
var webException = ex as WebException
|
||||||
|
?? ex.InnerException as WebException;
|
||||||
|
|
||||||
|
if (webException != null)
|
||||||
|
{
|
||||||
|
return GetException(webException, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
var operationCanceledException = ex as OperationCanceledException
|
||||||
|
?? ex.InnerException as OperationCanceledException;
|
||||||
|
|
||||||
if (operationCanceledException != null)
|
if (operationCanceledException != null)
|
||||||
{
|
{
|
||||||
// Cleanup
|
|
||||||
DeleteTempFile(tempFile);
|
|
||||||
|
|
||||||
return GetCancellationException(options.Url, options.CancellationToken, operationCanceledException);
|
return GetCancellationException(options.Url, options.CancellationToken, operationCanceledException);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
DeleteTempFile(tempFile);
|
|
||||||
|
|
||||||
var httpRequestException = ex as HttpRequestException;
|
|
||||||
|
|
||||||
if (httpRequestException != null)
|
|
||||||
{
|
|
||||||
return new HttpException(ex.Message, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
var webException = ex as WebException;
|
|
||||||
|
|
||||||
if (webException != null)
|
|
||||||
{
|
|
||||||
throw GetException(webException, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,5 +801,47 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||||||
{
|
{
|
||||||
return Post(url, postData, null, cancellationToken);
|
return Post(url, postData, null, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout)
|
||||||
|
{
|
||||||
|
var taskCompletion = new TaskCompletionSource<WebResponse>();
|
||||||
|
|
||||||
|
Task<WebResponse> asyncTask = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
|
||||||
|
|
||||||
|
ThreadPool.RegisterWaitForSingleObject((asyncTask as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, timeout, true);
|
||||||
|
asyncTask.ContinueWith(task =>
|
||||||
|
{
|
||||||
|
taskCompletion.TrySetResult(task.Result);
|
||||||
|
|
||||||
|
}, TaskContinuationOptions.NotOnFaulted);
|
||||||
|
|
||||||
|
// Handle errors
|
||||||
|
asyncTask.ContinueWith(task =>
|
||||||
|
{
|
||||||
|
if (task.Exception != null)
|
||||||
|
{
|
||||||
|
taskCompletion.TrySetException(task.Exception);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
taskCompletion.TrySetException(new List<Exception>());
|
||||||
|
}
|
||||||
|
|
||||||
|
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||||
|
|
||||||
|
return taskCompletion.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void TimeoutCallback(object state, bool timedOut)
|
||||||
|
{
|
||||||
|
if (timedOut)
|
||||||
|
{
|
||||||
|
WebRequest request = (WebRequest)state;
|
||||||
|
if (state != null)
|
||||||
|
{
|
||||||
|
request.Abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,8 @@ namespace MediaBrowser.Common.Net
|
|||||||
public CacheMode CacheMode { get; set; }
|
public CacheMode CacheMode { get; set; }
|
||||||
public TimeSpan CacheLength { get; set; }
|
public TimeSpan CacheLength { get; set; }
|
||||||
|
|
||||||
|
public int TimeoutMs { get; set; }
|
||||||
|
|
||||||
private string GetHeaderValue(string name)
|
private string GetHeaderValue(string name)
|
||||||
{
|
{
|
||||||
string value;
|
string value;
|
||||||
@ -115,6 +117,8 @@ namespace MediaBrowser.Common.Net
|
|||||||
|
|
||||||
LogRequest = true;
|
LogRequest = true;
|
||||||
CacheMode = CacheMode.None;
|
CacheMode = CacheMode.None;
|
||||||
|
|
||||||
|
TimeoutMs = 20000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPostData(IDictionary<string,string> values)
|
public void SetPostData(IDictionary<string,string> values)
|
||||||
|
@ -4,5 +4,7 @@ namespace MediaBrowser.Controller.Connect
|
|||||||
public class UserLinkResult
|
public class UserLinkResult
|
||||||
{
|
{
|
||||||
public bool IsPending { get; set; }
|
public bool IsPending { get; set; }
|
||||||
|
public bool IsNewUserInvitation { get; set; }
|
||||||
|
public string GuestDisplayName { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Dto
|
namespace MediaBrowser.Controller.Dto
|
||||||
@ -12,14 +10,6 @@ namespace MediaBrowser.Controller.Dto
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDtoService
|
public interface IDtoService
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets the user dto.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The user.</param>
|
|
||||||
/// <returns>UserDto.</returns>
|
|
||||||
[Obsolete]
|
|
||||||
UserDto GetUserDto(User user);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the dto id.
|
/// Gets the dto id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -226,7 +226,9 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||||||
|
|
||||||
public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
|
public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
|
||||||
{
|
{
|
||||||
return inputItems.OfType<IHasArtist>().Where(i => i.HasArtist(Name)).Cast<BaseItem>();
|
return inputItems.OfType<IHasArtist>()
|
||||||
|
.Where(i => i.HasArtist(Name))
|
||||||
|
.Cast<BaseItem>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,6 +429,12 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public virtual BaseItem DisplayParent
|
||||||
|
{
|
||||||
|
get { return Parent; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When the item first debuted. For movies this could be premiere date, episodes would be first aired
|
/// When the item first debuted. For movies this could be premiere date, episodes would be first aired
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -548,7 +554,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return CustomRating;
|
return CustomRating;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parent = Parent;
|
var parent = DisplayParent;
|
||||||
if (parent != null)
|
if (parent != null)
|
||||||
{
|
{
|
||||||
return parent.CustomRatingForComparison;
|
return parent.CustomRatingForComparison;
|
||||||
|
@ -74,7 +74,8 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
{
|
{
|
||||||
FileInfo = new DirectoryInfo(path),
|
FileInfo = new DirectoryInfo(path),
|
||||||
Path = path,
|
Path = path,
|
||||||
Parent = Parent
|
Parent = Parent,
|
||||||
|
CollectionType = CollectionType
|
||||||
};
|
};
|
||||||
|
|
||||||
// Gather child folder and files
|
// Gather child folder and files
|
||||||
|
@ -736,7 +736,9 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||||
protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return LibraryManager.ResolvePaths<BaseItem>(GetFileSystemChildren(directoryService), directoryService, this);
|
var collectionType = LibraryManager.FindCollectionType(this);
|
||||||
|
|
||||||
|
return LibraryManager.ResolvePaths<BaseItem>(GetFileSystemChildren(directoryService), directoryService, this, collectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -745,7 +747,16 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||||
protected IEnumerable<BaseItem> GetCachedChildren()
|
protected IEnumerable<BaseItem> GetCachedChildren()
|
||||||
{
|
{
|
||||||
return ItemRepository.GetChildren(Id).Select(RetrieveChild).Where(i => i != null);
|
var childrenItems = ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
|
||||||
|
|
||||||
|
//var children = ItemRepository.GetChildren(Id).Select(RetrieveChild).Where(i => i != null).ToList();
|
||||||
|
|
||||||
|
//if (children.Count != childrenItems.Count)
|
||||||
|
//{
|
||||||
|
// var b = this;
|
||||||
|
//}
|
||||||
|
|
||||||
|
return childrenItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -770,6 +781,29 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BaseItem RetrieveChild(BaseItem child)
|
||||||
|
{
|
||||||
|
var item = LibraryManager.GetMemoryItemById(child.Id);
|
||||||
|
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
if (item is IByReferenceItem)
|
||||||
|
{
|
||||||
|
return LibraryManager.GetOrAddByReferenceItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Parent = this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child.Parent = this;
|
||||||
|
LibraryManager.RegisterItem(child);
|
||||||
|
item = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
|
public virtual Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
var user = query.User;
|
var user = query.User;
|
||||||
|
@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
{
|
{
|
||||||
public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasProductionLocations, IHasBudget, IHasLookupInfo<MusicVideoInfo>
|
public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasProductionLocations, IHasBudget, IHasLookupInfo<MusicVideoInfo>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the artist.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The artist.</value>
|
|
||||||
public string Artist { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the album.
|
/// Gets or sets the album.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -35,27 +29,12 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// <value>The revenue.</value>
|
/// <value>The revenue.</value>
|
||||||
public double? Revenue { get; set; }
|
public double? Revenue { get; set; }
|
||||||
public List<string> ProductionLocations { get; set; }
|
public List<string> ProductionLocations { get; set; }
|
||||||
|
public List<string> Artists { get; set; }
|
||||||
|
|
||||||
public MusicVideo()
|
public MusicVideo()
|
||||||
{
|
{
|
||||||
ProductionLocations = new List<string>();
|
ProductionLocations = new List<string>();
|
||||||
}
|
Artists = new List<string>();
|
||||||
|
|
||||||
[IgnoreDataMember]
|
|
||||||
public List<string> Artists
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var list = new List<string>();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Artist))
|
|
||||||
{
|
|
||||||
list.Add(Artist);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
@ -63,15 +42,22 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var list = new List<string>();
|
return Artists;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Artist))
|
/// <summary>
|
||||||
|
/// TODO: Remove
|
||||||
|
/// </summary>
|
||||||
|
public string Artist
|
||||||
|
{
|
||||||
|
get { return Artists.FirstOrDefault(); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(value) && !Artists.Contains(value, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
list.Add(Artist);
|
Artists.Add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +68,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// <returns><c>true</c> if the specified name has artist; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the specified name has artist; otherwise, <c>false</c>.</returns>
|
||||||
public bool HasArtist(string name)
|
public bool HasArtist(string name)
|
||||||
{
|
{
|
||||||
return string.Equals(Artist, name, StringComparison.OrdinalIgnoreCase);
|
return AllArtists.Contains(name, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -104,6 +104,15 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public override BaseItem DisplayParent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Season ?? Parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the user data key.
|
/// Gets the user data key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -153,7 +162,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
// Episodes directly in series folder
|
// Episodes directly in series folder
|
||||||
if (season == null)
|
if (season == null)
|
||||||
{
|
{
|
||||||
var series = FindParent<Series>();
|
var series = Series;
|
||||||
|
|
||||||
if (ParentIndexNumber.HasValue)
|
if (ParentIndexNumber.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,12 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public override BaseItem DisplayParent
|
||||||
|
{
|
||||||
|
get { return Series ?? Parent; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// We want to group into our Series
|
/// We want to group into our Series
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -17,30 +17,14 @@ namespace MediaBrowser.Controller.Library
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ILibraryManager
|
public interface ILibraryManager
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Resolves the item.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">The args.</param>
|
|
||||||
/// <returns>BaseItem.</returns>
|
|
||||||
BaseItem ResolveItem(ItemResolveArgs args);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resolves a path into a BaseItem
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileInfo">The file info.</param>
|
|
||||||
/// <param name="directoryService">The directory service.</param>
|
|
||||||
/// <param name="parent">The parent.</param>
|
|
||||||
/// <returns>BaseItem.</returns>
|
|
||||||
/// <exception cref="System.ArgumentNullException"></exception>
|
|
||||||
BaseItem ResolvePath(FileSystemInfo fileInfo, IDirectoryService directoryService, Folder parent = null);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves the path.
|
/// Resolves the path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileInfo">The file information.</param>
|
/// <param name="fileInfo">The file information.</param>
|
||||||
/// <param name="parent">The parent.</param>
|
/// <param name="parent">The parent.</param>
|
||||||
|
/// <param name="collectionType">Type of the collection.</param>
|
||||||
/// <returns>BaseItem.</returns>
|
/// <returns>BaseItem.</returns>
|
||||||
BaseItem ResolvePath(FileSystemInfo fileInfo, Folder parent = null);
|
BaseItem ResolvePath(FileSystemInfo fileInfo, Folder parent = null, string collectionType = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves a set of files into a list of BaseItem
|
/// Resolves a set of files into a list of BaseItem
|
||||||
@ -49,8 +33,9 @@ namespace MediaBrowser.Controller.Library
|
|||||||
/// <param name="files">The files.</param>
|
/// <param name="files">The files.</param>
|
||||||
/// <param name="directoryService">The directory service.</param>
|
/// <param name="directoryService">The directory service.</param>
|
||||||
/// <param name="parent">The parent.</param>
|
/// <param name="parent">The parent.</param>
|
||||||
|
/// <param name="collectionType">Type of the collection.</param>
|
||||||
/// <returns>List{``0}.</returns>
|
/// <returns>List{``0}.</returns>
|
||||||
List<T> ResolvePaths<T>(IEnumerable<FileSystemInfo> files, IDirectoryService directoryService, Folder parent)
|
List<T> ResolvePaths<T>(IEnumerable<FileSystemInfo> files, IDirectoryService directoryService, Folder parent, string collectionType = null)
|
||||||
where T : BaseItem;
|
where T : BaseItem;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -151,6 +136,13 @@ namespace MediaBrowser.Controller.Library
|
|||||||
/// <returns>BaseItem.</returns>
|
/// <returns>BaseItem.</returns>
|
||||||
BaseItem GetItemById(Guid id);
|
BaseItem GetItemById(Guid id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the memory item by identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The identifier.</param>
|
||||||
|
/// <returns>BaseItem.</returns>
|
||||||
|
BaseItem GetMemoryItemById(Guid id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the intros.
|
/// Gets the intros.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Providers;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Library
|
namespace MediaBrowser.Controller.Library
|
||||||
|
@ -229,22 +229,6 @@ namespace MediaBrowser.Controller.Library
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name of the meta file by.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The name.</param>
|
|
||||||
/// <returns>FileSystemInfo.</returns>
|
|
||||||
/// <exception cref="System.ArgumentNullException"></exception>
|
|
||||||
public FileSystemInfo GetMetaFileByName(string name)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(name))
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetFileSystemEntryByName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether [contains meta file by name] [the specified name].
|
/// Determines whether [contains meta file by name] [the specified name].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -252,7 +236,12 @@ namespace MediaBrowser.Controller.Library
|
|||||||
/// <returns><c>true</c> if [contains meta file by name] [the specified name]; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if [contains meta file by name] [the specified name]; otherwise, <c>false</c>.</returns>
|
||||||
public bool ContainsMetaFileByName(string name)
|
public bool ContainsMetaFileByName(string name)
|
||||||
{
|
{
|
||||||
return GetMetaFileByName(name) != null;
|
if (string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetFileSystemEntryByName(name) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -265,20 +254,13 @@ namespace MediaBrowser.Controller.Library
|
|||||||
return GetFileSystemEntryByName(name) != null;
|
return GetFileSystemEntryByName(name) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _collectionTypeDiscovered;
|
|
||||||
private string _collectionType;
|
|
||||||
|
|
||||||
public string GetCollectionType()
|
public string GetCollectionType()
|
||||||
{
|
{
|
||||||
if (!_collectionTypeDiscovered)
|
return CollectionType;
|
||||||
{
|
|
||||||
_collectionType = Parent == null ? null : _libraryManager.FindCollectionType(Parent);
|
|
||||||
_collectionTypeDiscovered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _collectionType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string CollectionType { get; set; }
|
||||||
|
|
||||||
#region Equality Overrides
|
#region Equality Overrides
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -284,7 +284,7 @@ namespace MediaBrowser.Controller.Library
|
|||||||
{
|
{
|
||||||
if (IsSeasonFolder(child.FullName, directoryService, fileSystem))
|
if (IsSeasonFolder(child.FullName, directoryService, fileSystem))
|
||||||
{
|
{
|
||||||
logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
|
//logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task DeleteItem(Guid id, CancellationToken cancellationToken);
|
Task DeleteItem(Guid id, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the critic reviews.
|
/// Gets the critic reviews.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -41,6 +41,13 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// <returns>Task{IEnumerable{ItemReview}}.</returns>
|
/// <returns>Task{IEnumerable{ItemReview}}.</returns>
|
||||||
IEnumerable<ItemReview> GetCriticReviews(Guid itemId);
|
IEnumerable<ItemReview> GetCriticReviews(Guid itemId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the children items.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parentId">The parent identifier.</param>
|
||||||
|
/// <returns>IEnumerable<BaseItem>.</returns>
|
||||||
|
IEnumerable<BaseItem> GetChildrenItems(Guid parentId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the critic reviews.
|
/// Saves the critic reviews.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -101,7 +108,7 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// <param name="type">The type.</param>
|
/// <param name="type">The type.</param>
|
||||||
/// <returns>IEnumerable{Guid}.</returns>
|
/// <returns>IEnumerable{Guid}.</returns>
|
||||||
IEnumerable<BaseItem> GetItemsOfType(Type type);
|
IEnumerable<BaseItem> GetItemsOfType(Type type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the children.
|
/// Saves the children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -14,10 +14,6 @@ namespace MediaBrowser.Controller.Providers
|
|||||||
|
|
||||||
public MetadataRefreshMode MetadataRefreshMode { get; set; }
|
public MetadataRefreshMode MetadataRefreshMode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// TODO: deprecate. Keeping this for now, for api compatibility
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete]
|
|
||||||
public bool ForceSave { get; set; }
|
public bool ForceSave { get; set; }
|
||||||
|
|
||||||
public MetadataRefreshOptions()
|
public MetadataRefreshOptions()
|
||||||
|
@ -246,7 +246,7 @@ namespace MediaBrowser.Controller.Resolvers
|
|||||||
|
|
||||||
if (config.UseFileCreationTimeForDateAdded)
|
if (config.UseFileCreationTimeForDateAdded)
|
||||||
{
|
{
|
||||||
item.DateModified = fileSystem.GetCreationTimeUtc(info);
|
item.DateCreated = fileSystem.GetCreationTimeUtc(info);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -80,6 +80,12 @@ namespace MediaBrowser.Controller.Session
|
|||||||
/// <value>The last activity date.</value>
|
/// <value>The last activity date.</value>
|
||||||
public DateTime LastActivityDate { get; set; }
|
public DateTime LastActivityDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the last playback check in.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The last playback check in.</value>
|
||||||
|
public DateTime LastPlaybackCheckIn { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name of the device.
|
/// Gets or sets the name of the device.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
using MediaBrowser.Common.Extensions;
|
using System.Linq;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Localization;
|
using MediaBrowser.Controller.Localization;
|
||||||
using MediaBrowser.Dlna.Didl;
|
using MediaBrowser.Dlna.Didl;
|
||||||
@ -85,7 +87,9 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
{
|
{
|
||||||
var id = sparams["ObjectID"];
|
var id = sparams["ObjectID"];
|
||||||
|
|
||||||
var item = GetItemFromObjectId(id, user);
|
var serverItem = GetItemFromObjectId(id, user);
|
||||||
|
|
||||||
|
var item = serverItem.Item;
|
||||||
|
|
||||||
var newbookmark = int.Parse(sparams["PosSecond"], _usCulture);
|
var newbookmark = int.Parse(sparams["PosSecond"], _usCulture);
|
||||||
|
|
||||||
@ -173,49 +177,48 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
//didl.SetAttribute("xmlns:sec", NS_SEC);
|
//didl.SetAttribute("xmlns:sec", NS_SEC);
|
||||||
result.AppendChild(didl);
|
result.AppendChild(didl);
|
||||||
|
|
||||||
var item = GetItemFromObjectId(id, user);
|
var serverItem = GetItemFromObjectId(id, user);
|
||||||
|
var item = serverItem.Item;
|
||||||
|
|
||||||
var totalCount = 0;
|
var totalCount = 0;
|
||||||
|
|
||||||
if (string.Equals(flag, "BrowseMetadata"))
|
if (string.Equals(flag, "BrowseMetadata"))
|
||||||
{
|
{
|
||||||
var folder = item as Folder;
|
if (item.IsFolder || serverItem.StubType.HasValue)
|
||||||
|
|
||||||
if (folder == null)
|
|
||||||
{
|
{
|
||||||
result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, item, null, deviceId, filter));
|
var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requested).ConfigureAwait(false));
|
||||||
|
totalCount = childrenResult.TotalRecordCount;
|
||||||
|
|
||||||
|
result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, item, serverItem.StubType, null, totalCount, filter, id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var childrenResult = (await GetUserItems(folder, user, sortCriteria, start, requested).ConfigureAwait(false));
|
result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, item, null, null, deviceId, filter));
|
||||||
totalCount = childrenResult.TotalRecordCount;
|
|
||||||
|
|
||||||
result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, folder, totalCount, filter, id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
provided++;
|
provided++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var folder = (Folder)item;
|
var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requested).ConfigureAwait(false));
|
||||||
|
|
||||||
var childrenResult = (await GetUserItems(folder, user, sortCriteria, start, requested).ConfigureAwait(false));
|
|
||||||
totalCount = childrenResult.TotalRecordCount;
|
totalCount = childrenResult.TotalRecordCount;
|
||||||
|
|
||||||
provided = childrenResult.Items.Length;
|
provided = childrenResult.Items.Length;
|
||||||
|
|
||||||
foreach (var i in childrenResult.Items)
|
foreach (var i in childrenResult.Items)
|
||||||
{
|
{
|
||||||
if (i.IsFolder)
|
var displayStubType = GetDisplayStubType(i, serverItem.Item);
|
||||||
|
|
||||||
|
if (i.IsFolder || displayStubType.HasValue)
|
||||||
{
|
{
|
||||||
var f = (Folder)i;
|
var childCount = (await GetUserItems(i, displayStubType, user, sortCriteria, null, 0).ConfigureAwait(false))
|
||||||
var childCount = (await GetUserItems(f, user, sortCriteria, null, 0).ConfigureAwait(false))
|
|
||||||
.TotalRecordCount;
|
.TotalRecordCount;
|
||||||
|
|
||||||
result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, f, childCount, filter));
|
result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, i, displayStubType, item, childCount, filter));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, folder, deviceId, filter));
|
result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, item, serverItem.StubType, deviceId, filter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,6 +234,24 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StubType? GetDisplayStubType(BaseItem item, BaseItem context)
|
||||||
|
{
|
||||||
|
if (context == null || context.IsFolder)
|
||||||
|
{
|
||||||
|
var movie = item as Movie;
|
||||||
|
if (movie != null)
|
||||||
|
{
|
||||||
|
if (movie.LocalTrailerIds.Count > 0 ||
|
||||||
|
movie.SpecialFeatureIds.Count > 0)
|
||||||
|
{
|
||||||
|
return StubType.Folder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<KeyValuePair<string, string>>> HandleSearch(Headers sparams, User user, string deviceId)
|
private async Task<IEnumerable<KeyValuePair<string, string>>> HandleSearch(Headers sparams, User user, string deviceId)
|
||||||
{
|
{
|
||||||
var searchCriteria = new SearchCriteria(sparams.GetValueOrDefault("SearchCriteria", ""));
|
var searchCriteria = new SearchCriteria(sparams.GetValueOrDefault("SearchCriteria", ""));
|
||||||
@ -269,9 +290,11 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
|
|
||||||
result.AppendChild(didl);
|
result.AppendChild(didl);
|
||||||
|
|
||||||
var folder = (Folder)GetItemFromObjectId(sparams["ContainerID"], user);
|
var serverItem = GetItemFromObjectId(sparams["ContainerID"], user);
|
||||||
|
|
||||||
var childrenResult = (await GetChildrenSorted(folder, user, searchCriteria, sortCriteria, start, requested).ConfigureAwait(false));
|
var item = serverItem.Item;
|
||||||
|
|
||||||
|
var childrenResult = (await GetChildrenSorted(item, user, searchCriteria, sortCriteria, start, requested).ConfigureAwait(false));
|
||||||
|
|
||||||
var totalCount = childrenResult.TotalRecordCount;
|
var totalCount = childrenResult.TotalRecordCount;
|
||||||
|
|
||||||
@ -281,15 +304,14 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
{
|
{
|
||||||
if (i.IsFolder)
|
if (i.IsFolder)
|
||||||
{
|
{
|
||||||
var f = (Folder)i;
|
var childCount = (await GetChildrenSorted(i, user, searchCriteria, sortCriteria, null, 0).ConfigureAwait(false))
|
||||||
var childCount = (await GetChildrenSorted(f, user, searchCriteria, sortCriteria, null, 0).ConfigureAwait(false))
|
|
||||||
.TotalRecordCount;
|
.TotalRecordCount;
|
||||||
|
|
||||||
result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, f, childCount, filter));
|
result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, i, null, item, childCount, filter));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, folder, deviceId, filter));
|
result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, item, serverItem.StubType, deviceId, filter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,8 +326,10 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<QueryResult<BaseItem>> GetChildrenSorted(Folder folder, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit)
|
private async Task<QueryResult<BaseItem>> GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit)
|
||||||
{
|
{
|
||||||
|
var folder = (Folder)item;
|
||||||
|
|
||||||
var sortOrders = new List<string>();
|
var sortOrders = new List<string>();
|
||||||
if (!folder.IsPreSorted)
|
if (!folder.IsPreSorted)
|
||||||
{
|
{
|
||||||
@ -340,7 +364,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
//items = items.OfType<MusicAlbum>();
|
//items = items.OfType<MusicAlbum>();
|
||||||
isFolder = true;
|
isFolder = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await folder.GetItems(new InternalItemsQuery
|
return await folder.GetItems(new InternalItemsQuery
|
||||||
{
|
{
|
||||||
Limit = limit,
|
Limit = limit,
|
||||||
@ -356,8 +380,20 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<QueryResult<BaseItem>> GetUserItems(Folder folder, User user, SortCriteria sort, int? startIndex, int? limit)
|
private async Task<QueryResult<BaseItem>> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit)
|
||||||
{
|
{
|
||||||
|
if (stubType.HasValue)
|
||||||
|
{
|
||||||
|
var movie = item as Movie;
|
||||||
|
|
||||||
|
if (movie != null)
|
||||||
|
{
|
||||||
|
return await GetMovieItems(movie).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var folder = (Folder)item;
|
||||||
|
|
||||||
var sortOrders = new List<string>();
|
var sortOrders = new List<string>();
|
||||||
if (!folder.IsPreSorted)
|
if (!folder.IsPreSorted)
|
||||||
{
|
{
|
||||||
@ -376,6 +412,23 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task<QueryResult<BaseItem>> GetMovieItems(Movie item)
|
||||||
|
{
|
||||||
|
var list = new List<BaseItem>();
|
||||||
|
|
||||||
|
list.Add(item);
|
||||||
|
|
||||||
|
list.AddRange(item.LocalTrailerIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
|
||||||
|
list.AddRange(item.SpecialFeatureIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
|
||||||
|
list.AddRange(item.ThemeVideoIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
|
||||||
|
|
||||||
|
return Task.FromResult(new QueryResult<BaseItem>
|
||||||
|
{
|
||||||
|
Items = list.ToArray(),
|
||||||
|
TotalRecordCount = list.Count
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private bool FilterUnsupportedContent(BaseItem i, User user)
|
private bool FilterUnsupportedContent(BaseItem i, User user)
|
||||||
{
|
{
|
||||||
// Unplayable
|
// Unplayable
|
||||||
@ -399,26 +452,50 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseItem GetItemFromObjectId(string id, User user)
|
private ServerItem GetItemFromObjectId(string id, User user)
|
||||||
{
|
{
|
||||||
return DidlBuilder.IsIdRoot(id)
|
return DidlBuilder.IsIdRoot(id)
|
||||||
|
|
||||||
? user.RootFolder
|
? new ServerItem { Item = user.RootFolder }
|
||||||
: ParseItemId(id, user);
|
: ParseItemId(id, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseItem ParseItemId(string id, User user)
|
private ServerItem ParseItemId(string id, User user)
|
||||||
{
|
{
|
||||||
Guid itemId;
|
Guid itemId;
|
||||||
|
StubType? stubType = null;
|
||||||
|
|
||||||
|
if (id.StartsWith("folder_", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
stubType = StubType.Folder;
|
||||||
|
id = id.Split(new[] { '_' }, 2)[1];
|
||||||
|
}
|
||||||
|
|
||||||
if (Guid.TryParse(id, out itemId))
|
if (Guid.TryParse(id, out itemId))
|
||||||
{
|
{
|
||||||
return _libraryManager.GetItemById(itemId);
|
var item = _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
return new ServerItem
|
||||||
|
{
|
||||||
|
Item = item,
|
||||||
|
StubType = stubType
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Error("Error parsing item Id: {0}. Returning user root folder.", id);
|
Logger.Error("Error parsing item Id: {0}. Returning user root folder.", id);
|
||||||
|
|
||||||
return user.RootFolder;
|
return new ServerItem { Item = user.RootFolder };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ServerItem
|
||||||
|
{
|
||||||
|
public BaseItem Item { get; set; }
|
||||||
|
public StubType? StubType { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StubType
|
||||||
|
{
|
||||||
|
Folder = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using MediaBrowser.Controller.Entities.TV;
|
|||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Localization;
|
using MediaBrowser.Controller.Localization;
|
||||||
using MediaBrowser.Controller.Playlists;
|
using MediaBrowser.Controller.Playlists;
|
||||||
|
using MediaBrowser.Dlna.ContentDirectory;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
@ -63,25 +64,35 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
|
|
||||||
result.AppendChild(didl);
|
result.AppendChild(didl);
|
||||||
|
|
||||||
result.DocumentElement.AppendChild(GetItemElement(result, item, context, deviceId, filter, streamInfo));
|
result.DocumentElement.AppendChild(GetItemElement(result, item, context, null, deviceId, filter, streamInfo));
|
||||||
|
|
||||||
return result.DocumentElement.OuterXml;
|
return result.DocumentElement.OuterXml;
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlElement GetItemElement(XmlDocument doc, BaseItem item, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo = null)
|
public XmlElement GetItemElement(XmlDocument doc, BaseItem item, BaseItem context, StubType? contextStubType, string deviceId, Filter filter, StreamInfo streamInfo = null)
|
||||||
{
|
{
|
||||||
|
var clientId = GetClientId(item, null);
|
||||||
|
|
||||||
var element = doc.CreateElement(string.Empty, "item", NS_DIDL);
|
var element = doc.CreateElement(string.Empty, "item", NS_DIDL);
|
||||||
element.SetAttribute("restricted", "1");
|
element.SetAttribute("restricted", "1");
|
||||||
element.SetAttribute("id", item.Id.ToString("N"));
|
element.SetAttribute("id", clientId);
|
||||||
|
|
||||||
if (item.Parent != null)
|
if (context != null)
|
||||||
{
|
{
|
||||||
element.SetAttribute("parentID", item.Parent.Id.ToString("N"));
|
element.SetAttribute("parentID", GetClientId(context, contextStubType));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var parent = item.DisplayParent;
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
element.SetAttribute("parentID", GetClientId(parent, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//AddBookmarkInfo(item, user, element);
|
//AddBookmarkInfo(item, user, element);
|
||||||
|
|
||||||
AddGeneralProperties(item, context, element, filter);
|
AddGeneralProperties(item, null, context, element, filter);
|
||||||
|
|
||||||
// refID?
|
// refID?
|
||||||
// storeAttribute(itemNode, object, ClassProperties.REF_ID, false);
|
// storeAttribute(itemNode, object, ClassProperties.REF_ID, false);
|
||||||
@ -111,14 +122,14 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
{
|
{
|
||||||
var sources = _user == null ? video.GetMediaSources(true).ToList() : video.GetMediaSources(true, _user).ToList();
|
var sources = _user == null ? video.GetMediaSources(true).ToList() : video.GetMediaSources(true, _user).ToList();
|
||||||
|
|
||||||
streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
|
streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
|
||||||
{
|
{
|
||||||
ItemId = video.Id.ToString("N"),
|
ItemId = GetClientId(video),
|
||||||
MediaSources = sources,
|
MediaSources = sources,
|
||||||
Profile = _profile,
|
Profile = _profile,
|
||||||
DeviceId = deviceId,
|
DeviceId = deviceId,
|
||||||
MaxBitrate = _profile.MaxStreamingBitrate
|
MaxBitrate = _profile.MaxStreamingBitrate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetWidth = streamInfo.TargetWidth;
|
var targetWidth = streamInfo.TargetWidth;
|
||||||
@ -142,6 +153,7 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
streamInfo.TargetPacketLength,
|
streamInfo.TargetPacketLength,
|
||||||
streamInfo.TranscodeSeekInfo,
|
streamInfo.TranscodeSeekInfo,
|
||||||
streamInfo.IsTargetAnamorphic,
|
streamInfo.IsTargetAnamorphic,
|
||||||
|
streamInfo.IsTargetCabac,
|
||||||
streamInfo.TargetRefFrames);
|
streamInfo.TargetRefFrames);
|
||||||
|
|
||||||
foreach (var contentFeature in contentFeatureList)
|
foreach (var contentFeature in contentFeatureList)
|
||||||
@ -263,6 +275,7 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
streamInfo.TargetPacketLength,
|
streamInfo.TargetPacketLength,
|
||||||
streamInfo.TargetTimestamp,
|
streamInfo.TargetTimestamp,
|
||||||
streamInfo.IsTargetAnamorphic,
|
streamInfo.IsTargetAnamorphic,
|
||||||
|
streamInfo.IsTargetCabac,
|
||||||
streamInfo.TargetRefFrames);
|
streamInfo.TargetRefFrames);
|
||||||
|
|
||||||
var filename = url.Substring(0, url.IndexOf('?'));
|
var filename = url.Substring(0, url.IndexOf('?'));
|
||||||
@ -311,7 +324,7 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
|
|
||||||
return item.Name;
|
return item.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAudioResource(XmlElement container, IHasMediaSources audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
|
private void AddAudioResource(XmlElement container, IHasMediaSources audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
|
||||||
{
|
{
|
||||||
var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
|
var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
|
||||||
@ -322,7 +335,7 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
|
|
||||||
streamInfo = new StreamBuilder().BuildAudioItem(new AudioOptions
|
streamInfo = new StreamBuilder().BuildAudioItem(new AudioOptions
|
||||||
{
|
{
|
||||||
ItemId = audio.Id.ToString("N"),
|
ItemId = GetClientId(audio),
|
||||||
MediaSources = sources,
|
MediaSources = sources,
|
||||||
Profile = _profile,
|
Profile = _profile,
|
||||||
DeviceId = deviceId
|
DeviceId = deviceId
|
||||||
@ -403,8 +416,8 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
|
|
||||||
public static bool IsIdRoot(string id)
|
public static bool IsIdRoot(string id)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(id) ||
|
if (string.IsNullOrWhiteSpace(id) ||
|
||||||
|
|
||||||
string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
|
string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|
||||||
// Samsung sometimes uses 1 as root
|
// Samsung sometimes uses 1 as root
|
||||||
@ -416,13 +429,15 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlElement GetFolderElement(XmlDocument doc, BaseItem folder, int childCount, Filter filter, string requestedId = null)
|
public XmlElement GetFolderElement(XmlDocument doc, BaseItem folder, StubType? stubType, BaseItem context, int childCount, Filter filter, string requestedId = null)
|
||||||
{
|
{
|
||||||
var container = doc.CreateElement(string.Empty, "container", NS_DIDL);
|
var container = doc.CreateElement(string.Empty, "container", NS_DIDL);
|
||||||
container.SetAttribute("restricted", "0");
|
container.SetAttribute("restricted", "0");
|
||||||
container.SetAttribute("searchable", "1");
|
container.SetAttribute("searchable", "1");
|
||||||
container.SetAttribute("childCount", childCount.ToString(_usCulture));
|
container.SetAttribute("childCount", childCount.ToString(_usCulture));
|
||||||
|
|
||||||
|
var clientId = GetClientId(folder, stubType);
|
||||||
|
|
||||||
if (string.Equals(requestedId, "0"))
|
if (string.Equals(requestedId, "0"))
|
||||||
{
|
{
|
||||||
container.SetAttribute("id", "0");
|
container.SetAttribute("id", "0");
|
||||||
@ -430,20 +445,20 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
container.SetAttribute("id", folder.Id.ToString("N"));
|
container.SetAttribute("id", clientId);
|
||||||
|
|
||||||
var parent = folder.Parent;
|
var parent = context ?? folder.DisplayParent;
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
{
|
{
|
||||||
container.SetAttribute("parentID", "0");
|
container.SetAttribute("parentID", "0");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
container.SetAttribute("parentID", parent.Id.ToString("N"));
|
container.SetAttribute("parentID", GetClientId(parent, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCommonFields(folder, null, container, filter);
|
AddCommonFields(folder, stubType, null, container, filter);
|
||||||
|
|
||||||
AddCover(folder, container);
|
AddCover(folder, container);
|
||||||
|
|
||||||
@ -466,10 +481,11 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
/// Adds fields used by both items and folders
|
/// Adds fields used by both items and folders
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
|
/// <param name="itemStubType">Type of the item stub.</param>
|
||||||
/// <param name="context">The context.</param>
|
/// <param name="context">The context.</param>
|
||||||
/// <param name="element">The element.</param>
|
/// <param name="element">The element.</param>
|
||||||
/// <param name="filter">The filter.</param>
|
/// <param name="filter">The filter.</param>
|
||||||
private void AddCommonFields(BaseItem item, BaseItem context, XmlElement element, Filter filter)
|
private void AddCommonFields(BaseItem item, StubType? itemStubType, BaseItem context, XmlElement element, Filter filter)
|
||||||
{
|
{
|
||||||
// Don't filter on dc:title because not all devices will include it in the filter
|
// Don't filter on dc:title because not all devices will include it in the filter
|
||||||
// MediaMonkey for example won't display content without a title
|
// MediaMonkey for example won't display content without a title
|
||||||
@ -478,7 +494,7 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
AddValue(element, "dc", "title", GetDisplayName(item, context), NS_DC);
|
AddValue(element, "dc", "title", GetDisplayName(item, context), NS_DC);
|
||||||
}
|
}
|
||||||
|
|
||||||
element.AppendChild(CreateObjectClass(element.OwnerDocument, item));
|
element.AppendChild(CreateObjectClass(element.OwnerDocument, item, itemStubType));
|
||||||
|
|
||||||
if (filter.Contains("dc:date"))
|
if (filter.Contains("dc:date"))
|
||||||
{
|
{
|
||||||
@ -539,14 +555,14 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
AddPeople(item, element);
|
AddPeople(item, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XmlElement CreateObjectClass(XmlDocument result, BaseItem item)
|
private XmlElement CreateObjectClass(XmlDocument result, BaseItem item, StubType? stubType)
|
||||||
{
|
{
|
||||||
// More types here
|
// More types here
|
||||||
// http://oss.linn.co.uk/repos/Public/LibUpnpCil/DidlLite/UpnpAv/Test/TestDidlLite.cs
|
// http://oss.linn.co.uk/repos/Public/LibUpnpCil/DidlLite/UpnpAv/Test/TestDidlLite.cs
|
||||||
|
|
||||||
var objectClass = result.CreateElement("upnp", "class", NS_UPNP);
|
var objectClass = result.CreateElement("upnp", "class", NS_UPNP);
|
||||||
|
|
||||||
if (item.IsFolder)
|
if (item.IsFolder || stubType.HasValue)
|
||||||
{
|
{
|
||||||
string classType = null;
|
string classType = null;
|
||||||
|
|
||||||
@ -560,7 +576,7 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
{
|
{
|
||||||
classType = "object.container.person.musicArtist";
|
classType = "object.container.person.musicArtist";
|
||||||
}
|
}
|
||||||
else if (item is Series || item is Season || item is BoxSet)
|
else if (item is Series || item is Season || item is BoxSet || item is Video)
|
||||||
{
|
{
|
||||||
classType = "object.container.album.videoAlbum";
|
classType = "object.container.album.videoAlbum";
|
||||||
}
|
}
|
||||||
@ -628,9 +644,9 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddGeneralProperties(BaseItem item, BaseItem context, XmlElement element, Filter filter)
|
private void AddGeneralProperties(BaseItem item, StubType? itemStubType, BaseItem context, XmlElement element, Filter filter)
|
||||||
{
|
{
|
||||||
AddCommonFields(item, context, element, filter);
|
AddCommonFields(item, itemStubType, context, element, filter);
|
||||||
|
|
||||||
var audio = item as Audio;
|
var audio = item as Audio;
|
||||||
|
|
||||||
@ -671,10 +687,10 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
|
|
||||||
if (musicVideo != null)
|
if (musicVideo != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(musicVideo.Artist))
|
foreach (var artist in musicVideo.Artists)
|
||||||
{
|
{
|
||||||
AddValue(element, "upnp", "artist", musicVideo.Artist, NS_UPNP);
|
AddValue(element, "upnp", "artist", artist, NS_UPNP);
|
||||||
AddAlbumArtist(element, musicVideo.Artist);
|
AddAlbumArtist(element, artist);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(musicVideo.Album))
|
if (!string.IsNullOrEmpty(musicVideo.Album))
|
||||||
@ -773,20 +789,26 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AddImageResElement(item, element, 4096, 4096, playbackPercentage, "jpg", "JPEG_LRG");
|
var imageLimit = _profile.DidlAlbumArtLimit ?? 100;
|
||||||
AddImageResElement(item, element, 4096, 4096, playbackPercentage, "png", "PNG_LRG");
|
|
||||||
AddImageResElement(item, element, 1024, 768, playbackPercentage, "jpg", "JPEG_MED");
|
|
||||||
AddImageResElement(item, element, 640, 480, playbackPercentage, "jpg", "JPEG_SM");
|
|
||||||
AddImageResElement(item, element, 160, 160, playbackPercentage, "jpg", "JPEG_TN");
|
AddImageResElement(item, element, 160, 160, playbackPercentage, "jpg", "JPEG_TN");
|
||||||
AddImageResElement(item, element, 160, 160, playbackPercentage, "png", "PNG_TN");
|
|
||||||
|
if (imageLimit > 1)
|
||||||
|
{
|
||||||
|
AddImageResElement(item, element, 4096, 4096, playbackPercentage, "jpg", "JPEG_LRG");
|
||||||
|
AddImageResElement(item, element, 1024, 768, playbackPercentage, "jpg", "JPEG_MED");
|
||||||
|
AddImageResElement(item, element, 640, 480, playbackPercentage, "jpg", "JPEG_SM");
|
||||||
|
AddImageResElement(item, element, 4096, 4096, playbackPercentage, "png", "PNG_LRG");
|
||||||
|
AddImageResElement(item, element, 160, 160, playbackPercentage, "png", "PNG_TN");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddImageResElement(BaseItem item,
|
private void AddImageResElement(BaseItem item,
|
||||||
XmlElement element,
|
XmlElement element,
|
||||||
int maxWidth,
|
int maxWidth,
|
||||||
int maxHeight,
|
int maxHeight,
|
||||||
int playbackPercentage,
|
int playbackPercentage,
|
||||||
string format,
|
string format,
|
||||||
string org_Pn)
|
string org_Pn)
|
||||||
{
|
{
|
||||||
var imageInfo = GetImageInfo(item);
|
var imageInfo = GetImageInfo(item);
|
||||||
@ -920,6 +942,25 @@ namespace MediaBrowser.Dlna.Didl
|
|||||||
internal int? Height;
|
internal int? Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetClientId(BaseItem item, StubType? stubType)
|
||||||
|
{
|
||||||
|
var id = item.Id.ToString("N");
|
||||||
|
|
||||||
|
if (stubType.HasValue)
|
||||||
|
{
|
||||||
|
id = stubType.Value.ToString().ToLower() + "_" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetClientId(IHasMediaSources item)
|
||||||
|
{
|
||||||
|
var id = item.Id.ToString("N");
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
private ImageUrlInfo GetImageUrl(ImageDownloadInfo info, int maxWidth, int maxHeight, int playbackPercentage, string format)
|
private ImageUrlInfo GetImageUrl(ImageDownloadInfo info, int maxWidth, int maxHeight, int playbackPercentage, string format)
|
||||||
{
|
{
|
||||||
var url = string.Format("{0}/Items/{1}/Images/{2}/0/{3}/{4}/{5}/{6}/{7}",
|
var url = string.Format("{0}/Items/{1}/Images/{2}/0/{3}/{4}/{5}/{6}/{7}",
|
||||||
|
@ -3,6 +3,7 @@ using MediaBrowser.Common.Extensions;
|
|||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Dlna.Profiles;
|
using MediaBrowser.Dlna.Profiles;
|
||||||
using MediaBrowser.Dlna.Server;
|
using MediaBrowser.Dlna.Server;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
@ -37,8 +38,6 @@ namespace MediaBrowser.Dlna
|
|||||||
_appPaths = appPaths;
|
_appPaths = appPaths;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_jsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
|
|
||||||
//DumpProfiles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<DeviceProfile> GetProfiles()
|
public IEnumerable<DeviceProfile> GetProfiles()
|
||||||
@ -55,44 +54,6 @@ namespace MediaBrowser.Dlna
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DumpProfiles()
|
|
||||||
{
|
|
||||||
var list = new List<DeviceProfile>
|
|
||||||
{
|
|
||||||
new SamsungSmartTvProfile(),
|
|
||||||
new Xbox360Profile(),
|
|
||||||
new XboxOneProfile(),
|
|
||||||
new SonyPs3Profile(),
|
|
||||||
new SonyBravia2010Profile(),
|
|
||||||
new SonyBravia2011Profile(),
|
|
||||||
new SonyBravia2012Profile(),
|
|
||||||
new SonyBravia2013Profile(),
|
|
||||||
new SonyBlurayPlayer2013Profile(),
|
|
||||||
new SonyBlurayPlayerProfile(),
|
|
||||||
new PanasonicVieraProfile(),
|
|
||||||
new WdtvLiveProfile(),
|
|
||||||
new DenonAvrProfile(),
|
|
||||||
new LinksysDMA2100Profile(),
|
|
||||||
new LgTvProfile(),
|
|
||||||
new Foobar2000Profile(),
|
|
||||||
new MediaMonkeyProfile(),
|
|
||||||
new Windows81Profile(),
|
|
||||||
//new WindowsMediaCenterProfile(),
|
|
||||||
new WindowsPhoneProfile(),
|
|
||||||
new AndroidProfile(true, true, new[]{"baseline", "constrained baseline"}),
|
|
||||||
new DirectTvProfile(),
|
|
||||||
new DishHopperJoeyProfile(),
|
|
||||||
new DefaultProfile()
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var item in list)
|
|
||||||
{
|
|
||||||
var path = Path.Combine(_appPaths.ProgramDataPath, _fileSystem.GetValidFilename(item.Name) + ".xml");
|
|
||||||
|
|
||||||
_xmlSerializer.SerializeToFile(item, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _extracted;
|
private bool _extracted;
|
||||||
private readonly object _syncLock = new object();
|
private readonly object _syncLock = new object();
|
||||||
private void ExtractProfilesIfNeeded()
|
private void ExtractProfilesIfNeeded()
|
||||||
@ -521,4 +482,66 @@ namespace MediaBrowser.Dlna
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DlnaProfileEntryPoint : IServerEntryPoint
|
||||||
|
{
|
||||||
|
private readonly IApplicationPaths _appPaths;
|
||||||
|
private readonly IXmlSerializer _xmlSerializer;
|
||||||
|
private readonly IFileSystem _fileSystem;
|
||||||
|
|
||||||
|
public DlnaProfileEntryPoint(IApplicationPaths appPaths, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
|
||||||
|
{
|
||||||
|
_appPaths = appPaths;
|
||||||
|
_xmlSerializer = xmlSerializer;
|
||||||
|
_fileSystem = fileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
//DumpProfiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DumpProfiles()
|
||||||
|
{
|
||||||
|
var list = new List<DeviceProfile>
|
||||||
|
{
|
||||||
|
new SamsungSmartTvProfile(),
|
||||||
|
new Xbox360Profile(),
|
||||||
|
new XboxOneProfile(),
|
||||||
|
new SonyPs3Profile(),
|
||||||
|
new SonyBravia2010Profile(),
|
||||||
|
new SonyBravia2011Profile(),
|
||||||
|
new SonyBravia2012Profile(),
|
||||||
|
new SonyBravia2013Profile(),
|
||||||
|
new SonyBlurayPlayer2013Profile(),
|
||||||
|
new SonyBlurayPlayerProfile(),
|
||||||
|
new PanasonicVieraProfile(),
|
||||||
|
new WdtvLiveProfile(),
|
||||||
|
new DenonAvrProfile(),
|
||||||
|
new LinksysDMA2100Profile(),
|
||||||
|
new LgTvProfile(),
|
||||||
|
new Foobar2000Profile(),
|
||||||
|
new MediaMonkeyProfile(),
|
||||||
|
new Windows81Profile(),
|
||||||
|
//new WindowsMediaCenterProfile(),
|
||||||
|
new WindowsPhoneProfile(),
|
||||||
|
new AndroidProfile(),
|
||||||
|
new DirectTvProfile(),
|
||||||
|
new DishHopperJoeyProfile(),
|
||||||
|
new DefaultProfile(),
|
||||||
|
new PopcornHourProfile()
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
var path = Path.Combine(_appPaths.ProgramDataPath, _fileSystem.GetValidFilename(item.Name) + ".xml");
|
||||||
|
|
||||||
|
_xmlSerializer.SerializeToFile(item, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -75,6 +75,7 @@
|
|||||||
<Compile Include="PlayTo\PlayToController.cs" />
|
<Compile Include="PlayTo\PlayToController.cs" />
|
||||||
<Compile Include="Profiles\DirectTvProfile.cs" />
|
<Compile Include="Profiles\DirectTvProfile.cs" />
|
||||||
<Compile Include="Profiles\DishHopperJoeyProfile.cs" />
|
<Compile Include="Profiles\DishHopperJoeyProfile.cs" />
|
||||||
|
<Compile Include="Profiles\PopcornHourProfile.cs" />
|
||||||
<Compile Include="Ssdp\DeviceDiscoveryInfo.cs" />
|
<Compile Include="Ssdp\DeviceDiscoveryInfo.cs" />
|
||||||
<Compile Include="Ssdp\Extensions.cs" />
|
<Compile Include="Ssdp\Extensions.cs" />
|
||||||
<Compile Include="PlayTo\PlaybackProgressEventArgs.cs" />
|
<Compile Include="PlayTo\PlaybackProgressEventArgs.cs" />
|
||||||
@ -194,6 +195,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Profiles\Xml\Dish Hopper-Joey.xml" />
|
<EmbeddedResource Include="Profiles\Xml\Dish Hopper-Joey.xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Profiles\Xml\Popcorn Hour.xml" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
@ -139,16 +139,21 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager);
|
var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager);
|
||||||
var progress = GetProgressInfo(e.OldMediaInfo, streamInfo);
|
if (streamInfo.Item != null)
|
||||||
|
{
|
||||||
|
var progress = GetProgressInfo(e.OldMediaInfo, streamInfo);
|
||||||
|
|
||||||
var positionTicks = progress.PositionTicks;
|
var positionTicks = progress.PositionTicks;
|
||||||
|
|
||||||
ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks);
|
ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks);
|
||||||
|
}
|
||||||
|
|
||||||
streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager);
|
streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager);
|
||||||
progress = GetProgressInfo(e.NewMediaInfo, streamInfo);
|
if (streamInfo.Item == null) return;
|
||||||
|
|
||||||
|
var newItemProgress = GetProgressInfo(e.NewMediaInfo, streamInfo);
|
||||||
|
|
||||||
await _sessionManager.OnPlaybackStart(progress).ConfigureAwait(false);
|
await _sessionManager.OnPlaybackStart(newItemProgress).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -161,6 +166,9 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager);
|
var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager);
|
||||||
|
|
||||||
|
if (streamInfo.Item == null) return;
|
||||||
|
|
||||||
var progress = GetProgressInfo(e.MediaInfo, streamInfo);
|
var progress = GetProgressInfo(e.MediaInfo, streamInfo);
|
||||||
|
|
||||||
var positionTicks = progress.PositionTicks;
|
var positionTicks = progress.PositionTicks;
|
||||||
@ -219,9 +227,14 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var info = GetProgressInfo(e.MediaInfo);
|
var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager);
|
||||||
|
|
||||||
await _sessionManager.OnPlaybackStart(info).ConfigureAwait(false);
|
if (info.Item != null)
|
||||||
|
{
|
||||||
|
var progress = GetProgressInfo(e.MediaInfo, info);
|
||||||
|
|
||||||
|
await _sessionManager.OnPlaybackStart(progress).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -233,9 +246,14 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var info = GetProgressInfo(e.MediaInfo);
|
var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager);
|
||||||
|
|
||||||
await _sessionManager.OnPlaybackProgress(info).ConfigureAwait(false);
|
if (info.Item != null)
|
||||||
|
{
|
||||||
|
var progress = GetProgressInfo(e.MediaInfo, info);
|
||||||
|
|
||||||
|
await _sessionManager.OnPlaybackProgress(progress).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -243,13 +261,6 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlaybackStartInfo GetProgressInfo(uBaseObject mediaInfo)
|
|
||||||
{
|
|
||||||
var info = StreamParams.ParseFromUrl(mediaInfo.Url, _libraryManager);
|
|
||||||
|
|
||||||
return GetProgressInfo(mediaInfo, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PlaybackStartInfo GetProgressInfo(uBaseObject mediaInfo, StreamParams info)
|
private PlaybackStartInfo GetProgressInfo(uBaseObject mediaInfo, StreamParams info)
|
||||||
{
|
{
|
||||||
var ticks = _device.Position.Ticks;
|
var ticks = _device.Position.Ticks;
|
||||||
@ -441,19 +452,9 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
private void AddItemFromId(Guid id, List<BaseItem> list)
|
private void AddItemFromId(Guid id, List<BaseItem> list)
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(id);
|
var item = _libraryManager.GetItemById(id);
|
||||||
if (item.IsFolder)
|
if (item.MediaType == MediaType.Audio || item.MediaType == MediaType.Video)
|
||||||
{
|
{
|
||||||
foreach (var childId in _itemRepository.GetChildren(item.Id))
|
list.Add(item);
|
||||||
{
|
|
||||||
AddItemFromId(childId, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (item.MediaType == MediaType.Audio || item.MediaType == MediaType.Video)
|
|
||||||
{
|
|
||||||
list.Add(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,6 +527,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
streamInfo.TargetPacketLength,
|
streamInfo.TargetPacketLength,
|
||||||
streamInfo.TranscodeSeekInfo,
|
streamInfo.TranscodeSeekInfo,
|
||||||
streamInfo.IsTargetAnamorphic,
|
streamInfo.IsTargetAnamorphic,
|
||||||
|
streamInfo.IsTargetCabac,
|
||||||
streamInfo.TargetRefFrames);
|
streamInfo.TargetRefFrames);
|
||||||
|
|
||||||
return list.FirstOrDefault();
|
return list.FirstOrDefault();
|
||||||
@ -736,10 +738,10 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
if (media != null)
|
if (media != null)
|
||||||
{
|
{
|
||||||
var info = StreamParams.ParseFromUrl(media.Url, _libraryManager);
|
var info = StreamParams.ParseFromUrl(media.Url, _libraryManager);
|
||||||
var progress = GetProgressInfo(media, info);
|
|
||||||
|
|
||||||
if (info.Item != null)
|
if (info.Item != null)
|
||||||
{
|
{
|
||||||
|
var progress = GetProgressInfo(media, info);
|
||||||
var newPosition = progress.PositionTicks ?? 0;
|
var newPosition = progress.PositionTicks ?? 0;
|
||||||
|
|
||||||
var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null;
|
var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null;
|
||||||
@ -762,10 +764,10 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
if (media != null)
|
if (media != null)
|
||||||
{
|
{
|
||||||
var info = StreamParams.ParseFromUrl(media.Url, _libraryManager);
|
var info = StreamParams.ParseFromUrl(media.Url, _libraryManager);
|
||||||
var progress = GetProgressInfo(media, info);
|
|
||||||
|
|
||||||
if (info.Item != null)
|
if (info.Item != null)
|
||||||
{
|
{
|
||||||
|
var progress = GetProgressInfo(media, info);
|
||||||
var newPosition = progress.PositionTicks ?? 0;
|
var newPosition = progress.PositionTicks ?? 0;
|
||||||
|
|
||||||
var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null;
|
var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null;
|
||||||
@ -829,7 +831,9 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
ItemId = GetItemId(url)
|
ItemId = GetItemId(url)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(request.ItemId))
|
Guid parsedId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(request.ItemId) || !Guid.TryParse(request.ItemId, out parsedId))
|
||||||
{
|
{
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
@ -882,7 +886,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||||||
|
|
||||||
request.Item = string.IsNullOrWhiteSpace(request.ItemId)
|
request.Item = string.IsNullOrWhiteSpace(request.ItemId)
|
||||||
? null
|
? null
|
||||||
: libraryManager.GetItemById(new Guid(request.ItemId));
|
: libraryManager.GetItemById(parsedId);
|
||||||
|
|
||||||
var hasMediaSources = request.Item as IHasMediaSources;
|
var hasMediaSources = request.Item as IHasMediaSources;
|
||||||
|
|
||||||
|
@ -202,6 +202,17 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Method = SubtitleDeliveryMethod.External
|
Method = SubtitleDeliveryMethod.External
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new[]
|
||||||
|
{
|
||||||
|
new ResponseProfile
|
||||||
|
{
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
Container = "ts",
|
||||||
|
OrgPn = "MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO",
|
||||||
|
MimeType = "video/vnd.dlna.mpeg-tts"
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
178
MediaBrowser.Dlna/Profiles/PopcornHourProfile.cs
Normal file
178
MediaBrowser.Dlna/Profiles/PopcornHourProfile.cs
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
using MediaBrowser.Model.Dlna;
|
||||||
|
using MediaBrowser.Model.Dlna.Profiles;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Dlna.Profiles
|
||||||
|
{
|
||||||
|
[XmlRoot("Profile")]
|
||||||
|
public class PopcornHourProfile : DefaultProfile
|
||||||
|
{
|
||||||
|
public PopcornHourProfile()
|
||||||
|
{
|
||||||
|
Name = "Popcorn Hour";
|
||||||
|
|
||||||
|
TranscodingProfiles = new[]
|
||||||
|
{
|
||||||
|
new TranscodingProfile
|
||||||
|
{
|
||||||
|
Container = "mp3",
|
||||||
|
AudioCodec = "mp3",
|
||||||
|
Type = DlnaProfileType.Audio
|
||||||
|
},
|
||||||
|
|
||||||
|
new TranscodingProfile
|
||||||
|
{
|
||||||
|
Container = "mp4",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
AudioCodec = "aac",
|
||||||
|
VideoCodec = "h264",
|
||||||
|
VideoProfile= "baseline"
|
||||||
|
},
|
||||||
|
|
||||||
|
new TranscodingProfile
|
||||||
|
{
|
||||||
|
Container = "jpeg",
|
||||||
|
Type = DlnaProfileType.Photo
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DirectPlayProfiles = new[]
|
||||||
|
{
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "mp4,mov",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "h264,mpeg4",
|
||||||
|
AudioCodec = "aac"
|
||||||
|
},
|
||||||
|
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "ts",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "h264",
|
||||||
|
AudioCodec = "aac,ac3,eac3,mp3,mp2,pcm"
|
||||||
|
},
|
||||||
|
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "asf,wmv",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "wmv3,vc1",
|
||||||
|
AudioCodec = "wmav2,wmapro"
|
||||||
|
},
|
||||||
|
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "avi",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "mpeg4,msmpeg4",
|
||||||
|
AudioCodec = "mp3,ac3,eac3,mp2,pcm"
|
||||||
|
},
|
||||||
|
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "mkv",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "h264",
|
||||||
|
AudioCodec = "aac,mp3,ac3,eac3,mp2,pcm"
|
||||||
|
},
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "aac,mp3,flac,ogg,wma,wav",
|
||||||
|
Type = DlnaProfileType.Audio
|
||||||
|
},
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "jpeg,gif,bmp,png",
|
||||||
|
Type = DlnaProfileType.Photo
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CodecProfiles = new[]
|
||||||
|
{
|
||||||
|
new CodecProfile
|
||||||
|
{
|
||||||
|
Type = CodecType.Video,
|
||||||
|
Conditions = new []
|
||||||
|
{
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.LessThanEqual,
|
||||||
|
Property = ProfileConditionValue.Width,
|
||||||
|
Value = "1920"
|
||||||
|
},
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.LessThanEqual,
|
||||||
|
Property = ProfileConditionValue.Height,
|
||||||
|
Value = "1080"
|
||||||
|
},
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.NotEquals,
|
||||||
|
Property = ProfileConditionValue.IsAnamorphic,
|
||||||
|
Value = "true",
|
||||||
|
IsRequired = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
new CodecProfile
|
||||||
|
{
|
||||||
|
Type = CodecType.VideoAudio,
|
||||||
|
Codec = "aac",
|
||||||
|
Conditions = new []
|
||||||
|
{
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.LessThanEqual,
|
||||||
|
Property = ProfileConditionValue.AudioChannels,
|
||||||
|
Value = "2",
|
||||||
|
IsRequired = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
new CodecProfile
|
||||||
|
{
|
||||||
|
Type = CodecType.Audio,
|
||||||
|
Codec = "aac",
|
||||||
|
Conditions = new []
|
||||||
|
{
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.LessThanEqual,
|
||||||
|
Property = ProfileConditionValue.AudioChannels,
|
||||||
|
Value = "2",
|
||||||
|
IsRequired = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
new CodecProfile
|
||||||
|
{
|
||||||
|
Type = CodecType.Audio,
|
||||||
|
Codec = "mp3",
|
||||||
|
Conditions = new []
|
||||||
|
{
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.LessThanEqual,
|
||||||
|
Property = ProfileConditionValue.AudioChannels,
|
||||||
|
Value = "2",
|
||||||
|
IsRequired = false
|
||||||
|
},
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.LessThanEqual,
|
||||||
|
Property = ProfileConditionValue.AudioBitrate,
|
||||||
|
Value = "320000",
|
||||||
|
IsRequired = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using System.Xml.Serialization;
|
|
||||||
using MediaBrowser.Model.Dlna.Profiles;
|
using MediaBrowser.Model.Dlna.Profiles;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Dlna.Profiles
|
namespace MediaBrowser.Dlna.Profiles
|
||||||
{
|
{
|
||||||
@ -342,12 +341,6 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
|
|
||||||
SubtitleProfiles = new[]
|
SubtitleProfiles = new[]
|
||||||
{
|
{
|
||||||
new SubtitleProfile
|
|
||||||
{
|
|
||||||
Format = "smi",
|
|
||||||
Method = SubtitleDeliveryMethod.External,
|
|
||||||
DidlMode = "CaptionInfoEx"
|
|
||||||
},
|
|
||||||
new SubtitleProfile
|
new SubtitleProfile
|
||||||
{
|
{
|
||||||
Format = "srt",
|
Format = "srt",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using System.Xml.Serialization;
|
|
||||||
using MediaBrowser.Model.Dlna.Profiles;
|
using MediaBrowser.Model.Dlna.Profiles;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Dlna.Profiles
|
namespace MediaBrowser.Dlna.Profiles
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
ProtocolInfo =
|
ProtocolInfo =
|
||||||
"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000";
|
"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000";
|
||||||
|
|
||||||
|
DidlAlbumArtLimit = 1;
|
||||||
|
|
||||||
TranscodingProfiles = new[]
|
TranscodingProfiles = new[]
|
||||||
{
|
{
|
||||||
new TranscodingProfile
|
new TranscodingProfile
|
||||||
|
@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Manufacturer = "Microsoft Corporation";
|
Manufacturer = "Microsoft Corporation";
|
||||||
ManufacturerUrl = "http://www.microsoft.com/";
|
ManufacturerUrl = "http://www.microsoft.com/";
|
||||||
SonyAggregationFlags = "10";
|
SonyAggregationFlags = "10";
|
||||||
|
DidlAlbumArtLimit = 1;
|
||||||
|
|
||||||
TranscodingProfiles = new[]
|
TranscodingProfiles = new[]
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Manufacturer = "Microsoft Corporation";
|
Manufacturer = "Microsoft Corporation";
|
||||||
ManufacturerUrl = "http://www.microsoft.com/";
|
ManufacturerUrl = "http://www.microsoft.com/";
|
||||||
SonyAggregationFlags = "10";
|
SonyAggregationFlags = "10";
|
||||||
|
DidlAlbumArtLimit = 1;
|
||||||
|
|
||||||
TranscodingProfiles = new[]
|
TranscodingProfiles = new[]
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Manufacturer = "Microsoft Corporation";
|
Manufacturer = "Microsoft Corporation";
|
||||||
ManufacturerUrl = "http://www.microsoft.com/";
|
ManufacturerUrl = "http://www.microsoft.com/";
|
||||||
SonyAggregationFlags = "10";
|
SonyAggregationFlags = "10";
|
||||||
|
DidlAlbumArtLimit = 1;
|
||||||
|
|
||||||
TranscodingProfiles = new[]
|
TranscodingProfiles = new[]
|
||||||
{
|
{
|
||||||
|
@ -37,6 +37,49 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
|
|
||||||
SonyAggregationFlags = "10";
|
SonyAggregationFlags = "10";
|
||||||
XDlnaDoc = "DMS-1.50";
|
XDlnaDoc = "DMS-1.50";
|
||||||
|
DidlAlbumArtLimit = 1;
|
||||||
|
|
||||||
|
DirectPlayProfiles = new[]
|
||||||
|
{
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "avi",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "mpeg4",
|
||||||
|
AudioCodec = "mp2,mp3"
|
||||||
|
},
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "ts",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "mpeg1video,mpeg2video,h264",
|
||||||
|
AudioCodec = "ac3,mp2,mp3,aac"
|
||||||
|
},
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "mpeg",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "mpeg1video,mpeg2video",
|
||||||
|
AudioCodec = "mp2"
|
||||||
|
},
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "mp4",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
VideoCodec = "h264,mpeg4",
|
||||||
|
AudioCodec = "aac,ac3"
|
||||||
|
},
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "aac,mp3,wav",
|
||||||
|
Type = DlnaProfileType.Audio
|
||||||
|
},
|
||||||
|
new DirectPlayProfile
|
||||||
|
{
|
||||||
|
Container = "jpeg,png,gif,bmp,tiff",
|
||||||
|
Type = DlnaProfileType.Photo
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TranscodingProfiles = new[]
|
TranscodingProfiles = new[]
|
||||||
{
|
{
|
||||||
@ -185,28 +228,6 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
IsRequired = false
|
IsRequired = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
new CodecProfile
|
|
||||||
{
|
|
||||||
Type = CodecType.VideoAudio,
|
|
||||||
Codec = "aac",
|
|
||||||
|
|
||||||
Conditions = new []
|
|
||||||
{
|
|
||||||
new ProfileCondition
|
|
||||||
{
|
|
||||||
Condition = ProfileConditionType.LessThanEqual,
|
|
||||||
Property = ProfileConditionValue.AudioChannels,
|
|
||||||
Value = "2"
|
|
||||||
},
|
|
||||||
new ProfileCondition
|
|
||||||
{
|
|
||||||
Condition = ProfileConditionType.NotEquals,
|
|
||||||
Property = ProfileConditionValue.AudioProfile,
|
|
||||||
Value = "he-aac"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using System.Xml.Serialization;
|
|
||||||
using MediaBrowser.Model.Dlna.Profiles;
|
using MediaBrowser.Model.Dlna.Profiles;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Dlna.Profiles
|
namespace MediaBrowser.Dlna.Profiles
|
||||||
{
|
{
|
||||||
@ -10,8 +10,9 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
public XboxOneProfile()
|
public XboxOneProfile()
|
||||||
{
|
{
|
||||||
Name = "Xbox One";
|
Name = "Xbox One";
|
||||||
XDlnaDoc = "DMS-1.50";
|
|
||||||
|
|
||||||
|
TimelineOffsetSeconds = 40;
|
||||||
|
|
||||||
Identification = new DeviceIdentification
|
Identification = new DeviceIdentification
|
||||||
{
|
{
|
||||||
ModelName = "Xbox One",
|
ModelName = "Xbox One",
|
||||||
@ -27,10 +28,16 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Type = DlnaProfileType.Audio
|
Type = DlnaProfileType.Audio
|
||||||
},
|
},
|
||||||
new TranscodingProfile
|
new TranscodingProfile
|
||||||
|
{
|
||||||
|
Container = "jpeg",
|
||||||
|
VideoCodec = "jpeg",
|
||||||
|
Type = DlnaProfileType.Photo
|
||||||
|
},
|
||||||
|
new TranscodingProfile
|
||||||
{
|
{
|
||||||
Container = "ts",
|
Container = "ts",
|
||||||
VideoCodec = "h264",
|
VideoCodec = "h264",
|
||||||
AudioCodec = "ac3",
|
AudioCodec = "aac",
|
||||||
Type = DlnaProfileType.Video,
|
Type = DlnaProfileType.Video,
|
||||||
EstimateContentLength = true
|
EstimateContentLength = true
|
||||||
}
|
}
|
||||||
@ -114,6 +121,28 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
|
|
||||||
CodecProfiles = new[]
|
CodecProfiles = new[]
|
||||||
{
|
{
|
||||||
|
new CodecProfile
|
||||||
|
{
|
||||||
|
Type = CodecType.Video,
|
||||||
|
Conditions = new []
|
||||||
|
{
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.NotEquals,
|
||||||
|
Property = ProfileConditionValue.IsAnamorphic,
|
||||||
|
Value = "true",
|
||||||
|
IsRequired = false
|
||||||
|
},
|
||||||
|
new ProfileCondition
|
||||||
|
{
|
||||||
|
Condition = ProfileConditionType.LessThanEqual,
|
||||||
|
Property = ProfileConditionValue.VideoBitDepth,
|
||||||
|
Value = "8",
|
||||||
|
IsRequired = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
new CodecProfile
|
new CodecProfile
|
||||||
{
|
{
|
||||||
Type = CodecType.Video,
|
Type = CodecType.Video,
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -25,6 +26,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp4" audioCodec="aac" videoCodec="h264,mpeg4" type="Video" />
|
<DirectPlayProfile container="mp4" audioCodec="aac" videoCodec="h264,mpeg4" type="Video" />
|
||||||
@ -36,33 +39,43 @@
|
|||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||||
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" protocol="hls" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="Baseline" context="Streaming" />
|
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" protocol="hls" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="baseline" context="Streaming" />
|
||||||
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="Baseline" context="Static" />
|
<TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="baseline" context="Static" />
|
||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles>
|
<CodecProfiles>
|
||||||
|
<CodecProfile type="Video" codec="h264">
|
||||||
|
<Conditions>
|
||||||
|
<ProfileCondition condition="EqualsAny" property="VideoProfile" value="baseline|constrained baseline" isRequired="false" />
|
||||||
|
<ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="false" />
|
||||||
|
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="false" />
|
||||||
|
<ProfileCondition condition="LessThanEqual" property="VideoBitDepth" value="8" isRequired="false" />
|
||||||
|
<ProfileCondition condition="NotEquals" property="IsAnamorphic" value="true" isRequired="false" />
|
||||||
|
<ProfileCondition condition="Equals" property="IsCabac" value="true" isRequired="false" />
|
||||||
|
</Conditions>
|
||||||
|
</CodecProfile>
|
||||||
<CodecProfile type="Video">
|
<CodecProfile type="Video">
|
||||||
<Conditions>
|
<Conditions>
|
||||||
<ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
|
<ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="false" />
|
||||||
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
|
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="false" />
|
||||||
<ProfileCondition condition="NotEquals" property="IsAnamorphic" value="true" isRequired="false" />
|
|
||||||
<ProfileCondition condition="LessThanEqual" property="VideoBitDepth" value="8" isRequired="false" />
|
<ProfileCondition condition="LessThanEqual" property="VideoBitDepth" value="8" isRequired="false" />
|
||||||
|
<ProfileCondition condition="NotEquals" property="IsAnamorphic" value="true" isRequired="false" />
|
||||||
</Conditions>
|
</Conditions>
|
||||||
</CodecProfile>
|
</CodecProfile>
|
||||||
<CodecProfile type="VideoAudio" codec="aac">
|
<CodecProfile type="VideoAudio" codec="aac">
|
||||||
<Conditions>
|
<Conditions>
|
||||||
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
|
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
|
||||||
</Conditions>
|
</Conditions>
|
||||||
</CodecProfile>
|
</CodecProfile>
|
||||||
<CodecProfile type="Audio" codec="aac">
|
<CodecProfile type="Audio" codec="aac">
|
||||||
<Conditions>
|
<Conditions>
|
||||||
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
|
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
|
||||||
</Conditions>
|
</Conditions>
|
||||||
</CodecProfile>
|
</CodecProfile>
|
||||||
<CodecProfile type="Audio" codec="mp3">
|
<CodecProfile type="Audio" codec="mp3">
|
||||||
<Conditions>
|
<Conditions>
|
||||||
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
|
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
|
||||||
<ProfileCondition condition="LessThanEqual" property="AudioBitrate" value="320000" isRequired="true" />
|
<ProfileCondition condition="LessThanEqual" property="AudioBitrate" value="320000" isRequired="false" />
|
||||||
</Conditions>
|
</Conditions>
|
||||||
</CodecProfile>
|
</CodecProfile>
|
||||||
</CodecProfiles>
|
</CodecProfiles>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -25,6 +26,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp3,wma" type="Audio" />
|
<DirectPlayProfile container="mp3,wma" type="Audio" />
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -30,6 +31,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
|
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -31,6 +32,8 @@
|
|||||||
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>true</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>true</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>true</RequiresPlainFolders>
|
<RequiresPlainFolders>true</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mpeg" audioCodec="mp2" videoCodec="mpeg2video" type="Video" />
|
<DirectPlayProfile container="mpeg" audioCodec="mp2" videoCodec="mpeg2video" type="Video" />
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -32,6 +33,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp4,mkv,mpeg,ts" audioCodec="mp3,ac3,aac,he-aac,pcm" videoCodec="h264,mpeg2video" type="Video" />
|
<DirectPlayProfile container="mp4,mkv,mpeg,ts" audioCodec="mp3,ac3,aac,he-aac,pcm" videoCodec="h264,mpeg2video" type="Video" />
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -31,6 +32,8 @@
|
|||||||
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="ts" audioCodec="aac,ac3,mp3" videoCodec="h264" type="Video" />
|
<DirectPlayProfile container="ts" audioCodec="aac,ac3,mp3" videoCodec="h264" type="Video" />
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -29,6 +30,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
|
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -31,6 +32,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" />
|
<DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" />
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -32,6 +33,8 @@
|
|||||||
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:pv" value="http://www.pv.com/pvns/" />
|
<XmlAttribute name="xmlns:pv" value="http://www.pv.com/pvns/" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
|
74
MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
Normal file
74
MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
Normal file
File diff suppressed because one or more lines are too long
@ -16,6 +16,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -31,6 +32,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:sec" value="http://www.sec.co.kr/" />
|
<XmlAttribute name="xmlns:sec" value="http://www.sec.co.kr/" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
@ -109,7 +112,6 @@
|
|||||||
</ResponseProfile>
|
</ResponseProfile>
|
||||||
</ResponseProfiles>
|
</ResponseProfiles>
|
||||||
<SubtitleProfiles>
|
<SubtitleProfiles>
|
||||||
<SubtitleProfile format="smi" method="External" didlMode="CaptionInfoEx" />
|
|
||||||
<SubtitleProfile format="srt" method="External" didlMode="CaptionInfoEx" />
|
<SubtitleProfile format="srt" method="External" didlMode="CaptionInfoEx" />
|
||||||
</SubtitleProfiles>
|
</SubtitleProfiles>
|
||||||
</Profile>
|
</Profile>
|
@ -16,6 +16,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -31,6 +32,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -33,6 +34,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit>1</DidlAlbumArtLimit>
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -33,6 +34,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit>1</DidlAlbumArtLimit>
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -33,6 +34,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit>1</DidlAlbumArtLimit>
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -33,6 +34,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit>1</DidlAlbumArtLimit>
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -33,6 +34,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes>
|
<XmlRootAttributes>
|
||||||
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
<XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
|
||||||
</XmlRootAttributes>
|
</XmlRootAttributes>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit>1</DidlAlbumArtLimit>
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
<AlbumArtPn>JPEG_TN</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -33,10 +34,16 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp3,wma" type="Audio" />
|
<DirectPlayProfile container="avi" audioCodec="mp2,mp3" videoCodec="mpeg4" type="Video" />
|
||||||
<DirectPlayProfile container="avi,mp4" type="Video" />
|
<DirectPlayProfile container="ts" audioCodec="ac3,mp2,mp3,aac" videoCodec="mpeg1video,mpeg2video,h264" type="Video" />
|
||||||
|
<DirectPlayProfile container="mpeg" audioCodec="mp2" videoCodec="mpeg1video,mpeg2video" type="Video" />
|
||||||
|
<DirectPlayProfile container="mp4" audioCodec="aac,ac3" videoCodec="h264,mpeg4" type="Video" />
|
||||||
|
<DirectPlayProfile container="aac,mp3,wav" type="Audio" />
|
||||||
|
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
|
||||||
@ -77,12 +84,6 @@
|
|||||||
<ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="false" />
|
<ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="false" />
|
||||||
</Conditions>
|
</Conditions>
|
||||||
</CodecProfile>
|
</CodecProfile>
|
||||||
<CodecProfile type="VideoAudio" codec="aac">
|
|
||||||
<Conditions>
|
|
||||||
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
|
|
||||||
<ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="true" />
|
|
||||||
</Conditions>
|
|
||||||
</CodecProfile>
|
|
||||||
</CodecProfiles>
|
</CodecProfiles>
|
||||||
<ResponseProfiles>
|
<ResponseProfiles>
|
||||||
<ResponseProfile container="mp4,mov" audioCodec="aac" type="Video" mimeType="video/mp4">
|
<ResponseProfile container="mp4,mov" audioCodec="aac" type="Video" mimeType="video/mp4">
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>true</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>true</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -32,6 +33,8 @@
|
|||||||
<TimelineOffsetSeconds>5</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>5</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="avi" audioCodec="ac3,dca,mp2,mp3,pcm" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
|
<DirectPlayProfile container="avi" audioCodec="ac3,dca,mp2,mp3,pcm" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -29,6 +30,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp4,mov" audioCodec="aac,ac3,eac3,mp3,pcm" videoCodec="h264,mpeg4" type="Video" />
|
<DirectPlayProfile container="mp4,mov" audioCodec="aac,ac3,eac3,mp3,pcm" videoCodec="h264,mpeg4" type="Video" />
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -25,6 +26,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp4,mov" audioCodec="aac,mp3" videoCodec="h264" type="Video" />
|
<DirectPlayProfile container="mp4,mov" audioCodec="aac,mp3" videoCodec="h264" type="Video" />
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
<ModelUrl>http://www.microsoft.com/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -32,6 +33,8 @@
|
|||||||
<TimelineOffsetSeconds>40</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>40</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>true</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>true</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>true</RequiresPlainFolders>
|
<RequiresPlainFolders>true</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" />
|
<DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" />
|
||||||
|
File diff suppressed because one or more lines are too long
@ -16,6 +16,7 @@
|
|||||||
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
<ModelUrl>http://mediabrowser.tv/</ModelUrl>
|
||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
|
||||||
|
<DidlAlbumArtLimit xsi:nil="true" />
|
||||||
<SupportedMediaTypes>Audio</SupportedMediaTypes>
|
<SupportedMediaTypes>Audio</SupportedMediaTypes>
|
||||||
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
<AlbumArtPn>JPEG_SM</AlbumArtPn>
|
||||||
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
<MaxAlbumArtWidth>480</MaxAlbumArtWidth>
|
||||||
@ -31,6 +32,8 @@
|
|||||||
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
|
||||||
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
|
||||||
<RequiresPlainFolders>false</RequiresPlainFolders>
|
<RequiresPlainFolders>false</RequiresPlainFolders>
|
||||||
|
<SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
|
||||||
|
<SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" />
|
<DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" />
|
||||||
|
@ -172,6 +172,7 @@ namespace MediaBrowser.Dlna.Ssdp
|
|||||||
values["ST"] = d.Type;
|
values["ST"] = d.Type;
|
||||||
values["USN"] = d.USN;
|
values["USN"] = d.USN;
|
||||||
|
|
||||||
|
SendDatagram(header, values, endpoint, null, true);
|
||||||
SendDatagram(header, values, endpoint, new IPEndPoint(d.Address, 0), true);
|
SendDatagram(header, values, endpoint, new IPEndPoint(d.Address, 0), true);
|
||||||
//SendDatagram(header, values, endpoint, null, true);
|
//SendDatagram(header, values, endpoint, null, true);
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
using System.Xml;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace MediaBrowser.LocalMetadata.Parsers
|
namespace MediaBrowser.LocalMetadata.Parsers
|
||||||
{
|
{
|
||||||
@ -26,8 +27,17 @@ namespace MediaBrowser.LocalMetadata.Parsers
|
|||||||
switch (reader.Name)
|
switch (reader.Name)
|
||||||
{
|
{
|
||||||
case "Artist":
|
case "Artist":
|
||||||
item.Artist = reader.ReadElementContentAsString();
|
{
|
||||||
break;
|
var val = reader.ReadElementContentAsString();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
|
{
|
||||||
|
var artists = val.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
item.Artists.AddRange(artists);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "Album":
|
case "Album":
|
||||||
item.Album = reader.ReadElementContentAsString();
|
item.Album = reader.ReadElementContentAsString();
|
||||||
|
@ -78,9 +78,9 @@ namespace MediaBrowser.LocalMetadata.Savers
|
|||||||
|
|
||||||
if (musicVideo != null)
|
if (musicVideo != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(musicVideo.Artist))
|
if (musicVideo.Artists.Count > 0)
|
||||||
{
|
{
|
||||||
builder.Append("<Artist>" + SecurityElement.Escape(musicVideo.Artist) + "</Artist>");
|
builder.Append("<Artist>" + SecurityElement.Escape(string.Join(";", musicVideo.Artists.ToArray())) + "</Artist>");
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(musicVideo.Album))
|
if (!string.IsNullOrEmpty(musicVideo.Album))
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,12 @@ namespace MediaBrowser.MediaInfo
|
|||||||
result.IsInterlaced = text.IndexOf("interlac", StringComparison.OrdinalIgnoreCase) != -1;
|
result.IsInterlaced = text.IndexOf("interlac", StringComparison.OrdinalIgnoreCase) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text = GetValue(lib, videoStreamIndex, new[] { "Format_Settings_CABAC", "Format_Settings_CABAC/String" });
|
||||||
|
if (!string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
result.IsCabac = string.Equals(text, "yes", StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
int bitDepth;
|
int bitDepth;
|
||||||
text = GetValue(lib, videoStreamIndex, new[] { "BitDepth", "BitDepth/String" });
|
text = GetValue(lib, videoStreamIndex, new[] { "BitDepth", "BitDepth/String" });
|
||||||
|
|
||||||
@ -51,6 +57,7 @@ namespace MediaBrowser.MediaInfo
|
|||||||
|
|
||||||
public class MediaInfoResult
|
public class MediaInfoResult
|
||||||
{
|
{
|
||||||
|
public bool? IsCabac { get; set; }
|
||||||
public bool? IsInterlaced { get; set; }
|
public bool? IsInterlaced { get; set; }
|
||||||
public int? BitDepth { get; set; }
|
public int? BitDepth { get; set; }
|
||||||
public int? RefFrames { get; set; }
|
public int? RefFrames { get; set; }
|
||||||
|
@ -413,6 +413,9 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\Dto\GameSystemSummary.cs">
|
<Compile Include="..\MediaBrowser.Model\Dto\GameSystemSummary.cs">
|
||||||
<Link>Dto\GameSystemSummary.cs</Link>
|
<Link>Dto\GameSystemSummary.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MediaBrowser.Model\Dto\IHasServerId.cs">
|
||||||
|
<Link>Dto\IHasServerId.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dto\IItemDto.cs">
|
<Compile Include="..\MediaBrowser.Model\Dto\IItemDto.cs">
|
||||||
<Link>Dto\IItemDto.cs</Link>
|
<Link>Dto\IItemDto.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -1088,9 +1091,6 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\Users\AuthenticationResult.cs">
|
<Compile Include="..\MediaBrowser.Model\Users\AuthenticationResult.cs">
|
||||||
<Link>Users\AuthenticationResult.cs</Link>
|
<Link>Users\AuthenticationResult.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Weather\WeatherUnits.cs">
|
|
||||||
<Link>Weather\WeatherUnits.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\SharedVersion.cs">
|
<Compile Include="..\SharedVersion.cs">
|
||||||
<Link>Properties\SharedVersion.cs</Link>
|
<Link>Properties\SharedVersion.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -378,6 +378,9 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\Dto\GameSystemSummary.cs">
|
<Compile Include="..\MediaBrowser.Model\Dto\GameSystemSummary.cs">
|
||||||
<Link>Dto\GameSystemSummary.cs</Link>
|
<Link>Dto\GameSystemSummary.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MediaBrowser.Model\Dto\IHasServerId.cs">
|
||||||
|
<Link>Dto\IHasServerId.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dto\IItemDto.cs">
|
<Compile Include="..\MediaBrowser.Model\Dto\IItemDto.cs">
|
||||||
<Link>Dto\IItemDto.cs</Link>
|
<Link>Dto\IItemDto.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -1047,9 +1050,6 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\Users\AuthenticationResult.cs">
|
<Compile Include="..\MediaBrowser.Model\Users\AuthenticationResult.cs">
|
||||||
<Link>Users\AuthenticationResult.cs</Link>
|
<Link>Users\AuthenticationResult.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Weather\WeatherUnits.cs">
|
|
||||||
<Link>Weather\WeatherUnits.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\SharedVersion.cs">
|
<Compile Include="..\SharedVersion.cs">
|
||||||
<Link>Properties\SharedVersion.cs</Link>
|
<Link>Properties\SharedVersion.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -30,7 +30,9 @@ namespace MediaBrowser.Model.ApiClient
|
|||||||
/// Occurs when [connect user sign out].
|
/// Occurs when [connect user sign out].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler<EventArgs> ConnectUserSignOut;
|
event EventHandler<EventArgs> ConnectUserSignOut;
|
||||||
|
[Obsolete]
|
||||||
|
event EventHandler<EventArgs> RemoteLoggedOut;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the connect user.
|
/// Gets the connect user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -41,8 +43,8 @@ namespace MediaBrowser.Model.ApiClient
|
|||||||
/// Gets the API client.
|
/// Gets the API client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <returns>MediaBrowser.Model.ApiClient.IApiClient.</returns>
|
/// <returns>IApiClient.</returns>
|
||||||
IApiClient GetApiClient(BaseItemDto item);
|
IApiClient GetApiClient(IHasServerId item);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connects the specified cancellation token.
|
/// Connects the specified cancellation token.
|
||||||
|
@ -4,5 +4,10 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
public class MetadataConfiguration
|
public class MetadataConfiguration
|
||||||
{
|
{
|
||||||
public bool UseFileCreationTimeForDateAdded { get; set; }
|
public bool UseFileCreationTimeForDateAdded { get; set; }
|
||||||
|
|
||||||
|
public MetadataConfiguration()
|
||||||
|
{
|
||||||
|
UseFileCreationTimeForDateAdded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,8 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
|
|
||||||
public bool SaveMetadataHidden { get; set; }
|
public bool SaveMetadataHidden { get; set; }
|
||||||
|
|
||||||
|
public bool PlaylistImagesDeleted { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -88,6 +88,8 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
|
|
||||||
public AccessSchedule[] AccessSchedules { get; set; }
|
public AccessSchedule[] AccessSchedules { get; set; }
|
||||||
|
|
||||||
|
public bool EnableUserPreferenceAccess { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -112,6 +114,7 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
SyncConnectImage = true;
|
SyncConnectImage = true;
|
||||||
IncludeTrailersInSuggestions = true;
|
IncludeTrailersInSuggestions = true;
|
||||||
EnableCinemaMode = true;
|
EnableCinemaMode = true;
|
||||||
|
EnableUserPreferenceAccess = true;
|
||||||
|
|
||||||
AccessSchedules = new AccessSchedule[] { };
|
AccessSchedules = new AccessSchedule[] { };
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ namespace MediaBrowser.Model.Devices
|
|||||||
public class LocalFileInfo
|
public class LocalFileInfo
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string FullPath { get; set; }
|
public string Id { get; set; }
|
||||||
public string Album { get; set; }
|
public string Album { get; set; }
|
||||||
public string MimeType { get; set; }
|
public string MimeType { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
int? packetLength,
|
int? packetLength,
|
||||||
TransportStreamTimestamp? timestamp,
|
TransportStreamTimestamp? timestamp,
|
||||||
bool? isAnamorphic,
|
bool? isAnamorphic,
|
||||||
|
bool? isCabac,
|
||||||
int? refFrames)
|
int? refFrames)
|
||||||
{
|
{
|
||||||
switch (condition.Property)
|
switch (condition.Property)
|
||||||
@ -31,6 +32,8 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
return true;
|
return true;
|
||||||
case ProfileConditionValue.IsAnamorphic:
|
case ProfileConditionValue.IsAnamorphic:
|
||||||
return IsConditionSatisfied(condition, isAnamorphic);
|
return IsConditionSatisfied(condition, isAnamorphic);
|
||||||
|
case ProfileConditionValue.IsCabac:
|
||||||
|
return IsConditionSatisfied(condition, isCabac);
|
||||||
case ProfileConditionValue.VideoFramerate:
|
case ProfileConditionValue.VideoFramerate:
|
||||||
return IsConditionSatisfied(condition, videoFramerate);
|
return IsConditionSatisfied(condition, videoFramerate);
|
||||||
case ProfileConditionValue.VideoLevel:
|
case ProfileConditionValue.VideoLevel:
|
||||||
|
@ -116,6 +116,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
int? packetLength,
|
int? packetLength,
|
||||||
TranscodeSeekInfo transcodeSeekInfo,
|
TranscodeSeekInfo transcodeSeekInfo,
|
||||||
bool? isAnamorphic,
|
bool? isAnamorphic,
|
||||||
|
bool? isCabac,
|
||||||
int? refFrames)
|
int? refFrames)
|
||||||
{
|
{
|
||||||
// first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
|
// first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
|
||||||
@ -156,6 +157,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
packetLength,
|
packetLength,
|
||||||
timestamp,
|
timestamp,
|
||||||
isAnamorphic,
|
isAnamorphic,
|
||||||
|
isCabac,
|
||||||
refFrames);
|
refFrames);
|
||||||
|
|
||||||
List<string> orgPnValues = new List<string>();
|
List<string> orgPnValues = new List<string>();
|
||||||
|
@ -35,7 +35,9 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
public string ModelUrl { get; set; }
|
public string ModelUrl { get; set; }
|
||||||
public string SerialNumber { get; set; }
|
public string SerialNumber { get; set; }
|
||||||
public bool IgnoreTranscodeByteRangeRequests { get; set; }
|
public bool IgnoreTranscodeByteRangeRequests { get; set; }
|
||||||
|
|
||||||
public bool EnableAlbumArtInDidl { get; set; }
|
public bool EnableAlbumArtInDidl { get; set; }
|
||||||
|
public int? DidlAlbumArtLimit { get; set; }
|
||||||
|
|
||||||
public string SupportedMediaTypes { get; set; }
|
public string SupportedMediaTypes { get; set; }
|
||||||
|
|
||||||
@ -279,6 +281,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
int? packetLength,
|
int? packetLength,
|
||||||
TransportStreamTimestamp timestamp,
|
TransportStreamTimestamp timestamp,
|
||||||
bool? isAnamorphic,
|
bool? isAnamorphic,
|
||||||
|
bool? isCabac,
|
||||||
int? refFrames)
|
int? refFrames)
|
||||||
{
|
{
|
||||||
container = StringHelper.TrimStart((container ?? string.Empty), '.');
|
container = StringHelper.TrimStart((container ?? string.Empty), '.');
|
||||||
@ -313,7 +316,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
var anyOff = false;
|
var anyOff = false;
|
||||||
foreach (ProfileCondition c in i.Conditions)
|
foreach (ProfileCondition c in i.Conditions)
|
||||||
{
|
{
|
||||||
if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames))
|
if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
|
||||||
{
|
{
|
||||||
anyOff = true;
|
anyOff = true;
|
||||||
break;
|
break;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
VideoProfile = 11,
|
VideoProfile = 11,
|
||||||
VideoTimestamp = 12,
|
VideoTimestamp = 12,
|
||||||
IsAnamorphic = 13,
|
IsAnamorphic = 13,
|
||||||
RefFrames = 14
|
RefFrames = 14,
|
||||||
|
IsCabac = 15
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,8 +6,14 @@ namespace MediaBrowser.Model.Dlna.Profiles
|
|||||||
[XmlRoot("Profile")]
|
[XmlRoot("Profile")]
|
||||||
public class AndroidProfile : DefaultProfile
|
public class AndroidProfile : DefaultProfile
|
||||||
{
|
{
|
||||||
public AndroidProfile(bool supportsHls,
|
public AndroidProfile()
|
||||||
bool supportsMpegDash,
|
: this(true, true, new[] { "baseline", "constrained baseline" })
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AndroidProfile(bool supportsHls,
|
||||||
|
bool supportsMpegDash,
|
||||||
string[] supportedH264Profiles)
|
string[] supportedH264Profiles)
|
||||||
{
|
{
|
||||||
Name = "Android";
|
Name = "Android";
|
||||||
@ -108,7 +114,8 @@ namespace MediaBrowser.Model.Dlna.Profiles
|
|||||||
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Width, "1920"),
|
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Width, "1920"),
|
||||||
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Height, "1080"),
|
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Height, "1080"),
|
||||||
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoBitDepth, "8"),
|
new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoBitDepth, "8"),
|
||||||
new ProfileCondition(ProfileConditionType.NotEquals, ProfileConditionValue.IsAnamorphic, "true")
|
new ProfileCondition(ProfileConditionType.NotEquals, ProfileConditionValue.IsAnamorphic, "true"),
|
||||||
|
new ProfileCondition(ProfileConditionType.Equals, ProfileConditionValue.IsCabac, "true")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -419,6 +419,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
string videoProfile = videoStream == null ? null : videoStream.Profile;
|
string videoProfile = videoStream == null ? null : videoStream.Profile;
|
||||||
float? videoFramerate = videoStream == null ? null : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate;
|
float? videoFramerate = videoStream == null ? null : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate;
|
||||||
bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic;
|
bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic;
|
||||||
|
bool? isCabac = videoStream == null ? null : videoStream.IsCabac;
|
||||||
|
|
||||||
int? audioBitrate = audioStream == null ? null : audioStream.BitRate;
|
int? audioBitrate = audioStream == null ? null : audioStream.BitRate;
|
||||||
int? audioChannels = audioStream == null ? null : audioStream.Channels;
|
int? audioChannels = audioStream == null ? null : audioStream.Channels;
|
||||||
@ -431,7 +432,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
// Check container conditions
|
// Check container conditions
|
||||||
foreach (ProfileCondition i in conditions)
|
foreach (ProfileCondition i in conditions)
|
||||||
{
|
{
|
||||||
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames))
|
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -458,7 +459,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
|
|
||||||
foreach (ProfileCondition i in conditions)
|
foreach (ProfileCondition i in conditions)
|
||||||
{
|
{
|
||||||
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames))
|
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -647,6 +648,7 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
}
|
}
|
||||||
case ProfileConditionValue.AudioProfile:
|
case ProfileConditionValue.AudioProfile:
|
||||||
case ProfileConditionValue.IsAnamorphic:
|
case ProfileConditionValue.IsAnamorphic:
|
||||||
|
case ProfileConditionValue.IsCabac:
|
||||||
case ProfileConditionValue.Has64BitOffsets:
|
case ProfileConditionValue.Has64BitOffsets:
|
||||||
case ProfileConditionValue.PacketLength:
|
case ProfileConditionValue.PacketLength:
|
||||||
case ProfileConditionValue.VideoTimestamp:
|
case ProfileConditionValue.VideoTimestamp:
|
||||||
|
@ -456,6 +456,19 @@ namespace MediaBrowser.Model.Dlna
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool? IsTargetCabac
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsDirectStream)
|
||||||
|
{
|
||||||
|
return TargetVideoStream == null ? null : TargetVideoStream.IsCabac;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int? TargetWidth
|
public int? TargetWidth
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -16,7 +16,7 @@ namespace MediaBrowser.Model.Dto
|
|||||||
/// This holds information about a BaseItem in a format that is convenient for the client.
|
/// This holds information about a BaseItem in a format that is convenient for the client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerDisplay("Name = {Name}, ID = {Id}, Type = {Type}")]
|
[DebuggerDisplay("Name = {Name}, ID = {Id}, Type = {Type}")]
|
||||||
public class BaseItemDto : IHasProviderIds, IHasPropertyChangedEvent, IItemDto
|
public class BaseItemDto : IHasProviderIds, IHasPropertyChangedEvent, IItemDto, IHasServerId
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name.
|
/// Gets or sets the name.
|
||||||
@ -24,6 +24,12 @@ namespace MediaBrowser.Model.Dto
|
|||||||
/// <value>The name.</value>
|
/// <value>The name.</value>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the server identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The server identifier.</value>
|
||||||
|
public string ServerId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the id.
|
/// Gets or sets the id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -43,7 +49,8 @@ namespace MediaBrowser.Model.Dto
|
|||||||
public DateTime? DateCreated { get; set; }
|
public DateTime? DateCreated { get; set; }
|
||||||
|
|
||||||
public DateTime? DateLastMediaAdded { get; set; }
|
public DateTime? DateLastMediaAdded { get; set; }
|
||||||
|
public ExtraType? ExtraType { get; set; }
|
||||||
|
|
||||||
public int? AirsBeforeSeasonNumber { get; set; }
|
public int? AirsBeforeSeasonNumber { get; set; }
|
||||||
public int? AirsAfterSeasonNumber { get; set; }
|
public int? AirsAfterSeasonNumber { get; set; }
|
||||||
public int? AirsBeforeEpisodeNumber { get; set; }
|
public int? AirsBeforeEpisodeNumber { get; set; }
|
||||||
|
8
MediaBrowser.Model/Dto/IHasServerId.cs
Normal file
8
MediaBrowser.Model/Dto/IHasServerId.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
namespace MediaBrowser.Model.Dto
|
||||||
|
{
|
||||||
|
public interface IHasServerId
|
||||||
|
{
|
||||||
|
string ServerId { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Dto
|
|||||||
/// Class UserDto
|
/// Class UserDto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerDisplay("Name = {Name}, ID = {Id}, HasPassword = {HasPassword}")]
|
[DebuggerDisplay("Name = {Name}, ID = {Id}, HasPassword = {HasPassword}")]
|
||||||
public class UserDto : IHasPropertyChangedEvent, IItemDto
|
public class UserDto : IHasPropertyChangedEvent, IItemDto, IHasServerId
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name.
|
/// Gets or sets the name.
|
||||||
@ -20,6 +20,12 @@ namespace MediaBrowser.Model.Dto
|
|||||||
/// <value>The name.</value>
|
/// <value>The name.</value>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the server identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The server identifier.</value>
|
||||||
|
public string ServerId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name of the connect user.
|
/// Gets or sets the name of the connect user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -175,5 +175,11 @@ namespace MediaBrowser.Model.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if this instance is anamorphic; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if this instance is anamorphic; otherwise, <c>false</c>.</value>
|
||||||
public bool? IsAnamorphic { get; set; }
|
public bool? IsAnamorphic { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this instance is cabac.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>null</c> if [is cabac] contains no value, <c>true</c> if [is cabac]; otherwise, <c>false</c>.</value>
|
||||||
|
public bool? IsCabac { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,7 @@
|
|||||||
<Compile Include="Dlna\SubtitleDeliveryMethod.cs" />
|
<Compile Include="Dlna\SubtitleDeliveryMethod.cs" />
|
||||||
<Compile Include="Dlna\SubtitleStreamInfo.cs" />
|
<Compile Include="Dlna\SubtitleStreamInfo.cs" />
|
||||||
<Compile Include="Drawing\ImageOrientation.cs" />
|
<Compile Include="Drawing\ImageOrientation.cs" />
|
||||||
|
<Compile Include="Dto\IHasServerId.cs" />
|
||||||
<Compile Include="Dto\MediaSourceType.cs" />
|
<Compile Include="Dto\MediaSourceType.cs" />
|
||||||
<Compile Include="Dto\StreamOptions.cs" />
|
<Compile Include="Dto\StreamOptions.cs" />
|
||||||
<Compile Include="Dto\VideoStreamOptions.cs" />
|
<Compile Include="Dto\VideoStreamOptions.cs" />
|
||||||
@ -402,7 +403,6 @@
|
|||||||
<Compile Include="Updates\PackageInfo.cs" />
|
<Compile Include="Updates\PackageInfo.cs" />
|
||||||
<Compile Include="Updates\PackageVersionInfo.cs" />
|
<Compile Include="Updates\PackageVersionInfo.cs" />
|
||||||
<Compile Include="Users\AuthenticationResult.cs" />
|
<Compile Include="Users\AuthenticationResult.cs" />
|
||||||
<Compile Include="Weather\WeatherUnits.cs" />
|
|
||||||
<None Include="Fody.targets" />
|
<None Include="Fody.targets" />
|
||||||
<None Include="FodyWeavers.xml" />
|
<None Include="FodyWeavers.xml" />
|
||||||
<None Include="MediaBrowser.Model.snk" />
|
<None Include="MediaBrowser.Model.snk" />
|
||||||
|
@ -5,26 +5,7 @@ namespace MediaBrowser.Model.Querying
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the result of a query for items
|
/// Represents the result of a query for items
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ItemsResult
|
public class ItemsResult : QueryResult<BaseItemDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The set of items returned based on sorting, paging, etc
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The items.</value>
|
|
||||||
public BaseItemDto[] Items { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The total number of records available
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The total record count.</value>
|
|
||||||
public int TotalRecordCount { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ItemsResult"/> class.
|
|
||||||
/// </summary>
|
|
||||||
public ItemsResult()
|
|
||||||
{
|
|
||||||
Items = new BaseItemDto[] { };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
namespace MediaBrowser.Model.Weather
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Enum WeatherUnits
|
|
||||||
/// </summary>
|
|
||||||
public enum WeatherUnits
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The fahrenheit
|
|
||||||
/// </summary>
|
|
||||||
Fahrenheit,
|
|
||||||
/// <summary>
|
|
||||||
/// The celsius
|
|
||||||
/// </summary>
|
|
||||||
Celsius
|
|
||||||
}
|
|
||||||
}
|
|
@ -286,6 +286,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
{
|
{
|
||||||
var result = new MediaInfoLib().GetVideoInfo(video.Path);
|
var result = new MediaInfoLib().GetVideoInfo(video.Path);
|
||||||
|
|
||||||
|
videoStream.IsCabac = result.IsCabac ?? videoStream.IsCabac;
|
||||||
videoStream.IsInterlaced = result.IsInterlaced ?? videoStream.IsInterlaced;
|
videoStream.IsInterlaced = result.IsInterlaced ?? videoStream.IsInterlaced;
|
||||||
videoStream.BitDepth = result.BitDepth ?? videoStream.BitDepth;
|
videoStream.BitDepth = result.BitDepth ?? videoStream.BitDepth;
|
||||||
videoStream.RefFrames = result.RefFrames;
|
videoStream.RefFrames = result.RefFrames;
|
||||||
|
@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
{
|
{
|
||||||
class FanartMovieUpdatesPostScanTask : ILibraryPostScanTask
|
class FanartMovieUpdatesPostScanTask : ILibraryPostScanTask
|
||||||
{
|
{
|
||||||
private const string UpdatesUrl = "http://api.fanart.tv/webservice/newmovies/{0}/{1}/";
|
private const string UpdatesUrl = "http://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _HTTP client
|
/// The _HTTP client
|
||||||
@ -118,11 +118,26 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var updates = _jsonSerializer.DeserializeFromString<List<FanartUpdatesPostScanTask.FanArtUpdate>>(json);
|
var updates = _jsonSerializer.DeserializeFromString<List<RootObject>>(json);
|
||||||
|
|
||||||
var existingDictionary = existingIds.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
var existingDictionary = existingIds.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
return updates.Select(i => i.id).Where(existingDictionary.ContainsKey);
|
return updates.SelectMany(i =>
|
||||||
|
{
|
||||||
|
var list = new List<string>();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(i.imdb_id))
|
||||||
|
{
|
||||||
|
list.Add(i.imdb_id);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(i.tmdb_id))
|
||||||
|
{
|
||||||
|
list.Add(i.tmdb_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
|
||||||
|
}).Where(existingDictionary.ContainsKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +151,7 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
{
|
{
|
||||||
_logger.Info("Updating movie " + id);
|
_logger.Info("Updating movie " + id);
|
||||||
|
|
||||||
await FanartMovieImageProvider.Current.DownloadMovieXml(id, cancellationToken).ConfigureAwait(false);
|
await FanartMovieImageProvider.Current.DownloadMovieJson(id, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
double percent = numComplete;
|
double percent = numComplete;
|
||||||
@ -157,9 +172,10 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
return (dateTime - new DateTime(1970, 1, 1).ToUniversalTime()).TotalSeconds;
|
return (dateTime - new DateTime(1970, 1, 1).ToUniversalTime()).TotalSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FanArtUpdate
|
public class RootObject
|
||||||
{
|
{
|
||||||
public string id { get; set; }
|
public string tmdb_id { get; set; }
|
||||||
|
public string imdb_id { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string new_images { get; set; }
|
public string new_images { get; set; }
|
||||||
public string total_images { get; set; }
|
public string total_images { get; set; }
|
||||||
|
@ -1,25 +1,22 @@
|
|||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Channels;
|
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Channels;
|
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Providers.Music;
|
using MediaBrowser.Providers.Music;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Movies
|
namespace MediaBrowser.Providers.Movies
|
||||||
{
|
{
|
||||||
@ -29,16 +26,19 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
private readonly IJsonSerializer _json;
|
||||||
|
|
||||||
private const string FanArtBaseUrl = "http://api.fanart.tv/webservice/movie/{0}/{1}/xml/all/1/1";
|
private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3/movies/{1}?api_key={0}";
|
||||||
|
// &client_key=52c813aa7b8c8b3bb87f4797532a2f8c
|
||||||
|
|
||||||
internal static FanartMovieImageProvider Current;
|
internal static FanartMovieImageProvider Current;
|
||||||
|
|
||||||
public FanartMovieImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
|
public FanartMovieImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
_json = json;
|
||||||
|
|
||||||
Current = this;
|
Current = this;
|
||||||
}
|
}
|
||||||
@ -88,13 +88,13 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(movieId))
|
if (!string.IsNullOrEmpty(movieId))
|
||||||
{
|
{
|
||||||
await EnsureMovieXml(movieId, cancellationToken).ConfigureAwait(false);
|
await EnsureMovieJson(movieId, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var xmlPath = GetFanartXmlPath(movieId);
|
var path = GetFanartJsonPath(movieId);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AddImages(list, xmlPath, cancellationToken);
|
AddImages(list, path, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
@ -130,198 +130,63 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
.ThenByDescending(i => i.CommunityRating ?? 0);
|
.ThenByDescending(i => i.CommunityRating ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddImages(List<RemoteImageInfo> list, string xmlPath, CancellationToken cancellationToken)
|
private void AddImages(List<RemoteImageInfo> list, string path, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
|
var root = _json.DeserializeFromFile<RootObject>(path);
|
||||||
{
|
|
||||||
// Use XmlReader for best performance
|
|
||||||
using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
|
|
||||||
{
|
|
||||||
CheckCharacters = false,
|
|
||||||
IgnoreProcessingInstructions = true,
|
|
||||||
IgnoreComments = true,
|
|
||||||
ValidationType = ValidationType.None
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
reader.MoveToContent();
|
|
||||||
|
|
||||||
// Loop through each element
|
AddImages(list, root, cancellationToken);
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
if (reader.NodeType == XmlNodeType.Element)
|
|
||||||
{
|
|
||||||
switch (reader.Name)
|
|
||||||
{
|
|
||||||
case "movie":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
AddImages(list, subReader, cancellationToken);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
reader.Skip();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddImages(List<RemoteImageInfo> list, XmlReader reader, CancellationToken cancellationToken)
|
private void AddImages(List<RemoteImageInfo> list, RootObject obj, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
reader.MoveToContent();
|
PopulateImages(list, obj.hdmovieclearart, ImageType.Art, 1000, 562);
|
||||||
|
PopulateImages(list, obj.hdmovielogo, ImageType.Logo, 800, 310);
|
||||||
while (reader.Read())
|
PopulateImages(list, obj.moviedisc, ImageType.Disc, 1000, 1000);
|
||||||
{
|
PopulateImages(list, obj.movieposter, ImageType.Primary, 1000, 1426);
|
||||||
if (reader.NodeType == XmlNodeType.Element)
|
PopulateImages(list, obj.movielogo, ImageType.Logo, 400, 155);
|
||||||
{
|
PopulateImages(list, obj.movieart, ImageType.Art, 500, 281);
|
||||||
switch (reader.Name)
|
PopulateImages(list, obj.moviethumb, ImageType.Thumb, 1000, 562);
|
||||||
{
|
PopulateImages(list, obj.moviebanner, ImageType.Banner, 1000, 185);
|
||||||
case "hdmoviecleararts":
|
PopulateImages(list, obj.moviebackground, ImageType.Backdrop, 1920, 1080);
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Art, 1000, 562);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "hdmovielogos":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Logo, 800, 310);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "moviediscs":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Disc, 1000, 1000);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "movieposters":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Primary, 1000, 1426);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "movielogos":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Logo, 400, 155);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "moviearts":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Art, 500, 281);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "moviethumbs":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 1000, 562);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "moviebanners":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Banner, 1000, 185);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "moviebackgrounds":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Backdrop, 1920, 1080);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
using (reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateImageCategory(List<RemoteImageInfo> list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height)
|
private void PopulateImages(List<RemoteImageInfo> list, List<Image> images, ImageType type, int width, int height)
|
||||||
{
|
{
|
||||||
reader.MoveToContent();
|
if (images == null)
|
||||||
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
return;
|
||||||
|
|
||||||
if (reader.NodeType == XmlNodeType.Element)
|
|
||||||
{
|
|
||||||
switch (reader.Name)
|
|
||||||
{
|
|
||||||
case "hdmovielogo":
|
|
||||||
case "moviedisc":
|
|
||||||
case "hdmovieclearart":
|
|
||||||
case "movieposter":
|
|
||||||
case "movielogo":
|
|
||||||
case "movieart":
|
|
||||||
case "moviethumb":
|
|
||||||
case "moviebanner":
|
|
||||||
case "moviebackground":
|
|
||||||
{
|
|
||||||
var url = reader.GetAttribute("url");
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(url))
|
|
||||||
{
|
|
||||||
var likesString = reader.GetAttribute("likes");
|
|
||||||
int likes;
|
|
||||||
|
|
||||||
var info = new RemoteImageInfo
|
|
||||||
{
|
|
||||||
RatingType = RatingType.Likes,
|
|
||||||
Type = type,
|
|
||||||
Width = width,
|
|
||||||
Height = height,
|
|
||||||
ProviderName = Name,
|
|
||||||
Url = url,
|
|
||||||
Language = reader.GetAttribute("lang")
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
|
|
||||||
{
|
|
||||||
info.CommunityRating = likes;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.Add(info);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
reader.Skip();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list.AddRange(images.Select(i =>
|
||||||
|
{
|
||||||
|
var url = i.url;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(url))
|
||||||
|
{
|
||||||
|
var likesString = i.likes;
|
||||||
|
int likes;
|
||||||
|
|
||||||
|
var info = new RemoteImageInfo
|
||||||
|
{
|
||||||
|
RatingType = RatingType.Likes,
|
||||||
|
Type = type,
|
||||||
|
Width = width,
|
||||||
|
Height = height,
|
||||||
|
ProviderName = Name,
|
||||||
|
Url = url,
|
||||||
|
Language = i.lang
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
|
||||||
|
{
|
||||||
|
info.CommunityRating = likes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}).Where(i => i != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order
|
public int Order
|
||||||
@ -347,13 +212,17 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
}
|
}
|
||||||
|
|
||||||
var id = item.GetProviderId(MetadataProviders.Tmdb);
|
var id = item.GetProviderId(MetadataProviders.Tmdb);
|
||||||
|
if (string.IsNullOrEmpty(id))
|
||||||
|
{
|
||||||
|
id = item.GetProviderId(MetadataProviders.Imdb);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(id))
|
if (!string.IsNullOrEmpty(id))
|
||||||
{
|
{
|
||||||
// Process images
|
// Process images
|
||||||
var xmlPath = GetFanartXmlPath(id);
|
var path = GetFanartJsonPath(id);
|
||||||
|
|
||||||
var fileInfo = new FileInfo(xmlPath);
|
var fileInfo = new FileInfo(path);
|
||||||
|
|
||||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
|
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
|
||||||
}
|
}
|
||||||
@ -364,12 +233,12 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the movie data path.
|
/// Gets the movie data path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="appPaths">The app paths.</param>
|
/// <param name="appPaths">The application paths.</param>
|
||||||
/// <param name="tmdbId">The TMDB id.</param>
|
/// <param name="id">The identifier.</param>
|
||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
internal static string GetMovieDataPath(IApplicationPaths appPaths, string tmdbId)
|
internal static string GetMovieDataPath(IApplicationPaths appPaths, string id)
|
||||||
{
|
{
|
||||||
var dataPath = Path.Combine(GetMoviesDataPath(appPaths), tmdbId);
|
var dataPath = Path.Combine(GetMoviesDataPath(appPaths), id);
|
||||||
|
|
||||||
return dataPath;
|
return dataPath;
|
||||||
}
|
}
|
||||||
@ -386,27 +255,27 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
return dataPath;
|
return dataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFanartXmlPath(string tmdbId)
|
public string GetFanartJsonPath(string id)
|
||||||
{
|
{
|
||||||
var movieDataPath = GetMovieDataPath(_config.ApplicationPaths, tmdbId);
|
var movieDataPath = GetMovieDataPath(_config.ApplicationPaths, id);
|
||||||
return Path.Combine(movieDataPath, "fanart.xml");
|
return Path.Combine(movieDataPath, "fanart.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Downloads the movie XML.
|
/// Downloads the movie json.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tmdbId">The TMDB id.</param>
|
/// <param name="id">The identifier.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
internal async Task DownloadMovieXml(string tmdbId, CancellationToken cancellationToken)
|
internal async Task DownloadMovieJson(string id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, tmdbId);
|
var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, id);
|
||||||
|
|
||||||
var xmlPath = GetFanartXmlPath(tmdbId);
|
var path = GetFanartJsonPath(id);
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(xmlPath));
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
|
|
||||||
using (var response = await _httpClient.Get(new HttpRequestOptions
|
using (var response = await _httpClient.Get(new HttpRequestOptions
|
||||||
{
|
{
|
||||||
@ -416,17 +285,17 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
|
|
||||||
}).ConfigureAwait(false))
|
}).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
using (var xmlFileStream = _fileSystem.GetFileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||||
{
|
{
|
||||||
await response.CopyToAsync(xmlFileStream).ConfigureAwait(false);
|
await response.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Task _cachedTask = Task.FromResult(true);
|
private readonly Task _cachedTask = Task.FromResult(true);
|
||||||
internal Task EnsureMovieXml(string tmdbId, CancellationToken cancellationToken)
|
internal Task EnsureMovieJson(string id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var path = GetFanartXmlPath(tmdbId);
|
var path = GetFanartJsonPath(id);
|
||||||
|
|
||||||
var fileInfo = _fileSystem.GetFileSystemInfo(path);
|
var fileInfo = _fileSystem.GetFileSystemInfo(path);
|
||||||
|
|
||||||
@ -438,7 +307,31 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DownloadMovieXml(tmdbId, cancellationToken);
|
return DownloadMovieJson(id, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Image
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public string url { get; set; }
|
||||||
|
public string lang { get; set; }
|
||||||
|
public string likes { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RootObject
|
||||||
|
{
|
||||||
|
public string name { get; set; }
|
||||||
|
public string tmdb_id { get; set; }
|
||||||
|
public string imdb_id { get; set; }
|
||||||
|
public List<Image> hdmovielogo { get; set; }
|
||||||
|
public List<Image> moviedisc { get; set; }
|
||||||
|
public List<Image> movielogo { get; set; }
|
||||||
|
public List<Image> movieposter { get; set; }
|
||||||
|
public List<Image> hdmovieclearart { get; set; }
|
||||||
|
public List<Image> movieart { get; set; }
|
||||||
|
public List<Image> moviebackground { get; set; }
|
||||||
|
public List<Image> moviebanner { get; set; }
|
||||||
|
public List<Image> moviethumb { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Providers.Manager;
|
using MediaBrowser.Providers.Manager;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Music
|
namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
@ -36,9 +34,9 @@ namespace MediaBrowser.Providers.Music
|
|||||||
target.Album = source.Album;
|
target.Album = source.Album;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replaceData || string.IsNullOrEmpty(target.Artist))
|
if (replaceData || target.Artists.Count == 0)
|
||||||
{
|
{
|
||||||
target.Artist = source.Artist;
|
target.Artists = source.Artists.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,15 @@ using MediaBrowser.Controller.Providers;
|
|||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Providers.Music;
|
using MediaBrowser.Providers.Music;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.TV
|
namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
@ -26,12 +25,14 @@ namespace MediaBrowser.Providers.TV
|
|||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
private readonly IJsonSerializer _json;
|
||||||
|
|
||||||
public FanArtSeasonProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
|
public FanArtSeasonProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
_json = json;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
@ -71,14 +72,14 @@ namespace MediaBrowser.Providers.TV
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(id) && season.IndexNumber.HasValue)
|
if (!string.IsNullOrEmpty(id) && season.IndexNumber.HasValue)
|
||||||
{
|
{
|
||||||
await FanartSeriesProvider.Current.EnsureSeriesXml(id, cancellationToken).ConfigureAwait(false);
|
await FanartSeriesProvider.Current.EnsureSeriesJson(id, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var xmlPath = FanartSeriesProvider.Current.GetFanartXmlPath(id);
|
var path = FanartSeriesProvider.Current.GetFanartJsonPath(id);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int seasonNumber = AdjustForSeriesOffset(series, season.IndexNumber.Value);
|
int seasonNumber = AdjustForSeriesOffset(series, season.IndexNumber.Value);
|
||||||
AddImages(list, seasonNumber, xmlPath, cancellationToken);
|
AddImages(list, seasonNumber, path, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
@ -125,142 +126,67 @@ namespace MediaBrowser.Providers.TV
|
|||||||
return seasonNumber;
|
return seasonNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddImages(List<RemoteImageInfo> list, int seasonNumber, string xmlPath, CancellationToken cancellationToken)
|
private void AddImages(List<RemoteImageInfo> list, int seasonNumber, string path, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
|
var root = _json.DeserializeFromFile<FanartSeriesProvider.RootObject>(path);
|
||||||
{
|
|
||||||
// Use XmlReader for best performance
|
|
||||||
using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
|
|
||||||
{
|
|
||||||
CheckCharacters = false,
|
|
||||||
IgnoreProcessingInstructions = true,
|
|
||||||
IgnoreComments = true,
|
|
||||||
ValidationType = ValidationType.None
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
reader.MoveToContent();
|
|
||||||
|
|
||||||
// Loop through each element
|
AddImages(list, root, seasonNumber, cancellationToken);
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
if (reader.NodeType == XmlNodeType.Element)
|
|
||||||
{
|
|
||||||
switch (reader.Name)
|
|
||||||
{
|
|
||||||
case "series":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
AddImages(list, subReader, seasonNumber, cancellationToken);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
reader.Skip();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddImages(List<RemoteImageInfo> list, XmlReader reader, int seasonNumber, CancellationToken cancellationToken)
|
private void AddImages(List<RemoteImageInfo> list, FanartSeriesProvider.RootObject obj, int seasonNumber, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
reader.MoveToContent();
|
PopulateImages(list, obj.seasonthumb, ImageType.Thumb, 500, 281, seasonNumber);
|
||||||
|
PopulateImages(list, obj.showbackground, ImageType.Backdrop, 1920, 1080, seasonNumber);
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
if (reader.NodeType == XmlNodeType.Element)
|
|
||||||
{
|
|
||||||
switch (reader.Name)
|
|
||||||
{
|
|
||||||
case "seasonthumbs":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 500, 281, seasonNumber);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "showbackgrounds":
|
|
||||||
{
|
|
||||||
using (var subReader = reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
PopulateImageCategory(list, subReader, cancellationToken, ImageType.Backdrop, 1920, 1080, seasonNumber);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
using (reader.ReadSubtree())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateImageCategory(List<RemoteImageInfo> list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height, int seasonNumber)
|
private void PopulateImages(List<RemoteImageInfo> list,
|
||||||
|
List<FanartSeriesProvider.Image> images,
|
||||||
|
ImageType type,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int seasonNumber)
|
||||||
{
|
{
|
||||||
reader.MoveToContent();
|
if (images == null)
|
||||||
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
return;
|
||||||
|
|
||||||
if (reader.NodeType == XmlNodeType.Element)
|
|
||||||
{
|
|
||||||
switch (reader.Name)
|
|
||||||
{
|
|
||||||
case "seasonthumb":
|
|
||||||
case "showbackground":
|
|
||||||
{
|
|
||||||
var url = reader.GetAttribute("url");
|
|
||||||
var season = reader.GetAttribute("season");
|
|
||||||
|
|
||||||
int imageSeasonNumber;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(url) &&
|
|
||||||
!string.IsNullOrEmpty(season) &&
|
|
||||||
int.TryParse(season, NumberStyles.Any, _usCulture, out imageSeasonNumber) &&
|
|
||||||
seasonNumber == imageSeasonNumber)
|
|
||||||
{
|
|
||||||
var likesString = reader.GetAttribute("likes");
|
|
||||||
int likes;
|
|
||||||
|
|
||||||
var info = new RemoteImageInfo
|
|
||||||
{
|
|
||||||
RatingType = RatingType.Likes,
|
|
||||||
Type = type,
|
|
||||||
Width = width,
|
|
||||||
Height = height,
|
|
||||||
ProviderName = Name,
|
|
||||||
Url = url,
|
|
||||||
Language = reader.GetAttribute("lang")
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
|
|
||||||
{
|
|
||||||
info.CommunityRating = likes;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.Add(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
reader.Skip();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list.AddRange(images.Select(i =>
|
||||||
|
{
|
||||||
|
var url = i.url;
|
||||||
|
var season = i.season;
|
||||||
|
|
||||||
|
int imageSeasonNumber;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(url) &&
|
||||||
|
!string.IsNullOrEmpty(season) &&
|
||||||
|
int.TryParse(season, NumberStyles.Any, _usCulture, out imageSeasonNumber) &&
|
||||||
|
seasonNumber == imageSeasonNumber)
|
||||||
|
{
|
||||||
|
var likesString = i.likes;
|
||||||
|
int likes;
|
||||||
|
|
||||||
|
var info = new RemoteImageInfo
|
||||||
|
{
|
||||||
|
RatingType = RatingType.Likes,
|
||||||
|
Type = type,
|
||||||
|
Width = width,
|
||||||
|
Height = height,
|
||||||
|
ProviderName = Name,
|
||||||
|
Url = url,
|
||||||
|
Language = i.lang
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
|
||||||
|
{
|
||||||
|
info.CommunityRating = likes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}).Where(i => i != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order
|
public int Order
|
||||||
@ -298,9 +224,9 @@ namespace MediaBrowser.Providers.TV
|
|||||||
if (!String.IsNullOrEmpty(tvdbId))
|
if (!String.IsNullOrEmpty(tvdbId))
|
||||||
{
|
{
|
||||||
// Process images
|
// Process images
|
||||||
var imagesXmlPath = FanartSeriesProvider.Current.GetFanartXmlPath(tvdbId);
|
var imagesFilePath = FanartSeriesProvider.Current.GetFanartJsonPath(tvdbId);
|
||||||
|
|
||||||
var fileInfo = new FileInfo(imagesXmlPath);
|
var fileInfo = new FileInfo(imagesFilePath);
|
||||||
|
|
||||||
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
|
return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user