diff --git a/Emby.Dlna/Api/DlnaServerService.cs b/Emby.Dlna/Api/DlnaServerService.cs index d3585bcc75..1551ba72dc 100644 --- a/Emby.Dlna/Api/DlnaServerService.cs +++ b/Emby.Dlna/Api/DlnaServerService.cs @@ -114,18 +114,16 @@ public class DlnaServerService : IService, IRequiresRequest private readonly IMediaReceiverRegistrar _mediaReceiverRegistrar; private const string XMLContentType = "text/xml; charset=UTF-8"; - private readonly IMemoryStreamFactory _memoryStreamProvider; public IRequest Request { get; set; } private IHttpResultFactory _resultFactory; - public DlnaServerService(IDlnaManager dlnaManager, IHttpResultFactory httpResultFactory, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar, IMemoryStreamFactory memoryStreamProvider) + public DlnaServerService(IDlnaManager dlnaManager, IHttpResultFactory httpResultFactory, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar) { _dlnaManager = dlnaManager; _contentDirectory = contentDirectory; _connectionManager = connectionManager; _mediaReceiverRegistrar = mediaReceiverRegistrar; - _memoryStreamProvider = memoryStreamProvider; _resultFactory = httpResultFactory; } @@ -236,24 +234,12 @@ private List Parse(string pathUri) public object Get(GetIcon request) { - using (var response = _dlnaManager.GetIcon(request.Filename)) - { - using (var ms = new MemoryStream()) - { - response.Stream.CopyTo(ms); - - ms.Position = 0; - var bytes = ms.ToArray(); - - var contentType = "image/" + response.Format.ToString().ToLower(); + var contentType = "image/" + Path.GetExtension(request.Filename).TrimStart('.').ToLower(); - var cacheLength = TimeSpan.FromDays(365); - var cacheKey = Request.RawUrl.GetMD5(); + var cacheLength = TimeSpan.FromDays(365); + var cacheKey = Request.RawUrl.GetMD5(); - return _resultFactory.GetStaticResult(Request, cacheKey, null, cacheLength, contentType, ()=> Task.FromResult(new MemoryStream(bytes))); - //return ResultFactory.GetResult(bytes, contentType); - } - } + return _resultFactory.GetStaticResult(Request, cacheKey, null, cacheLength, contentType, () => Task.FromResult(_dlnaManager.GetIcon(request.Filename).Stream)); } public object Subscribe(ProcessContentDirectoryEventRequest request) diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index e961184f9d..85bf0e40d9 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -1214,7 +1214,7 @@ private ImageUrlInfo GetImageUrl(ImageDownloadInfo info, int maxWidth, int maxHe Height = height.Value, Width = width.Value - }, null, null, maxWidth, maxHeight); + }, 0, 0, maxWidth, maxHeight); width = Convert.ToInt32(newSize.Width); height = Convert.ToInt32(newSize.Height); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 32888d0f81..153e8e0734 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -59,6 +59,7 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; @@ -269,7 +270,6 @@ public virtual string OperatingSystemDisplayName protected readonly SimpleInjector.Container Container = new SimpleInjector.Container(); protected ISystemEvents SystemEvents { get; set; } - protected IMemoryStreamFactory MemoryStreamFactory { get; set; } /// /// Gets the server configuration manager. @@ -429,7 +429,6 @@ public ApplicationHost(ServerApplicationPaths applicationPaths, networkManager.LocalSubnetsFn = GetConfiguredLocalSubnets; EnvironmentInfo = environmentInfo; SystemEvents = systemEvents; - MemoryStreamFactory = new MemoryStreamProvider(); ApplicationPaths = applicationPaths; LogManager = logManager; @@ -526,6 +525,11 @@ private Tuple GetAssembly(Type type) return new Tuple(assembly, path); } + public virtual IStreamHelper CreateStreamHelper() + { + return new StreamHelper(); + } + public virtual bool SupportsAutoRunAtStartup { get @@ -859,9 +863,11 @@ protected virtual void OnLoggerLoaded(bool isFirstLoad) protected virtual IHttpClient CreateHttpClient() { - return new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamFactory, GetDefaultUserAgent); + return new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, GetDefaultUserAgent); } + public static IStreamHelper StreamHelper { get; set; } + /// /// Registers resources that classes will depend on /// @@ -873,7 +879,6 @@ protected void RegisterResources() RegisterSingleInstance(ApplicationPaths); RegisterSingleInstance(JsonSerializer); - RegisterSingleInstance(MemoryStreamFactory); RegisterSingleInstance(SystemEvents); RegisterSingleInstance(LogManager, false); @@ -902,6 +907,10 @@ protected void RegisterResources() TimerFactory = new TimerFactory(); RegisterSingleInstance(TimerFactory); + var streamHelper = CreateStreamHelper(); + ApplicationHost.StreamHelper = streamHelper; + RegisterSingleInstance(streamHelper); + RegisterSingleInstance(CryptographyProvider); SocketFactory = new SocketFactory(LogManager.GetLogger("SocketFactory")); @@ -918,7 +927,7 @@ protected void RegisterResources() ZipClient = new ZipClient(FileSystemManager); RegisterSingleInstance(ZipClient); - HttpResultFactory = new HttpResultFactory(LogManager, FileSystemManager, JsonSerializer, MemoryStreamFactory); + HttpResultFactory = new HttpResultFactory(LogManager, FileSystemManager, JsonSerializer); RegisterSingleInstance(HttpResultFactory); RegisterSingleInstance(this); @@ -947,11 +956,11 @@ protected void RegisterResources() // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it RegisterSingleInstance(UserRepository); - var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager.GetLogger("SqliteDisplayPreferencesRepository"), JsonSerializer, ApplicationPaths, MemoryStreamFactory, FileSystemManager); + var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager.GetLogger("SqliteDisplayPreferencesRepository"), JsonSerializer, ApplicationPaths, FileSystemManager); DisplayPreferencesRepository = displayPreferencesRepo; RegisterSingleInstance(DisplayPreferencesRepository); - var itemRepo = new SqliteItemRepository(ServerConfigurationManager, this, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo, TimerFactory); + var itemRepo = new SqliteItemRepository(ServerConfigurationManager, this, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), assemblyInfo, FileSystemManager, EnvironmentInfo, TimerFactory); ItemRepository = itemRepo; RegisterSingleInstance(ItemRepository); @@ -975,11 +984,11 @@ protected void RegisterResources() CertificateInfo = GetCertificateInfo(true); Certificate = GetCertificate(CertificateInfo); - HttpServer = HttpServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamFactory, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider, JsonSerializer, XmlSerializer, EnvironmentInfo, Certificate, FileSystemManager, SupportsDualModeSockets); + HttpServer = HttpServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, streamHelper, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider, JsonSerializer, XmlSerializer, EnvironmentInfo, Certificate, FileSystemManager, SupportsDualModeSockets); HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading"); RegisterSingleInstance(HttpServer, false); - ServerManager = new ServerManager.ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamFactory, textEncoding); + ServerManager = new ServerManager.ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, textEncoding); RegisterSingleInstance(ServerManager); ImageProcessor = GetImageProcessor(); @@ -1012,7 +1021,7 @@ protected void RegisterResources() SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor, MediaSourceManager, ServerConfigurationManager, LocalizationManager); RegisterSingleInstance(SubtitleManager); - ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamFactory); + ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer); RegisterSingleInstance(ProviderManager); DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager); @@ -1072,7 +1081,7 @@ protected void RegisterResources() AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, NetworkManager); RegisterSingleInstance(AuthService); - SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamFactory, ProcessFactory, textEncoding); + SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory, textEncoding); RegisterSingleInstance(SubtitleEncoder); RegisterSingleInstance(CreateResourceFileManager()); @@ -1289,7 +1298,6 @@ private void RegisterMediaEncoder(IAssemblyInfo assemblyInfo) () => MediaSourceManager, HttpClient, ZipClient, - MemoryStreamFactory, ProcessFactory, (Environment.ProcessorCount > 2 ? 14000 : 40000), EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows, @@ -1307,7 +1315,7 @@ private void RegisterMediaEncoder(IAssemblyInfo assemblyInfo) /// Task{IUserRepository}. private IUserRepository GetUserRepository() { - var repo = new SqliteUserRepository(LogManager.GetLogger("SqliteUserRepository"), ApplicationPaths, JsonSerializer, MemoryStreamFactory); + var repo = new SqliteUserRepository(LogManager.GetLogger("SqliteUserRepository"), ApplicationPaths, JsonSerializer); repo.Initialize(); diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index 0438638806..09ff7e09d2 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -18,14 +18,12 @@ namespace Emby.Server.Implementations.Data /// public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository { - private readonly IMemoryStreamFactory _memoryStreamProvider; protected IFileSystem FileSystem { get; private set; } - public SqliteDisplayPreferencesRepository(ILogger logger, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IMemoryStreamFactory memoryStreamProvider, IFileSystem fileSystem) + public SqliteDisplayPreferencesRepository(ILogger logger, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IFileSystem fileSystem) : base(logger) { _jsonSerializer = jsonSerializer; - _memoryStreamProvider = memoryStreamProvider; FileSystem = fileSystem; DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db"); } @@ -119,7 +117,7 @@ public void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid u private void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, IDatabaseConnection connection) { - var serialized = _jsonSerializer.SerializeToBytes(displayPreferences, _memoryStreamProvider); + var serialized = _jsonSerializer.SerializeToBytes(displayPreferences); using (var statement = connection.PrepareStatement("replace into userdisplaypreferences (id, userid, client, data) values (@id, @userId, @client, @data)")) { diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs index be410169ce..a755c65f4a 100644 --- a/Emby.Server.Implementations/Data/SqliteExtensions.cs +++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs @@ -130,7 +130,7 @@ public static DateTime ReadDateTime(this IResultSetValue result) /// /// System.Byte[][]. /// obj - public static byte[] SerializeToBytes(this IJsonSerializer json, object obj, IMemoryStreamFactory streamProvider) + public static byte[] SerializeToBytes(this IJsonSerializer json, object obj) { if (obj == null) { diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 730bb8f608..2986be2a44 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -66,7 +66,6 @@ public string Name /// private readonly IServerConfigurationManager _config; - private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly IFileSystem _fileSystem; private readonly IEnvironmentInfo _environmentInfo; private readonly ITimerFactory _timerFactory; @@ -76,7 +75,7 @@ public string Name /// /// Initializes a new instance of the class. /// - public SqliteItemRepository(IServerConfigurationManager config, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, IAssemblyInfo assemblyInfo, IFileSystem fileSystem, IEnvironmentInfo environmentInfo, ITimerFactory timerFactory) + public SqliteItemRepository(IServerConfigurationManager config, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, ILogger logger, IAssemblyInfo assemblyInfo, IFileSystem fileSystem, IEnvironmentInfo environmentInfo, ITimerFactory timerFactory) : base(logger) { if (config == null) @@ -91,7 +90,6 @@ public SqliteItemRepository(IServerConfigurationManager config, IServerApplicati _appHost = appHost; _config = config; _jsonSerializer = jsonSerializer; - _memoryStreamProvider = memoryStreamProvider; _fileSystem = fileSystem; _environmentInfo = environmentInfo; _timerFactory = timerFactory; @@ -180,7 +178,6 @@ var createMediaStreamsTableCommand AddColumn(db, "TypedBaseItems", "EndDate", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "ChannelId", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsMovie", "BIT", existingColumnNames); - AddColumn(db, "TypedBaseItems", "IsSports", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "CommunityRating", "Float", existingColumnNames); AddColumn(db, "TypedBaseItems", "CustomRating", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "IndexNumber", "INT", existingColumnNames); @@ -201,7 +198,6 @@ var createMediaStreamsTableCommand AddColumn(db, "TypedBaseItems", "DateCreated", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsSeries", "BIT", existingColumnNames); - AddColumn(db, "TypedBaseItems", "IsNews", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "EpisodeTitle", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsRepeat", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "PreferredMetadataLanguage", "Text", existingColumnNames); @@ -395,9 +391,7 @@ private void OnShrinkMemoryTimerCallback(object state) "EndDate", "ChannelId", "IsMovie", - "IsSports", "IsSeries", - "IsNews", "EpisodeTitle", "IsRepeat", "CommunityRating", @@ -512,9 +506,7 @@ private string GetSaveItemCommandText() "EndDate", "ChannelId", "IsMovie", - "IsSports", "IsSeries", - "IsNews", "EpisodeTitle", "IsRepeat", "CommunityRating", @@ -758,7 +750,7 @@ private void SaveItem(BaseItem item, BaseItem topParent, string userDataKey, ISt if (TypeRequiresDeserialization(item.GetType())) { - saveItemStatement.TryBind("@data", _jsonSerializer.SerializeToBytes(item, _memoryStreamProvider)); + saveItemStatement.TryBind("@data", _jsonSerializer.SerializeToBytes(item)); } else { @@ -792,18 +784,14 @@ private void SaveItem(BaseItem item, BaseItem topParent, string userDataKey, ISt if (hasProgramAttributes != null) { saveItemStatement.TryBind("@IsMovie", hasProgramAttributes.IsMovie); - saveItemStatement.TryBind("@IsSports", hasProgramAttributes.IsSports); saveItemStatement.TryBind("@IsSeries", hasProgramAttributes.IsSeries); - saveItemStatement.TryBind("@IsNews", hasProgramAttributes.IsNews); saveItemStatement.TryBind("@EpisodeTitle", hasProgramAttributes.EpisodeTitle); saveItemStatement.TryBind("@IsRepeat", hasProgramAttributes.IsRepeat); } else { saveItemStatement.TryBindNull("@IsMovie"); - saveItemStatement.TryBindNull("@IsSports"); saveItemStatement.TryBindNull("@IsSeries"); - saveItemStatement.TryBindNull("@IsNews"); saveItemStatement.TryBindNull("@EpisodeTitle"); saveItemStatement.TryBindNull("@IsRepeat"); } @@ -1460,24 +1448,12 @@ private BaseItem GetItem(IReadOnlyList reader, InternalItemsQue } index++; - if (!reader.IsDBNull(index)) - { - hasProgramAttributes.IsSports = reader.GetBoolean(index); - } - index++; - if (!reader.IsDBNull(index)) { hasProgramAttributes.IsSeries = reader.GetBoolean(index); } index++; - if (!reader.IsDBNull(index)) - { - hasProgramAttributes.IsNews = reader.GetBoolean(index); - } - index++; - if (!reader.IsDBNull(index)) { hasProgramAttributes.EpisodeTitle = reader.GetString(index); @@ -1492,7 +1468,7 @@ private BaseItem GetItem(IReadOnlyList reader, InternalItemsQue } else { - index += 6; + index += 4; } } @@ -2485,9 +2461,7 @@ private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] star if (!HasProgramAttributes(query)) { list.Remove("IsMovie"); - list.Remove("IsSports"); list.Remove("IsSeries"); - list.Remove("IsNews"); list.Remove("EpisodeTitle"); list.Remove("IsRepeat"); list.Remove("ShowId"); @@ -3491,16 +3465,10 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem } } - var exclusiveProgramAttribtues = !(query.IsMovie ?? true) || - !(query.IsSports ?? true) || - !(query.IsKids ?? true) || - !(query.IsNews ?? true) || - !(query.IsSeries ?? true); - var tags = query.Tags.ToList(); var excludeTags = query.ExcludeTags.ToList(); - if (exclusiveProgramAttribtues) + if (!(query.IsMovie ?? true) || !(query.IsSeries ?? true)) { if (query.IsMovie.HasValue) { @@ -3539,22 +3507,6 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem statement.TryBind("@IsSeries", query.IsSeries); } } - if (query.IsNews.HasValue) - { - whereClauses.Add("IsNews=@IsNews"); - if (statement != null) - { - statement.TryBind("@IsNews", query.IsNews); - } - } - if (query.IsSports.HasValue) - { - whereClauses.Add("IsSports=@IsSports"); - if (statement != null) - { - statement.TryBind("@IsSports", query.IsSports); - } - } } else { @@ -3585,22 +3537,6 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem statement.TryBind("@IsMovie", true); } } - if (query.IsSports ?? false) - { - programAttribtues.Add("IsSports=@IsSports"); - if (statement != null) - { - statement.TryBind("@IsSports", query.IsSports); - } - } - if (query.IsNews ?? false) - { - programAttribtues.Add("IsNews=@IsNews"); - if (statement != null) - { - statement.TryBind("@IsNews", query.IsNews); - } - } if (query.IsSeries ?? false) { programAttribtues.Add("IsSeries=@IsSeries"); @@ -3615,6 +3551,30 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem } } + if (query.IsSports.HasValue) + { + if (query.IsSports.HasValue) + { + tags.Add("Sports"); + } + else + { + excludeTags.Add("Sports"); + } + } + + if (query.IsNews.HasValue) + { + if (query.IsNews.HasValue) + { + tags.Add("News"); + } + else + { + excludeTags.Add("News"); + } + } + if (query.IsKids.HasValue) { if (query.IsKids.HasValue) diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs index 079d3aa450..71ffe773fd 100644 --- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs @@ -18,13 +18,11 @@ namespace Emby.Server.Implementations.Data public class SqliteUserRepository : BaseSqliteRepository, IUserRepository { private readonly IJsonSerializer _jsonSerializer; - private readonly IMemoryStreamFactory _memoryStreamProvider; - public SqliteUserRepository(ILogger logger, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IMemoryStreamFactory memoryStreamProvider) + public SqliteUserRepository(ILogger logger, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer) : base(logger) { _jsonSerializer = jsonSerializer; - _memoryStreamProvider = memoryStreamProvider; DbFilePath = Path.Combine(appPaths.DataPath, "users.db"); } @@ -79,7 +77,7 @@ public void SaveUser(User user, CancellationToken cancellationToken) cancellationToken.ThrowIfCancellationRequested(); - var serialized = _jsonSerializer.SerializeToBytes(user, _memoryStreamProvider); + var serialized = _jsonSerializer.SerializeToBytes(user); cancellationToken.ThrowIfCancellationRequested(); diff --git a/Emby.Server.Implementations/Diagnostics/CommonProcess.cs b/Emby.Server.Implementations/Diagnostics/CommonProcess.cs index 09b8bf22cd..6348148a2b 100644 --- a/Emby.Server.Implementations/Diagnostics/CommonProcess.cs +++ b/Emby.Server.Implementations/Diagnostics/CommonProcess.cs @@ -3,6 +3,7 @@ using System.IO; using System.Threading.Tasks; using MediaBrowser.Model.Diagnostics; +using System.Threading; namespace Emby.Server.Implementations.Diagnostics { @@ -48,8 +49,12 @@ public CommonProcess(ProcessOptions options) } } + private bool HasExited; + private void _process_Exited(object sender, EventArgs e) { + HasExited = true; + if (Exited != null) { Exited(this, e); @@ -98,7 +103,19 @@ public bool WaitForExit(int timeMs) public Task WaitForExitAsync(int timeMs) { - return Task.FromResult(_process.WaitForExit(timeMs)); + if (HasExited) + { + return Task.FromResult(true); + } + + var tcs = new TaskCompletionSource(); + + var cancellationToken = new CancellationTokenSource(timeMs).Token; + _process.Exited += (sender, args) => tcs.TrySetResult(HasExited); + + cancellationToken.Register(() => tcs.TrySetResult(HasExited)); + + return tcs.Task; } public void Dispose() diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 1ef425e422..2e1f530043 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -110,7 +110,6 @@ - @@ -335,6 +334,7 @@ + diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index f42f1dc297..d53606e878 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -41,13 +41,12 @@ public class HttpClientManager : IHttpClient private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; - private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly Func _defaultUserAgentFn; /// /// Initializes a new instance of the class. /// - public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamFactory memoryStreamProvider, Func defaultUserAgentFn) + public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, Func defaultUserAgentFn) { if (appPaths == null) { @@ -60,7 +59,6 @@ public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem _logger = logger; _fileSystem = fileSystem; - _memoryStreamProvider = memoryStreamProvider; _appPaths = appPaths; _defaultUserAgentFn = defaultUserAgentFn; @@ -636,7 +634,7 @@ public async Task GetTempFileResponse(HttpRequestOptions optio { using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true)) { - await StreamHelper.CopyToAsync(httpResponse.GetResponseStream(), fs, StreamDefaults.DefaultCopyToBufferSize, options.Progress, contentLength.Value, options.CancellationToken).ConfigureAwait(false); + await httpResponse.GetResponseStream().CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false); } } diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index d7fa3b7eb8..d5698f0bea 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -45,7 +45,7 @@ public class HttpListenerHost : IHttpServer, IDisposable private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; - private readonly IMemoryStreamFactory _memoryStreamProvider; + private readonly IStreamHelper _streamHelper; private readonly IServerApplicationHost _appHost; @@ -70,14 +70,14 @@ public HttpListenerHost(IServerApplicationHost applicationHost, ILogger logger, IServerConfigurationManager config, string serviceName, - string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, IEnvironmentInfo environment, X509Certificate certificate, Func> funcParseFn, bool enableDualModeSockets, IFileSystem fileSystem) + string defaultRedirectPath, INetworkManager networkManager, IStreamHelper streamHelper, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, IEnvironmentInfo environment, X509Certificate certificate, Func> funcParseFn, bool enableDualModeSockets, IFileSystem fileSystem) { Instance = this; _appHost = applicationHost; DefaultRedirectPath = defaultRedirectPath; _networkManager = networkManager; - _memoryStreamProvider = memoryStreamProvider; + _streamHelper = streamHelper; _textEncoding = textEncoding; _socketFactory = socketFactory; _cryptoProvider = cryptoProvider; @@ -180,7 +180,7 @@ private IHttpListener GetListener() return new WebSocketSharpListener(_logger, _certificate, - _memoryStreamProvider, + _streamHelper, _textEncoding, _networkManager, _socketFactory, @@ -264,7 +264,7 @@ private int GetStatusCode(Exception ex) return statusCode; } - private void ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace, bool logExceptionMessage) + private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace, bool logExceptionMessage) { try { @@ -290,7 +290,7 @@ private void ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStack httpRes.StatusCode = statusCode; httpRes.ContentType = "text/html"; - Write(httpRes, NormalizeExceptionMessage(ex.Message)); + await Write(httpRes, NormalizeExceptionMessage(ex.Message)).ConfigureAwait(false); } catch { @@ -509,7 +509,7 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri { httpRes.StatusCode = 503; httpRes.ContentType = "text/plain"; - Write(httpRes, "Server shutting down"); + await Write(httpRes, "Server shutting down").ConfigureAwait(false); return; } @@ -517,7 +517,7 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri { httpRes.StatusCode = 400; httpRes.ContentType = "text/plain"; - Write(httpRes, "Invalid host"); + await Write(httpRes, "Invalid host").ConfigureAwait(false); return; } @@ -525,7 +525,7 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri { httpRes.StatusCode = 403; httpRes.ContentType = "text/plain"; - Write(httpRes, "Forbidden"); + await Write(httpRes, "Forbidden").ConfigureAwait(false); return; } @@ -542,7 +542,7 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri httpRes.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); httpRes.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); httpRes.ContentType = "text/plain"; - Write(httpRes, string.Empty); + await Write(httpRes, string.Empty).ConfigureAwait(false); return; } @@ -583,9 +583,9 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) { - Write(httpRes, + await Write(httpRes, "EmbyPlease update your Emby bookmark to " + newUrl + ""); + newUrl + "\">" + newUrl + "").ConfigureAwait(false); return; } } @@ -600,9 +600,9 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) { - Write(httpRes, + await Write(httpRes, "EmbyPlease update your Emby bookmark to " + newUrl + ""); + newUrl + "\">" + newUrl + "").ConfigureAwait(false); return; } } @@ -635,7 +635,7 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri { httpRes.StatusCode = 503; httpRes.ContentType = "text/html"; - Write(httpRes, GlobalResponse); + await Write(httpRes, GlobalResponse).ConfigureAwait(false); return; } } @@ -720,13 +720,12 @@ public ServiceHandler GetServiceHandler(IHttpRequest httpReq) return null; } - private void Write(IResponse response, string text) + private Task Write(IResponse response, string text) { var bOutput = Encoding.UTF8.GetBytes(text); response.SetContentLength(bOutput.Length); - var outputStream = response.OutputStream; - outputStream.Write(bOutput, 0, bOutput.Length); + return response.OutputStream.WriteAsync(bOutput, 0, bOutput.Length); } private void RedirectToSecureUrl(IHttpRequest httpReq, IResponse httpRes, string url) diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index 7a7c8f7e46..f860ec311f 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -31,16 +31,14 @@ public class HttpResultFactory : IHttpResultFactory private readonly ILogger _logger; private readonly IFileSystem _fileSystem; private readonly IJsonSerializer _jsonSerializer; - private readonly IMemoryStreamFactory _memoryStreamFactory; /// /// Initializes a new instance of the class. /// - public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IMemoryStreamFactory memoryStreamFactory) + public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer) { _fileSystem = fileSystem; _jsonSerializer = jsonSerializer; - _memoryStreamFactory = memoryStreamFactory; _logger = logManager.GetLogger("HttpResultFactory"); } @@ -51,12 +49,22 @@ public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSe /// Type of the content. /// The response headers. /// System.Object. - public object GetResult(object content, string contentType, IDictionary responseHeaders = null) + public object GetResult(byte[] content, string contentType, IDictionary responseHeaders = null) { return GetHttpResult(null, content, contentType, true, responseHeaders); } - public object GetResult(IRequest requestContext, object content, string contentType, IDictionary responseHeaders = null) + public object GetResult(string content, string contentType, IDictionary responseHeaders = null) + { + return GetHttpResult(null, content, contentType, true, responseHeaders); + } + + public object GetResult(Stream content, string contentType, IDictionary responseHeaders = null) + { + return GetHttpResult(null, content, contentType, true, responseHeaders); + } + + public object GetResult(IRequest requestContext, string content, string contentType, IDictionary responseHeaders = null) { return GetHttpResult(requestContext, content, contentType, true, responseHeaders); } @@ -140,19 +148,8 @@ private IHasHeaders GetHttpResult(IRequest requestContext, object content, strin /// Gets the optimized result. /// /// - /// The request context. - /// The result. - /// The response headers. - /// System.Object. - /// result - public object GetOptimizedResult(IRequest requestContext, T result, IDictionary responseHeaders = null) + public object GetResult(IRequest requestContext, T result, IDictionary responseHeaders = null) where T : class - { - return GetOptimizedResultInternal(requestContext, result, true, responseHeaders); - } - - private object GetOptimizedResultInternal(IRequest requestContext, T result, bool addCachePrevention, IDictionary responseHeaders = null) - where T : class { if (result == null) { @@ -164,10 +161,7 @@ private object GetOptimizedResultInternal(IRequest requestContext, T result, responseHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); } - if (addCachePrevention) - { - responseHeaders["Expires"] = "-1"; - } + responseHeaders["Expires"] = "-1"; return ToOptimizedResultInternal(requestContext, result, responseHeaders); } @@ -334,50 +328,6 @@ private string SerializeToXmlString(object from) } } - /// - /// Gets the optimized result using cache. - /// - /// - /// The request context. - /// The cache key. - /// The last date modified. - /// Duration of the cache. - /// The factory fn. - /// The response headers. - /// System.Object. - /// cacheKey - /// or - /// factoryFn - public object GetOptimizedResultUsingCache(IRequest requestContext, Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func factoryFn, IDictionary responseHeaders = null) - where T : class - { - if (cacheKey.Equals(Guid.Empty)) - { - throw new ArgumentNullException("cacheKey"); - } - if (factoryFn == null) - { - throw new ArgumentNullException("factoryFn"); - } - - var key = cacheKey.ToString("N"); - - if (responseHeaders == null) - { - responseHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); - } - - // See if the result is already cached in the browser - var result = GetCachedResult(requestContext, responseHeaders, cacheKey, key, lastDateModified, cacheDuration, null); - - if (result != null) - { - return result; - } - - return GetOptimizedResultInternal(requestContext, factoryFn(), false, responseHeaders); - } - /// /// To the cached result. /// @@ -551,19 +501,17 @@ public async Task GetStaticResult(IRequest requestContext, StaticResultO options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary(StringComparer.OrdinalIgnoreCase); var contentType = options.ContentType; - if (cacheKey.Equals(Guid.Empty)) + if (!cacheKey.Equals(Guid.Empty)) { - throw new ArgumentNullException("cacheKey"); - } - - var key = cacheKey.ToString("N"); + var key = cacheKey.ToString("N"); - // See if the result is already cached in the browser - var result = GetCachedResult(requestContext, options.ResponseHeaders, cacheKey, key, options.DateLastModified, options.CacheDuration, contentType); + // See if the result is already cached in the browser + var result = GetCachedResult(requestContext, options.ResponseHeaders, cacheKey, key, options.DateLastModified, options.CacheDuration, contentType); - if (result != null) - { - return result; + if (result != null) + { + return result; + } } // TODO: We don't really need the option value @@ -592,7 +540,7 @@ public async Task GetStaticResult(IRequest requestContext, StaticResultO { var stream = await factoryFn().ConfigureAwait(false); - var hasHeaders = new RangeRequestWriter(rangeHeader, stream, contentType, isHeadRequest, _logger) + var hasHeaders = new RangeRequestWriter(rangeHeader, options.ContentLength, stream, contentType, isHeadRequest, _logger) { OnComplete = options.OnComplete }; diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs index 305c917c62..a0b94b4d69 100644 --- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs +++ b/Emby.Server.Implementations/HttpServer/IHttpListener.cs @@ -13,7 +13,7 @@ public interface IHttpListener : IDisposable /// Gets or sets the error handler. /// /// The error handler. - Action ErrorHandler { get; set; } + Func ErrorHandler { get; set; } /// /// Gets or sets the request handler. diff --git a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs index 7c967949b8..9017ba381a 100644 --- a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -58,7 +58,7 @@ public IDictionary Headers /// The source. /// Type of the content. /// if set to true [is head request]. - public RangeRequestWriter(string rangeHeader, Stream source, string contentType, bool isHeadRequest, ILogger logger) + public RangeRequestWriter(string rangeHeader, long? contentLength, Stream source, string contentType, bool isHeadRequest, ILogger logger) { if (string.IsNullOrEmpty(contentType)) { @@ -76,17 +76,17 @@ public RangeRequestWriter(string rangeHeader, Stream source, string contentType, StatusCode = HttpStatusCode.PartialContent; Cookies = new List(); - SetRangeValues(); + SetRangeValues(contentLength); } /// /// Sets the range values. /// - private void SetRangeValues() + private void SetRangeValues(long? contentLength) { var requestedRange = RequestedRanges[0]; - TotalContentLength = SourceStream.Length; + TotalContentLength = contentLength ?? SourceStream.Length; // If the requested range is "0-", we can optimize by just doing a stream copy if (!requestedRange.Value.HasValue) @@ -105,7 +105,7 @@ private void SetRangeValues() Headers["Content-Length"] = RangeLength.ToString(UsCulture); Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength); - if (RangeStart > 0) + if (RangeStart > 0 && SourceStream.CanSeek) { SourceStream.Position = RangeStart; } diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index 632fa522c1..295b45245d 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -24,7 +24,7 @@ public class WebSocketSharpListener : IHttpListener private readonly ILogger _logger; private readonly X509Certificate _certificate; - private readonly IMemoryStreamFactory _memoryStreamProvider; + private readonly IStreamHelper _streamHelper; private readonly ITextEncoding _textEncoding; private readonly INetworkManager _networkManager; private readonly ISocketFactory _socketFactory; @@ -36,11 +36,11 @@ public class WebSocketSharpListener : IHttpListener private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); private CancellationToken _disposeCancellationToken; - public WebSocketSharpListener(ILogger logger, X509Certificate certificate, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, bool enableDualMode, IFileSystem fileSystem, IEnvironmentInfo environment) + public WebSocketSharpListener(ILogger logger, X509Certificate certificate, IStreamHelper streamHelper, ITextEncoding textEncoding, INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, bool enableDualMode, IFileSystem fileSystem, IEnvironmentInfo environment) { _logger = logger; _certificate = certificate; - _memoryStreamProvider = memoryStreamProvider; + _streamHelper = streamHelper; _textEncoding = textEncoding; _networkManager = networkManager; _socketFactory = socketFactory; @@ -52,7 +52,7 @@ public WebSocketSharpListener(ILogger logger, X509Certificate certificate, IMemo _disposeCancellationToken = _disposeCancellationTokenSource.Token; } - public Action ErrorHandler { get; set; } + public Func ErrorHandler { get; set; } public Func RequestHandler { get; set; } public Action WebSocketConnecting { get; set; } @@ -62,7 +62,7 @@ public WebSocketSharpListener(ILogger logger, X509Certificate certificate, IMemo public void Start(IEnumerable urlPrefixes) { if (_listener == null) - _listener = new HttpListener(_logger, _cryptoProvider, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider, _fileSystem, _environment); + _listener = new HttpListener(_logger, _cryptoProvider, _socketFactory, _networkManager, _textEncoding, _streamHelper, _fileSystem, _environment); _listener.EnableDualMode = _enableDualMode; @@ -99,8 +99,7 @@ private Task InitTask(HttpListenerContext context, CancellationToken cancellatio { LoggerUtils.LogRequest(_logger, request); - ProcessWebSocketRequest(context); - return Task.CompletedTask; + return ProcessWebSocketRequest(context); } httpReq = GetRequest(context); @@ -110,8 +109,7 @@ private Task InitTask(HttpListenerContext context, CancellationToken cancellatio _logger.ErrorException("Error processing request", ex); httpReq = httpReq ?? GetRequest(context); - ErrorHandler(ex, httpReq, true, true); - return Task.CompletedTask; + return ErrorHandler(ex, httpReq, true, true); } var uri = request.Url; @@ -119,17 +117,19 @@ private Task InitTask(HttpListenerContext context, CancellationToken cancellatio return RequestHandler(httpReq, uri.OriginalString, uri.Host, uri.LocalPath, cancellationToken); } - private void ProcessWebSocketRequest(HttpListenerContext ctx) + private async Task ProcessWebSocketRequest(HttpListenerContext ctx) { try { var endpoint = ctx.Request.RemoteEndPoint.ToString(); var url = ctx.Request.RawUrl; + var queryString = ctx.Request.QueryString; + var connectingArgs = new WebSocketConnectingEventArgs { Url = url, - QueryString = ctx.Request.QueryString, + QueryString = queryString, Endpoint = endpoint }; @@ -142,14 +142,14 @@ private void ProcessWebSocketRequest(HttpListenerContext ctx) { _logger.Debug("Web socket connection allowed"); - var webSocketContext = ctx.AcceptWebSocket(null); + var webSocketContext = await ctx.AcceptWebSocketAsync(null).ConfigureAwait(false); if (WebSocketConnected != null) { WebSocketConnected(new WebSocketConnectEventArgs { Url = url, - QueryString = ctx.Request.QueryString, + QueryString = queryString, WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger), Endpoint = endpoint }); @@ -176,7 +176,7 @@ private IHttpRequest GetRequest(HttpListenerContext httpContext) var operationName = urlSegments[urlSegments.Length - 1]; - var req = new WebSocketSharpRequest(httpContext, operationName, _logger, _memoryStreamProvider); + var req = new WebSocketSharpRequest(httpContext, operationName, _logger); return req; } diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 79cfce6387..2a45bdb842 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -20,12 +20,10 @@ public partial class WebSocketSharpRequest : IHttpRequest { private readonly HttpListenerRequest request; private readonly IHttpResponse response; - private readonly IMemoryStreamFactory _memoryStreamProvider; - public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, ILogger logger, IMemoryStreamFactory memoryStreamProvider) + public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, ILogger logger) { this.OperationName = operationName; - _memoryStreamProvider = memoryStreamProvider; this.request = httpContext.Request; this.response = new WebSocketSharpResponse(logger, httpContext.Response, this); diff --git a/Emby.Server.Implementations/HttpServerFactory.cs b/Emby.Server.Implementations/HttpServerFactory.cs index 717c50e7b5..7ec97c006b 100644 --- a/Emby.Server.Implementations/HttpServerFactory.cs +++ b/Emby.Server.Implementations/HttpServerFactory.cs @@ -34,7 +34,7 @@ public static IHttpServer CreateServer(IServerApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, INetworkManager networkmanager, - IMemoryStreamFactory streamProvider, + IStreamHelper streamProvider, string serverName, string defaultRedirectpath, ITextEncoding textEncoding, diff --git a/Emby.Server.Implementations/IO/MemoryStreamProvider.cs b/Emby.Server.Implementations/IO/MemoryStreamProvider.cs deleted file mode 100644 index e999ec4e26..0000000000 --- a/Emby.Server.Implementations/IO/MemoryStreamProvider.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.IO; -using MediaBrowser.Model.IO; - -namespace Emby.Server.Implementations.IO -{ - public class MemoryStreamProvider : IMemoryStreamFactory - { - public MemoryStream CreateNew() - { - return new MemoryStream(); - } - } -} diff --git a/Emby.Server.Implementations/IO/StreamHelper.cs b/Emby.Server.Implementations/IO/StreamHelper.cs new file mode 100644 index 0000000000..48a5063e80 --- /dev/null +++ b/Emby.Server.Implementations/IO/StreamHelper.cs @@ -0,0 +1,190 @@ +using System.IO; +using System.Threading; +using System; +using System.Threading.Tasks; +using MediaBrowser.Model.IO; + +namespace Emby.Server.Implementations.IO +{ + public class StreamHelper : IStreamHelper + { + public async Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken) + { + byte[] buffer = new byte[bufferSize]; + int read; + while ((read = source.Read(buffer, 0, buffer.Length)) != 0) + { + cancellationToken.ThrowIfCancellationRequested(); + + await destination.WriteAsync(buffer, 0, read).ConfigureAwait(false); + + if (onStarted != null) + { + onStarted(); + onStarted = null; + } + } + } + + public async Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken) + { + byte[] buffer = new byte[bufferSize]; + + if (emptyReadLimit <= 0) + { + int read; + while ((read = source.Read(buffer, 0, buffer.Length)) != 0) + { + cancellationToken.ThrowIfCancellationRequested(); + + await destination.WriteAsync(buffer, 0, read).ConfigureAwait(false); + } + + return; + } + + var eofCount = 0; + + while (eofCount < emptyReadLimit) + { + cancellationToken.ThrowIfCancellationRequested(); + + var bytesRead = source.Read(buffer, 0, buffer.Length); + + if (bytesRead == 0) + { + eofCount++; + await Task.Delay(50, cancellationToken).ConfigureAwait(false); + } + else + { + eofCount = 0; + + await destination.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false); + } + } + } + + const int StreamCopyToBufferSize = 81920; + public async Task CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken) + { + var array = new byte[StreamCopyToBufferSize]; + int bytesRead; + int totalBytesRead = 0; + + while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0) + { + var bytesToWrite = bytesRead; + + if (bytesToWrite > 0) + { + await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false); + + totalBytesRead += bytesRead; + } + } + + return totalBytesRead; + } + + public async Task CopyToAsyncWithSyncRead(Stream source, Stream destination, CancellationToken cancellationToken) + { + var array = new byte[StreamCopyToBufferSize]; + int bytesRead; + int totalBytesRead = 0; + + while ((bytesRead = source.Read(array, 0, array.Length)) != 0) + { + var bytesToWrite = bytesRead; + + if (bytesToWrite > 0) + { + await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false); + + totalBytesRead += bytesRead; + } + } + + return totalBytesRead; + } + + public async Task CopyToAsyncWithSyncRead(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken) + { + var array = new byte[StreamCopyToBufferSize]; + int bytesRead; + + while ((bytesRead = source.Read(array, 0, array.Length)) != 0) + { + var bytesToWrite = Math.Min(bytesRead, copyLength); + + if (bytesToWrite > 0) + { + await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false); + } + + copyLength -= bytesToWrite; + + if (copyLength <= 0) + { + break; + } + } + } + + public async Task CopyToAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken) + { + var array = new byte[StreamCopyToBufferSize]; + int bytesRead; + + while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0) + { + var bytesToWrite = Math.Min(bytesRead, copyLength); + + if (bytesToWrite > 0) + { + await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false); + } + + copyLength -= bytesToWrite; + + if (copyLength <= 0) + { + break; + } + } + } + + public async Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken) + { + byte[] buffer = new byte[bufferSize]; + + while (!cancellationToken.IsCancellationRequested) + { + var bytesRead = await CopyToAsyncInternal(source, target, buffer, cancellationToken).ConfigureAwait(false); + + //var position = fs.Position; + //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); + + if (bytesRead == 0) + { + await Task.Delay(100).ConfigureAwait(false); + } + } + } + + private static async Task CopyToAsyncInternal(Stream source, Stream destination, byte[] buffer, CancellationToken cancellationToken) + { + int bytesRead; + int totalBytesRead = 0; + + while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) + { + await destination.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false); + + totalBytesRead += bytesRead; + } + + return totalBytesRead; + } + } +} diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 053a45669b..ec357380bb 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -366,7 +366,7 @@ private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData use var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference) ? Array.Empty() - : NormalizeLanguage(user.Configuration.SubtitleLanguagePreference); + : NormalizeLanguage(user.Configuration.AudioLanguagePreference); source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack); } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index f0578d9efb..1344be9fed 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -17,12 +17,14 @@ public class DirectRecorder : IRecorder private readonly ILogger _logger; private readonly IHttpClient _httpClient; private readonly IFileSystem _fileSystem; + private readonly IStreamHelper _streamHelper; - public DirectRecorder(ILogger logger, IHttpClient httpClient, IFileSystem fileSystem) + public DirectRecorder(ILogger logger, IHttpClient httpClient, IFileSystem fileSystem, IStreamHelper streamHelper) { _logger = logger; _httpClient = httpClient; _fileSystem = fileSystem; + _streamHelper = streamHelper; } public string GetOutputPath(MediaSourceInfo mediaSource, string targetFile) @@ -90,45 +92,11 @@ private async Task RecordFromMediaSource(MediaSourceInfo mediaSource, string tar var durationToken = new CancellationTokenSource(duration); cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; - await CopyUntilCancelled(response.Content, output, cancellationToken).ConfigureAwait(false); + await _streamHelper.CopyUntilCancelled(response.Content, output, 81920, cancellationToken).ConfigureAwait(false); } } _logger.Info("Recording completed to file {0}", targetFile); } - - private const int BufferSize = 81920; - public static async Task CopyUntilCancelled(Stream source, Stream target, CancellationToken cancellationToken) - { - byte[] buffer = new byte[BufferSize]; - - while (!cancellationToken.IsCancellationRequested) - { - var bytesRead = await CopyToAsyncInternal(source, target, buffer, cancellationToken).ConfigureAwait(false); - - //var position = fs.Position; - //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); - - if (bytesRead == 0) - { - await Task.Delay(100).ConfigureAwait(false); - } - } - } - - private static async Task CopyToAsyncInternal(Stream source, Stream destination, byte[] buffer, CancellationToken cancellationToken) - { - int bytesRead; - int totalBytesRead = 0; - - while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) - { - destination.Write(buffer, 0, bytesRead); - - totalBytesRead += bytesRead; - } - - return totalBytesRead; - } } } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 2f782b14ab..86a807e579 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -76,7 +76,9 @@ public class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNe private readonly ConcurrentDictionary _activeRecordings = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - public EmbyTV(IServerApplicationHost appHost, IMediaSourceManager mediaSourceManager, IAssemblyInfo assemblyInfo, ILogger logger, IJsonSerializer jsonSerializer, IPowerManagement powerManagement, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory, IProcessFactory processFactory, ISystemEvents systemEvents) + private readonly IStreamHelper _streamHelper; + + public EmbyTV(IServerApplicationHost appHost, IStreamHelper streamHelper, IMediaSourceManager mediaSourceManager, IAssemblyInfo assemblyInfo, ILogger logger, IJsonSerializer jsonSerializer, IPowerManagement powerManagement, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory, IProcessFactory processFactory, ISystemEvents systemEvents) { Current = this; @@ -95,6 +97,7 @@ public EmbyTV(IServerApplicationHost appHost, IMediaSourceManager mediaSourceMan _jsonSerializer = jsonSerializer; _assemblyInfo = assemblyInfo; _mediaSourceManager = mediaSourceManager; + _streamHelper = streamHelper; _seriesTimerProvider = new SeriesTimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers")); _timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers"), _logger, timerFactory, powerManagement); @@ -832,13 +835,11 @@ private void UpdateExistingTimerWithNewMetadata(TimerInfo existingTimer, TimerIn existingTimer.EpisodeTitle = updatedTimer.EpisodeTitle; existingTimer.Genres = updatedTimer.Genres; existingTimer.HomePageUrl = updatedTimer.HomePageUrl; - existingTimer.IsNews = updatedTimer.IsNews; existingTimer.IsMovie = updatedTimer.IsMovie; existingTimer.IsSeries = updatedTimer.IsSeries; existingTimer.Tags = updatedTimer.Tags; existingTimer.IsProgramSeries = updatedTimer.IsProgramSeries; existingTimer.IsRepeat = updatedTimer.IsRepeat; - existingTimer.IsSports = updatedTimer.IsSports; existingTimer.Name = updatedTimer.Name; existingTimer.OfficialRating = updatedTimer.OfficialRating; existingTimer.OriginalAirDate = updatedTimer.OriginalAirDate; @@ -1826,7 +1827,7 @@ private IRecorder GetRecorder(MediaSourceInfo mediaSource) return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _httpClient, _processFactory, _config, _assemblyInfo); } - return new DirectRecorder(_logger, _httpClient, _fileSystem); + return new DirectRecorder(_logger, _httpClient, _fileSystem, _streamHelper); } private void OnSuccessfulRecording(TimerInfo timer, string path) @@ -2705,8 +2706,6 @@ private void CopyProgramInfoToTimerInfo(LiveTvProgram programInfo, TimerInfo tim timerInfo.SeasonNumber = programInfo.ParentIndexNumber; timerInfo.EpisodeNumber = programInfo.IndexNumber; timerInfo.IsMovie = programInfo.IsMovie; - timerInfo.IsNews = programInfo.IsNews; - timerInfo.IsSports = programInfo.IsSports; timerInfo.ProductionYear = programInfo.ProductionYear; timerInfo.EpisodeTitle = programInfo.EpisodeTitle; timerInfo.OriginalAirDate = programInfo.PremiereDate; diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index d4ec30dbe7..c9db788bba 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -304,7 +304,7 @@ private ProgramInfo GetProgram(string channelId, ScheduleDirect.Program programI IsMovie = IsMovie(details), Etag = programInfo.md5, IsLive = string.Equals(programInfo.liveTapeDelay, "live", StringComparison.OrdinalIgnoreCase), - IsPremiere = programInfo.premiere + IsPremiere = programInfo.premiere || (programInfo.isPremiereOrFinale ?? string.Empty).IndexOf("premiere", StringComparison.OrdinalIgnoreCase) != -1 }; var showId = programId; @@ -1129,6 +1129,7 @@ public class Program public string liveTapeDelay { get; set; } public bool premiere { get; set; } public bool repeat { get; set; } + public string isPremiereOrFinale { get; set; } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 47a4b8d7c8..ff65ae49a5 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -584,7 +584,6 @@ private Tuple GetProgram(ProgramInfo info, Dictionary item.Genres = info.Genres.ToArray(); item.IsHD = info.IsHD; item.IsMovie = info.IsMovie; - item.IsNews = info.IsNews; item.IsRepeat = info.IsRepeat; if (item.IsSeries != isSeries) @@ -593,7 +592,6 @@ private Tuple GetProgram(ProgramInfo info, Dictionary } item.IsSeries = isSeries; - item.IsSports = info.IsSports; item.Name = info.Name; item.OfficialRating = item.OfficialRating ?? info.OfficialRating; item.Overview = item.Overview ?? info.Overview; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs index 4ed33bad3d..3733887ed0 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs @@ -206,7 +206,7 @@ private async Task CopyFile(string path, bool seekFile, int emptyReadLimit, bool TrySeek(inputStream, -20000); } - await CopyTo(inputStream, stream, 81920, emptyReadLimit, cancellationToken).ConfigureAwait(false); + await ApplicationHost.StreamHelper.CopyToAsync(inputStream, stream, 81920, emptyReadLimit, cancellationToken).ConfigureAwait(false); } } @@ -218,46 +218,6 @@ protected virtual int EmptyReadLimit } } - private async Task CopyTo(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken) - { - byte[] buffer = new byte[bufferSize]; - - if (emptyReadLimit <= 0) - { - int read; - while ((read = source.Read(buffer, 0, buffer.Length)) != 0) - { - cancellationToken.ThrowIfCancellationRequested(); - - destination.Write(buffer, 0, read); - } - - return; - } - - var eofCount = 0; - - while (eofCount < emptyReadLimit) - { - cancellationToken.ThrowIfCancellationRequested(); - - var bytesRead = source.Read(buffer, 0, buffer.Length); - - if (bytesRead == 0) - { - eofCount++; - await Task.Delay(50, cancellationToken).ConfigureAwait(false); - } - else - { - eofCount = 0; - - //await destination.WriteAsync(buffer, 0, read).ConfigureAwait(false); - destination.Write(buffer, 0, bytesRead); - } - } - } - private void TrySeek(FileStream stream, long offset) { //Logger.Info("TrySeek live stream"); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index 0ad1e8fa88..f22d7f1e02 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -133,7 +133,7 @@ private Task StartStreaming(HttpResponseInfo response, TaskCompletionSource Resolve(openTaskCompletionSource), cancellationToken); + await ApplicationHost.StreamHelper.CopyToAsync(stream, fileStream, 81920, () => Resolve(openTaskCompletionSource), cancellationToken).ConfigureAwait(false); } } } diff --git a/Emby.Server.Implementations/Security/PluginSecurityManager.cs b/Emby.Server.Implementations/Security/PluginSecurityManager.cs index 9b59e7bfd2..adad3442f1 100644 --- a/Emby.Server.Implementations/Security/PluginSecurityManager.cs +++ b/Emby.Server.Implementations/Security/PluginSecurityManager.cs @@ -28,7 +28,7 @@ public class PluginSecurityManager : ISecurityManager public async Task IsSupporter() { - var result = await GetRegistrationStatus("MBSupporter", _appHost.ApplicationVersion.ToString()).ConfigureAwait(false); + var result = await GetRegistrationStatusInternal("MBSupporter", false, _appHost.ApplicationVersion.ToString(), CancellationToken.None).ConfigureAwait(false); return result.IsRegistered; } @@ -73,25 +73,7 @@ public PluginSecurityManager(IServerApplicationHost appHost, IHttpClient httpCli /// public Task GetRegistrationStatus(string feature) { - return GetRegistrationStatus(feature, null); - } - - private SemaphoreSlim _regCheckLock = new SemaphoreSlim(1, 1); - /// - /// Gets the registration status. - /// - public async Task GetRegistrationStatus(string feature, string version) - { - await _regCheckLock.WaitAsync(CancellationToken.None).ConfigureAwait(false); - - try - { - return await GetRegistrationStatusInternal(feature, version).ConfigureAwait(false); - } - finally - { - _regCheckLock.Release(); - } + return GetRegistrationStatusInternal(feature, false, null, CancellationToken.None); } /// @@ -123,7 +105,7 @@ public async Task UpdateSupporterKey(string newValue) LicenseFile.Save(); // Reset this - await IsSupporter().ConfigureAwait(false); + await GetRegistrationStatusInternal("MBSupporter", true, _appHost.ApplicationVersion.ToString(), CancellationToken.None).ConfigureAwait(false); } } @@ -202,97 +184,113 @@ private void SaveAppStoreInfo(string info) } } - private async Task GetRegistrationStatusInternal(string feature, - string version = null) - { - var regInfo = LicenseFile.GetRegInfo(feature); - var lastChecked = regInfo == null ? DateTime.MinValue : regInfo.LastChecked; - var expDate = regInfo == null ? DateTime.MinValue : regInfo.ExpirationDate; + private SemaphoreSlim _regCheckLock = new SemaphoreSlim(1, 1); - var maxCacheDays = 14; - var nextCheckDate = new [] { expDate, lastChecked.AddDays(maxCacheDays) }.Min(); + private async Task GetRegistrationStatusInternal(string feature, bool forceCallToServer, string version, CancellationToken cancellationToken) + { + await _regCheckLock.WaitAsync(cancellationToken).ConfigureAwait(false); - if (nextCheckDate > DateTime.UtcNow.AddDays(maxCacheDays)) + try { - nextCheckDate = DateTime.MinValue; - } + var regInfo = LicenseFile.GetRegInfo(feature); + var lastChecked = regInfo == null ? DateTime.MinValue : regInfo.LastChecked; + var expDate = regInfo == null ? DateTime.MinValue : regInfo.ExpirationDate; - //check the reg file first to alleviate strain on the MB admin server - must actually check in every 30 days tho - var reg = new RegRecord - { - // Cache the result for up to a week - registered = regInfo != null && nextCheckDate >= DateTime.UtcNow && expDate >= DateTime.UtcNow, - expDate = expDate - }; + var maxCacheDays = 14; + var nextCheckDate = new[] { expDate, lastChecked.AddDays(maxCacheDays) }.Min(); - var key = SupporterKey; + if (nextCheckDate > DateTime.UtcNow.AddDays(maxCacheDays)) + { + nextCheckDate = DateTime.MinValue; + } - var success = reg.registered; + //check the reg file first to alleviate strain on the MB admin server - must actually check in every 30 days tho + var reg = new RegRecord + { + // Cache the result for up to a week + registered = regInfo != null && nextCheckDate >= DateTime.UtcNow && expDate >= DateTime.UtcNow, + expDate = expDate + }; - if (!(lastChecked > DateTime.UtcNow.AddDays(-1)) || (!reg.registered)) - { - var data = new Dictionary + var key = SupporterKey; + + if (!forceCallToServer && string.IsNullOrWhiteSpace(key)) { - { "feature", feature }, - { "key", key }, - { "mac", _appHost.SystemId }, - { "systemid", _appHost.SystemId }, - { "ver", version }, + return new MBRegistrationRecord(); + } + + var success = reg.registered; + + if (!(lastChecked > DateTime.UtcNow.AddDays(-1)) || (!reg.registered)) + { + var data = new Dictionary + { + { "feature", feature }, + { "key", key }, + { "mac", _appHost.SystemId }, + { "systemid", _appHost.SystemId }, + { "ver", version }, { "platform", _appHost.OperatingSystemDisplayName } }; - try - { - var options = new HttpRequestOptions + try { - Url = MBValidateUrl, + var options = new HttpRequestOptions + { + Url = MBValidateUrl, - // Seeing block length errors - EnableHttpCompression = false, - BufferContent = false - }; + // Seeing block length errors + EnableHttpCompression = false, + BufferContent = false, + CancellationToken = cancellationToken + }; - options.SetPostData(data); + options.SetPostData(data); - using (var response = (await _httpClient.Post(options).ConfigureAwait(false))) - { - using (var json = response.Content) + using (var response = (await _httpClient.Post(options).ConfigureAwait(false))) { - reg = _jsonSerializer.DeserializeFromStream(json); - success = true; + using (var json = response.Content) + { + reg = _jsonSerializer.DeserializeFromStream(json); + success = true; + } + } + + if (reg.registered) + { + _logger.Info("Registered for feature {0}", feature); + LicenseFile.AddRegCheck(feature, reg.expDate); + } + else + { + _logger.Info("Not registered for feature {0}", feature); + LicenseFile.RemoveRegCheck(feature); } - } - if (reg.registered) - { - _logger.Info("Registered for feature {0}", feature); - LicenseFile.AddRegCheck(feature, reg.expDate); } - else + catch (Exception e) { - _logger.Info("Not registered for feature {0}", feature); - LicenseFile.RemoveRegCheck(feature); + _logger.ErrorException("Error checking registration status of {0}", e, feature); } - - } - catch (Exception e) - { - _logger.ErrorException("Error checking registration status of {0}", e, feature); } - } - var record = new MBRegistrationRecord - { - IsRegistered = reg.registered, - ExpirationDate = reg.expDate, - RegChecked = true, - RegError = !success - }; + var record = new MBRegistrationRecord + { + IsRegistered = reg.registered, + ExpirationDate = reg.expDate, + RegChecked = true, + RegError = !success + }; - record.TrialVersion = IsInTrial(reg.expDate, record.RegChecked, record.IsRegistered); - record.IsValid = !record.RegChecked || record.IsRegistered || record.TrialVersion; + record.TrialVersion = IsInTrial(reg.expDate, record.RegChecked, record.IsRegistered); + record.IsValid = !record.RegChecked || record.IsRegistered || record.TrialVersion; - return record; + return record; + } + finally + { + _regCheckLock.Release(); + } } private bool IsInTrial(DateTime expirationDate, bool regChecked, bool isRegistered) diff --git a/Emby.Server.Implementations/ServerManager/ServerManager.cs b/Emby.Server.Implementations/ServerManager/ServerManager.cs index a20e9c39ac..b06a1e4d8e 100644 --- a/Emby.Server.Implementations/ServerManager/ServerManager.cs +++ b/Emby.Server.Implementations/ServerManager/ServerManager.cs @@ -75,7 +75,6 @@ public IEnumerable WebSocketConnections private readonly List _webSocketListeners = new List(); private bool _disposed; - private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly ITextEncoding _textEncoding; /// @@ -86,7 +85,7 @@ public IEnumerable WebSocketConnections /// The logger. /// The configuration manager. /// applicationHost - public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jsonSerializer, ILogger logger, IServerConfigurationManager configurationManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding) + public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jsonSerializer, ILogger logger, IServerConfigurationManager configurationManager, ITextEncoding textEncoding) { if (applicationHost == null) { @@ -105,7 +104,6 @@ public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jso _jsonSerializer = jsonSerializer; _applicationHost = applicationHost; ConfigurationManager = configurationManager; - _memoryStreamProvider = memoryStreamProvider; _textEncoding = textEncoding; } @@ -155,7 +153,7 @@ void HttpServer_WebSocketConnected(object sender, WebSocketConnectEventArgs e) return; } - var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger, _memoryStreamProvider, _textEncoding) + var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger, _textEncoding) { OnReceive = ProcessWebSocketMessageReceived, Url = e.Url, diff --git a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs index e0a0c43f33..2bbfbda863 100644 --- a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs +++ b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs @@ -75,7 +75,6 @@ public class WebSocketConnection : IWebSocketConnection /// /// The query string. public QueryParamCollection QueryString { get; set; } - private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly ITextEncoding _textEncoding; /// @@ -86,7 +85,7 @@ public class WebSocketConnection : IWebSocketConnection /// The json serializer. /// The logger. /// socket - public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding) + public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger, ITextEncoding textEncoding) { if (socket == null) { @@ -112,7 +111,6 @@ public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerial _socket.OnReceive = OnReceiveInternal; RemoteEndPoint = remoteEndPoint; _logger = logger; - _memoryStreamProvider = memoryStreamProvider; _textEncoding = textEncoding; socket.Closed += socket_Closed; diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index 7059d0cf26..79b57438ca 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -122,7 +122,13 @@ private static async Task GetTaskResult(Task task) return null; } - var result = type.GetDeclaredProperty("Result").GetValue(task); + var resultProperty = type.GetDeclaredProperty("Result"); + if (resultProperty == null) + { + return null; + } + + var result = resultProperty.GetValue(task); // hack alert if (result.GetType().Name.IndexOf("voidtaskresult", StringComparison.OrdinalIgnoreCase) != -1) diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index f5bc73dd24..bd0a14c71b 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -93,9 +93,7 @@ public async Task ProcessRequestAsync(HttpListenerHost appHost, IRequest httpReq appHost.ApplyRequestFilters(httpReq, httpRes, request); - var rawResponse = await appHost.ServiceController.Execute(appHost, request, httpReq).ConfigureAwait(false); - - var response = rawResponse; + var response = await appHost.ServiceController.Execute(appHost, request, httpReq).ConfigureAwait(false); // Apply response filters foreach (var responseFilter in appHost.ResponseFilters) diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 1474c26ac2..61f60769d1 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -81,7 +81,7 @@ public static Guid[] GetGuids(string value) protected object ToOptimizedResult(T result) where T : class { - return ResultFactory.GetOptimizedResult(Request, result); + return ResultFactory.GetResult(Request, result); } protected void AssertCanUpdateUser(IAuthorizationContext authContext, IUserManager userManager, string userId, bool restrictUserPreferences) @@ -107,18 +107,6 @@ protected void AssertCanUpdateUser(IAuthorizationContext authContext, IUserManag } } - /// - /// To the optimized serialized result using cache. - /// - /// - /// The result. - /// System.Object. - protected object ToOptimizedSerializedResultUsingCache(T result) - where T : class - { - return ToOptimizedResult(result); - } - /// /// Gets the session. /// diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index 8e65f21ce0..0b346de579 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -140,7 +140,7 @@ public void Post(UpdateNamedConfiguration request) public object Get(GetDefaultMetadataOptions request) { - return ToOptimizedSerializedResultUsingCache(new MetadataOptions()); + return ToOptimizedResult(new MetadataOptions()); } } } diff --git a/MediaBrowser.Api/DisplayPreferencesService.cs b/MediaBrowser.Api/DisplayPreferencesService.cs index 4f8cc52558..6bc2f7e4af 100644 --- a/MediaBrowser.Api/DisplayPreferencesService.cs +++ b/MediaBrowser.Api/DisplayPreferencesService.cs @@ -76,7 +76,7 @@ public object Get(GetDisplayPreferences request) { var result = _displayPreferencesManager.GetDisplayPreferences(request.Id, request.UserId, request.Client); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index eef256f974..ea3920d38d 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -200,10 +200,10 @@ public object Get(GetDirectoryContents request) if (path.StartsWith(networkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf(UncSeparator) == 1) { - return ToOptimizedSerializedResultUsingCache(GetNetworkShares(path).OrderBy(i => i.Path).ToList()); + return ToOptimizedResult(GetNetworkShares(path).OrderBy(i => i.Path).ToList()); } - return ToOptimizedSerializedResultUsingCache(GetFileSystemEntries(request).ToList()); + return ToOptimizedResult(GetFileSystemEntries(request).ToList()); } public object Get(GetNetworkShares request) @@ -212,7 +212,7 @@ public object Get(GetNetworkShares request) var shares = GetNetworkShares(path).OrderBy(i => i.Path).ToList(); - return ToOptimizedSerializedResultUsingCache(shares); + return ToOptimizedResult(shares); } /// @@ -224,7 +224,7 @@ public object Get(GetDrives request) { var result = GetDrives().ToList(); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -250,7 +250,7 @@ public object Get(GetNetworkDevices request) { var result = _networkManager.GetNetworkDevices().ToList(); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index b591db25d5..8e597b471b 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -109,7 +109,7 @@ public object Get(GetGameSystemSummaries request) .Select(i => GetSummary(i, user)) .ToArray(); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -159,7 +159,7 @@ public object Get(GetSimilarGames request) { var result = GetSimilarItemsResult(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 7a35aa9729..2d24fb0bbc 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -265,7 +265,7 @@ public object Get(GetItemImageInfos request) var result = GetItemImageInfos(item); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index bea2cacaa1..97ac9138e3 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -129,7 +129,7 @@ public object Get(GetRemoteImageProviders request) var result = GetImageProviders(item); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } private List GetImageProviders(BaseItem item) diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 8431c5a42d..cbd102a8b2 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -888,7 +888,7 @@ public object Get(GetPhyscialPaths request) .SelectMany(c => c.PhysicalLocations) .ToList(); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -900,7 +900,7 @@ public object Get(GetAncestors request) { var result = GetAncestors(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -978,7 +978,7 @@ public object Get(GetItemCounts request) BookCount = GetCount(typeof(Book), user, request) }; - return ToOptimizedSerializedResultUsingCache(counts); + return ToOptimizedResult(counts); } private int GetCount(Type type, User user, GetItemCounts request) @@ -1082,7 +1082,7 @@ public object Get(GetThemeMedia request) }); - return ToOptimizedSerializedResultUsingCache(new AllThemeMediaResult + return ToOptimizedResult(new AllThemeMediaResult { ThemeSongsResult = themeSongs, ThemeVideosResult = themeVideos, @@ -1100,7 +1100,7 @@ public object Get(GetThemeSongs request) { var result = GetThemeSongs(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } private ThemeMediaResult GetThemeSongs(GetThemeSongs request) @@ -1157,7 +1157,7 @@ public object Get(GetThemeVideos request) { var result = GetThemeVideos(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public ThemeMediaResult GetThemeVideos(GetThemeVideos request) diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index fc624b93ab..bba89acec6 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -210,7 +210,7 @@ public object Get(GetVirtualFolders request) { var result = _libraryManager.GetVirtualFolders(true); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public void Post(UpdateLibraryOptions request) diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 9a102e7caf..880cf69cdc 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -17,7 +17,7 @@ using System.Threading.Tasks; using MediaBrowser.Api.UserLibrary; using MediaBrowser.Model.IO; - +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Services; @@ -707,8 +707,9 @@ public class LiveTvService : BaseApiService private readonly ISessionContext _sessionContext; private readonly IEnvironmentInfo _environment; private ICryptoProvider _cryptographyProvider; + private IStreamHelper _streamHelper; - public LiveTvService(ICryptoProvider crypto, ILiveTvManager liveTvManager, IUserManager userManager, IServerConfigurationManager config, IHttpClient httpClient, ILibraryManager libraryManager, IDtoService dtoService, IFileSystem fileSystem, IAuthorizationContext authContext, ISessionContext sessionContext, IEnvironmentInfo environment) + public LiveTvService(ICryptoProvider crypto, IStreamHelper streamHelper, ILiveTvManager liveTvManager, IUserManager userManager, IServerConfigurationManager config, IHttpClient httpClient, ILibraryManager libraryManager, IDtoService dtoService, IFileSystem fileSystem, IAuthorizationContext authContext, ISessionContext sessionContext, IEnvironmentInfo environment) { _liveTvManager = liveTvManager; _userManager = userManager; @@ -721,6 +722,7 @@ public LiveTvService(ICryptoProvider crypto, ILiveTvManager liveTvManager, IUser _sessionContext = sessionContext; _environment = environment; _cryptographyProvider = crypto; + _streamHelper = streamHelper; } public object Get(GetTunerHostTypes request) @@ -742,7 +744,7 @@ public object Get(GetRecordingFolders request) TotalRecordCount = returnArray.Length }; - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public object Get(GetLiveRecordingFile request) @@ -758,7 +760,7 @@ public object Get(GetLiveRecordingFile request) outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path); - return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, Logger, _environment) + return new ProgressiveFileCopier(_fileSystem, _streamHelper, path, outputHeaders, Logger, _environment) { AllowEndOfFile = false }; @@ -777,7 +779,7 @@ public async Task Get(GetLiveStreamFile request) outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container); - return new ProgressiveFileCopier(directStreamProvider, outputHeaders, Logger, _environment) + return new ProgressiveFileCopier(directStreamProvider , _streamHelper, outputHeaders, Logger, _environment) { AllowEndOfFile = false }; @@ -913,14 +915,14 @@ public async Task Get(GetLineups request) { var info = await _liveTvManager.GetLineups(request.Type, request.Id, request.Country, request.Location).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(info); + return ToOptimizedResult(info); } public object Get(GetLiveTvInfo request) { var info = _liveTvManager.GetLiveTvInfo(CancellationToken.None); - return ToOptimizedSerializedResultUsingCache(info); + return ToOptimizedResult(info); } public object Get(GetChannels request) @@ -962,7 +964,7 @@ public object Get(GetChannels request) TotalRecordCount = channelResult.TotalRecordCount }; - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } private void RemoveFields(DtoOptions options) @@ -986,7 +988,7 @@ public object Get(GetChannel request) var result = _dtoService.GetBaseItemDto(item, dtoOptions, user); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public object Get(GetLiveTvFolder request) @@ -1121,14 +1123,14 @@ public async Task Get(GetRecording request) var result = _dtoService.GetBaseItemDto(item, dtoOptions, user); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public async Task Get(GetTimer request) { var result = await _liveTvManager.GetTimer(request.Id, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public async Task Get(GetTimers request) @@ -1142,7 +1144,7 @@ public async Task Get(GetTimers request) }, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public void Delete(DeleteRecording request) @@ -1178,14 +1180,14 @@ public async Task Get(GetSeriesTimers request) }, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public async Task Get(GetSeriesTimer request) { var result = await _liveTvManager.GetSeriesTimer(request.Id, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public Task Delete(CancelSeriesTimer request) @@ -1208,13 +1210,13 @@ public async Task Get(GetDefaultTimer request) { var result = await _liveTvManager.GetNewTimerDefaults(CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } else { var result = await _liveTvManager.GetNewTimerDefaults(request.ProgramId, CancellationToken.None).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } } @@ -1224,7 +1226,7 @@ public async Task Get(GetProgram request) var result = await _liveTvManager.GetProgram(request.Id, CancellationToken.None, user).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public Task Post(CreateSeriesTimer request) diff --git a/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs b/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs index 74293ccd90..0a6ccd4c5c 100644 --- a/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs +++ b/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Services; using MediaBrowser.Model.System; +using MediaBrowser.Controller.IO; namespace MediaBrowser.Api.LiveTv { @@ -20,28 +21,30 @@ public class ProgressiveFileCopier : IAsyncStreamWriter, IHasHeaders const int StreamCopyToBufferSize = 81920; - private long _bytesWritten = 0; public long StartPosition { get; set; } public bool AllowEndOfFile = true; private readonly IDirectStreamProvider _directStreamProvider; private readonly IEnvironmentInfo _environment; + private IStreamHelper _streamHelper; - public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary outputHeaders, ILogger logger, IEnvironmentInfo environment) + public ProgressiveFileCopier(IFileSystem fileSystem, IStreamHelper streamHelper, string path, Dictionary outputHeaders, ILogger logger, IEnvironmentInfo environment) { _fileSystem = fileSystem; _path = path; _outputHeaders = outputHeaders; _logger = logger; _environment = environment; + _streamHelper = streamHelper; } - public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, Dictionary outputHeaders, ILogger logger, IEnvironmentInfo environment) + public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, IStreamHelper streamHelper, Dictionary outputHeaders, ILogger logger, IEnvironmentInfo environment) { _directStreamProvider = directStreamProvider; _outputHeaders = outputHeaders; _logger = logger; _environment = environment; + _streamHelper = streamHelper; } public IDictionary Headers @@ -75,7 +78,7 @@ public async Task WriteToAsync(Stream outputStream, CancellationToken cancellati var eofCount = 0; // use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039 - var allowAsyncFileRead = _environment.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows; + var allowAsyncFileRead = true; using (var inputStream = GetInputStream(allowAsyncFileRead)) { @@ -89,14 +92,7 @@ public async Task WriteToAsync(Stream outputStream, CancellationToken cancellati while (eofCount < emptyReadLimit) { int bytesRead; - if (allowAsyncFileRead) - { - bytesRead = await CopyToInternalAsync(inputStream, outputStream, cancellationToken).ConfigureAwait(false); - } - else - { - bytesRead = await CopyToInternalAsyncWithSyncRead(inputStream, outputStream, cancellationToken).ConfigureAwait(false); - } + bytesRead = await _streamHelper.CopyToAsync(inputStream, outputStream, cancellationToken).ConfigureAwait(false); //var position = fs.Position; //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); @@ -113,49 +109,5 @@ public async Task WriteToAsync(Stream outputStream, CancellationToken cancellati } } } - - private async Task CopyToInternalAsyncWithSyncRead(Stream source, Stream destination, CancellationToken cancellationToken) - { - var array = new byte[StreamCopyToBufferSize]; - int bytesRead; - int totalBytesRead = 0; - - while ((bytesRead = source.Read(array, 0, array.Length)) != 0) - { - var bytesToWrite = bytesRead; - - if (bytesToWrite > 0) - { - await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false); - - _bytesWritten += bytesRead; - totalBytesRead += bytesRead; - } - } - - return totalBytesRead; - } - - private async Task CopyToInternalAsync(Stream source, Stream destination, CancellationToken cancellationToken) - { - var array = new byte[StreamCopyToBufferSize]; - int bytesRead; - int totalBytesRead = 0; - - while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0) - { - var bytesToWrite = bytesRead; - - if (bytesToWrite > 0) - { - await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false); - - _bytesWritten += bytesRead; - totalBytesRead += bytesRead; - } - } - - return totalBytesRead; - } } } diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 7f65173246..bbdbbcf633 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -117,14 +117,14 @@ public object Get(GetSimilarMovies request) { var result = GetSimilarItemsResult(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public object Get(GetSimilarTrailers request) { var result = GetSimilarItemsResult(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public object Get(GetMovieRecommendations request) diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index d7986fa501..538840f6c4 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -64,7 +64,7 @@ public object Get(GetSimilarArtists request) request, new[] { typeof(MusicArtist) }, SimilarItemsHelper.GetSimiliarityScore); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -85,7 +85,7 @@ public object Get(GetSimilarAlbums request) request, new[] { typeof(MusicAlbum) }, GetAlbumSimilarityScore); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/NewsService.cs b/MediaBrowser.Api/NewsService.cs index 542103799b..cbc77bfc9a 100644 --- a/MediaBrowser.Api/NewsService.cs +++ b/MediaBrowser.Api/NewsService.cs @@ -40,7 +40,7 @@ public object Get(GetProductNews request) }); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } } } diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 72d9206c2e..ab5090d625 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -240,7 +240,7 @@ public async Task Get(GetPlugins request) } } - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -269,7 +269,7 @@ public async Task Get(GetPluginSecurityInfo request) SupporterKey = _securityManager.SupporterKey }; - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index b6cd583c49..d44c6d6157 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -138,7 +138,7 @@ public async Task Get(GetSearchHints request) { var result = await GetSearchHintsAsync(request).ConfigureAwait(false); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index c38e80b382..29ed7a44aa 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -297,7 +297,7 @@ public object Get(GetSimilarShows request) { var result = GetSimilarItemsResult(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) @@ -365,7 +365,7 @@ public object Get(GetUpcomingEpisodes request) Items = returnItems }; - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -391,7 +391,7 @@ public object Get(GetNextUpEpisodes request) var returnItems = _dtoService.GetBaseItemDtos(result.Items, options, user); - return ToOptimizedSerializedResultUsingCache(new QueryResult + return ToOptimizedResult(new QueryResult { TotalRecordCount = result.TotalRecordCount, Items = returnItems diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs index 0b2ca4daf9..dd1da7b862 100644 --- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs @@ -46,7 +46,7 @@ public object Get(GetGameGenre request) { var result = GetItem(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -79,7 +79,7 @@ public object Get(GetGameGenres request) { var result = GetResultSlim(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query) diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index d913f52d96..9bf38a78a1 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -56,7 +56,7 @@ public object Get(GetGenre request) { var result = GetItem(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -89,7 +89,7 @@ public object Get(GetGenres request) { var result = GetResultSlim(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query) diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index cc51313786..246e1bd2cc 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -130,7 +130,7 @@ public object Get(GetResumeItems request) Items = returnItems }; - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -147,7 +147,7 @@ public object Get(GetItems request) var result = GetItems(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs index 36dc773d4d..90da90bc20 100644 --- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs @@ -47,7 +47,7 @@ public object Get(GetMusicGenre request) { var result = GetItem(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -80,7 +80,7 @@ public object Get(GetMusicGenres request) { var result = GetResultSlim(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query) diff --git a/MediaBrowser.Api/UserLibrary/PersonsService.cs b/MediaBrowser.Api/UserLibrary/PersonsService.cs index 7093b0ac8c..efd4c9415b 100644 --- a/MediaBrowser.Api/UserLibrary/PersonsService.cs +++ b/MediaBrowser.Api/UserLibrary/PersonsService.cs @@ -55,7 +55,7 @@ public object Get(GetPerson request) { var result = GetItem(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -88,7 +88,7 @@ public object Get(GetPersons request) { var result = GetResult(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs index f10cccbb13..54248c5fd8 100644 --- a/MediaBrowser.Api/UserLibrary/StudiosService.cs +++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs @@ -56,7 +56,7 @@ public object Get(GetStudio request) { var result = GetItem(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -89,7 +89,7 @@ public object Get(GetStudios request) { var result = GetResultSlim(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } protected override QueryResult> GetItems(GetItemsByName request, InternalItemsQuery query) diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 2d13947fc5..80a6a5f070 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -291,7 +291,7 @@ public object Get(GetSpecialFeatures request) { var result = GetAsync(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public object Get(GetLatestMedia request) @@ -413,7 +413,7 @@ public object Get(GetLocalTrailers request) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)) .ToArray(); - return ToOptimizedSerializedResultUsingCache(dtos); + return ToOptimizedResult(dtos); } /// @@ -433,7 +433,7 @@ public async Task Get(GetItem request) var result = _dtoService.GetBaseItemDto(item, dtoOptions, user); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } private async Task RefreshItemOnDemandIfNeeded(BaseItem item) @@ -472,7 +472,7 @@ public object Get(GetRootFolder request) var result = _dtoService.GetBaseItemDto(item, dtoOptions, user); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -498,7 +498,7 @@ public async Task Get(GetIntros request) TotalRecordCount = dtos.Length }; - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/UserLibrary/YearsService.cs b/MediaBrowser.Api/UserLibrary/YearsService.cs index db622a9b34..676c1a911c 100644 --- a/MediaBrowser.Api/UserLibrary/YearsService.cs +++ b/MediaBrowser.Api/UserLibrary/YearsService.cs @@ -54,7 +54,7 @@ public object Get(GetYear request) { var result = GetItem(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// @@ -87,7 +87,7 @@ public object Get(GetYears request) { var result = GetResult(request); - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs index c89b55ad29..e1b335ca83 100644 --- a/MediaBrowser.Api/VideosService.cs +++ b/MediaBrowser.Api/VideosService.cs @@ -105,7 +105,7 @@ public object Get(GetAdditionalParts request) TotalRecordCount = items.Length }; - return ToOptimizedSerializedResultUsingCache(result); + return ToOptimizedResult(result); } public void Delete(DeleteAlternateSources request) diff --git a/MediaBrowser.Controller/Drawing/ImageHelper.cs b/MediaBrowser.Controller/Drawing/ImageHelper.cs index bd1aac6ed4..827036fe8a 100644 --- a/MediaBrowser.Controller/Drawing/ImageHelper.cs +++ b/MediaBrowser.Controller/Drawing/ImageHelper.cs @@ -12,7 +12,7 @@ public static ImageSize GetNewImageSize(ImageProcessingOptions options, ImageSiz if (originalImageSize.HasValue) { // Determine the output size based on incoming parameters - var newSize = DrawingUtils.Resize(originalImageSize.Value, options.Width, options.Height, options.MaxWidth, options.MaxHeight); + var newSize = DrawingUtils.Resize(originalImageSize.Value, options.Width ?? 0, options.Height ?? 0, options.MaxWidth ?? 0, options.MaxHeight ?? 0); return newSize; } diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs index fa2fc83bb5..3ff0772718 100644 --- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs +++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs @@ -5,8 +5,8 @@ namespace MediaBrowser.Controller.Entities public interface IHasProgramAttributes { bool IsMovie { get; set; } - bool IsSports { get; set; } - bool IsNews { get; set; } + bool IsSports { get; } + bool IsNews { get; } bool IsKids { get; } bool IsRepeat { get; set; } bool? IsHD { get; set; } diff --git a/MediaBrowser.Controller/IO/StreamHelper.cs b/MediaBrowser.Controller/IO/StreamHelper.cs deleted file mode 100644 index 5aec9a1828..0000000000 --- a/MediaBrowser.Controller/IO/StreamHelper.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.IO; -using System.Threading; -using System; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.IO -{ - public static class StreamHelper - { - public static void CopyTo(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken) - { - byte[] buffer = new byte[bufferSize]; - int read; - while ((read = source.Read(buffer, 0, buffer.Length)) != 0) - { - cancellationToken.ThrowIfCancellationRequested(); - - destination.Write(buffer, 0, read); - - if (onStarted != null) - { - onStarted(); - onStarted = null; - } - } - } - - public static async Task CopyToAsync(Stream source, Stream destination, int bufferSize, IProgress progress, long contentLength, CancellationToken cancellationToken) - { - byte[] buffer = new byte[bufferSize]; - int read; - long totalRead = 0; - - while ((read = source.Read(buffer, 0, buffer.Length)) != 0) - { - cancellationToken.ThrowIfCancellationRequested(); - - destination.Write(buffer, 0, read); - - totalRead += read; - - double pct = totalRead; - pct /= contentLength; - pct *= 100; - - progress.Report(pct); - } - } - } -} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index eed4431fc1..c667b4aa1f 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -134,7 +134,13 @@ public override SourceType SourceType /// /// true if this instance is sports; otherwise, false. [IgnoreDataMember] - public bool IsSports { get; set; } + public bool IsSports + { + get + { + return Tags.Contains("Sports", StringComparer.OrdinalIgnoreCase); + } + } /// /// Gets or sets a value indicating whether this instance is series. @@ -161,7 +167,13 @@ public bool IsLive /// /// true if this instance is news; otherwise, false. [IgnoreDataMember] - public bool IsNews { get; set; } + public bool IsNews + { + get + { + return Tags.Contains("News", StringComparer.OrdinalIgnoreCase); + } + } /// /// Gets or sets a value indicating whether this instance is kids. diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs index 68ec32b511..baf0b0b138 100644 --- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs @@ -122,8 +122,20 @@ public bool IsKids return Tags.Contains("Kids", StringComparer.OrdinalIgnoreCase); } } - public bool IsSports { get; set; } - public bool IsNews { get; set; } + public bool IsSports + { + get + { + return Tags.Contains("Sports", StringComparer.OrdinalIgnoreCase); + } + } + public bool IsNews + { + get + { + return Tags.Contains("News", StringComparer.OrdinalIgnoreCase); + } + } public bool IsSeries { get; set; } /// diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 97b2f52f3c..6d7b3c111f 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -121,7 +121,6 @@ - diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index a625325ba7..97fca9b1cd 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -366,10 +366,10 @@ public int? OutputWidth }; var newSize = DrawingUtils.Resize(size, - BaseRequest.Width, - BaseRequest.Height, - BaseRequest.MaxWidth, - BaseRequest.MaxHeight); + BaseRequest.Width ?? 0, + BaseRequest.Height ?? 0, + BaseRequest.MaxWidth ?? 0, + BaseRequest.MaxHeight ?? 0); return Convert.ToInt32(newSize.Width); } @@ -396,10 +396,10 @@ public int? OutputHeight }; var newSize = DrawingUtils.Resize(size, - BaseRequest.Width, - BaseRequest.Height, - BaseRequest.MaxWidth, - BaseRequest.MaxHeight); + BaseRequest.Width ?? 0, + BaseRequest.Height ?? 0, + BaseRequest.MaxWidth ?? 0, + BaseRequest.MaxHeight ?? 0); return Convert.ToInt32(newSize.Height); } diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index e6695a9355..03f27858a0 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -56,11 +56,6 @@ protected BasePeriodicWebSocketListener(ILogger logger, ITimerFactory timerFacto TimerFactory = timerFactory; } - /// - /// The null task result - /// - protected Task NullTaskResult = Task.FromResult(true); - /// /// Processes the message. /// @@ -83,7 +78,7 @@ public Task ProcessMessage(WebSocketMessageInfo message) Stop(message); } - return NullTaskResult; + return Task.FromResult(true); } protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs index 5dae85c7fb..1b3cc8e8e5 100644 --- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs @@ -20,35 +20,17 @@ public interface IHttpResultFactory /// Type of the content. /// The response headers. /// System.Object. - object GetResult(object content, string contentType, IDictionary responseHeaders = null); + object GetResult(byte[] content, string contentType, IDictionary responseHeaders = null); - object GetResult(IRequest requestContext, object content, string contentType, IDictionary responseHeaders = null); + object GetResult(Stream content, string contentType, IDictionary responseHeaders = null); - object GetRedirectResult(string url); + object GetResult(string content, string contentType, IDictionary responseHeaders = null); - /// - /// Gets the optimized result. - /// - /// - /// The request context. - /// The result. - /// The response headers. - /// System.Object. - object GetOptimizedResult(IRequest requestContext, T result, IDictionary responseHeaders = null) - where T : class; + object GetResult(IRequest requestContext, string content, string contentType, IDictionary responseHeaders = null); - /// - /// Gets the optimized result using cache. - /// - /// - /// The request context. - /// The cache key. - /// The last date modified. - /// Duration of the cache. - /// The factory function that creates the response object. - /// The response headers. - /// System.Object. - object GetOptimizedResultUsingCache(IRequest requestContext, Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func factoryFn, IDictionary responseHeaders = null) + object GetRedirectResult(string url); + + object GetResult(IRequest requestContext, T result, IDictionary responseHeaders = null) where T : class; /// diff --git a/MediaBrowser.Controller/Net/StaticResultOptions.cs b/MediaBrowser.Controller/Net/StaticResultOptions.cs index 3064cbf101..1c9b2586d1 100644 --- a/MediaBrowser.Controller/Net/StaticResultOptions.cs +++ b/MediaBrowser.Controller/Net/StaticResultOptions.cs @@ -24,6 +24,7 @@ public class StaticResultOptions public Action OnError { get; set; } public string Path { get; set; } + public long? ContentLength { get; set; } public FileShareMode FileShare { get; set; } diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs index 8f25643ba1..2bcc532642 100644 --- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -325,7 +325,7 @@ public static void AddCommonNodes(BaseItem item, XmlWriter writer, ILibraryManag { var timespan = TimeSpan.FromTicks(runTimeTicks.Value); - writer.WriteElementString("RunningTime", Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture)); + writer.WriteElementString("RunningTime", Math.Floor(timespan.TotalMinutes).ToString(UsCulture)); } if (item.ProviderIds != null) diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 645ec73b1a..94925cf2cf 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -986,10 +986,10 @@ public int? TargetWidth double? maxHeight = MaxHeight.HasValue ? (double)MaxHeight.Value : (double?)null; ImageSize newSize = DrawingUtils.Resize(size, - null, - null, - maxWidth, - maxHeight); + 0, + 0, + maxWidth ?? 0, + maxHeight ?? 0); return Convert.ToInt32(newSize.Width); } @@ -1016,10 +1016,10 @@ public int? TargetHeight double? maxHeight = MaxHeight.HasValue ? (double)MaxHeight.Value : (double?)null; ImageSize newSize = DrawingUtils.Resize(size, - null, - null, - maxWidth, - maxHeight); + 0, + 0, + maxWidth ?? 0, + maxHeight ?? 0); return Convert.ToInt32(newSize.Height); } diff --git a/MediaBrowser.Model/Drawing/DrawingUtils.cs b/MediaBrowser.Model/Drawing/DrawingUtils.cs index fcc5ddd161..e6235cb06f 100644 --- a/MediaBrowser.Model/Drawing/DrawingUtils.cs +++ b/MediaBrowser.Model/Drawing/DrawingUtils.cs @@ -5,61 +5,6 @@ /// public static class DrawingUtils { - /// - /// Resizes a set of dimensions - /// - /// Width of the current. - /// Height of the current. - /// The scale factor. - /// ImageSize. - public static ImageSize Scale(double currentWidth, double currentHeight, double scaleFactor) - { - return Scale(new ImageSize - { - Width = currentWidth, - Height = currentHeight - - }, scaleFactor); - } - - /// - /// Resizes a set of dimensions - /// - /// The size. - /// The scale factor. - /// ImageSize. - public static ImageSize Scale(ImageSize size, double scaleFactor) - { - double newWidth = size.Width * scaleFactor; - - return Resize(size.Width, size.Height, newWidth, null, null, null); - } - - /// - /// Resizes a set of dimensions - /// - /// Width of the current. - /// Height of the current. - /// The width. - /// The height. - /// A max fixed width, if desired - /// A max fixed height, if desired - /// ImageSize. - public static ImageSize Resize(double currentWidth, - double currentHeight, - double? width, - double? height, - double? maxWidth, - double? maxHeight) - { - return Resize(new ImageSize - { - Width = currentWidth, - Height = currentHeight - - }, width, height, maxWidth, maxHeight); - } - /// /// Resizes a set of dimensions /// @@ -69,43 +14,43 @@ public static ImageSize Resize(double currentWidth, /// A max fixed width, if desired /// A max fixed height, if desired /// A new size object - public static ImageSize Resize(ImageSize size, - double? width, - double? height, - double? maxWidth, - double? maxHeight) + public static ImageSize Resize(ImageSize size, + double width, + double height, + double maxWidth, + double maxHeight) { double newWidth = size.Width; double newHeight = size.Height; - if (width.HasValue && height.HasValue) + if (width > 0 && height > 0) { - newWidth = width.Value; - newHeight = height.Value; + newWidth = width; + newHeight = height; } - else if (height.HasValue) + else if (height > 0) { - newWidth = GetNewWidth(newHeight, newWidth, height.Value); - newHeight = height.Value; + newWidth = GetNewWidth(newHeight, newWidth, height); + newHeight = height; } - else if (width.HasValue) + else if (width > 0) { - newHeight = GetNewHeight(newHeight, newWidth, width.Value); - newWidth = width.Value; + newHeight = GetNewHeight(newHeight, newWidth, width); + newWidth = width; } - if (maxHeight.HasValue && maxHeight.Value < newHeight) + if (maxHeight > 0 && maxHeight < newHeight) { - newWidth = GetNewWidth(newHeight, newWidth, maxHeight.Value); - newHeight = maxHeight.Value; + newWidth = GetNewWidth(newHeight, newWidth, maxHeight); + newHeight = maxHeight; } - if (maxWidth.HasValue && maxWidth.Value < newWidth) + if (maxWidth > 0 && maxWidth < newWidth) { - newHeight = GetNewHeight(newHeight, newWidth, maxWidth.Value); - newWidth = maxWidth.Value; + newHeight = GetNewHeight(newHeight, newWidth, maxWidth); + newWidth = maxWidth; } return new ImageSize { Width = newWidth, Height = newHeight }; diff --git a/MediaBrowser.Model/Entities/DisplayPreferences.cs b/MediaBrowser.Model/Entities/DisplayPreferences.cs index 0ba8eaa4f4..dc386f7753 100644 --- a/MediaBrowser.Model/Entities/DisplayPreferences.cs +++ b/MediaBrowser.Model/Entities/DisplayPreferences.cs @@ -95,29 +95,5 @@ public DisplayPreferences() /// Gets or sets the client /// public string Client { get; set; } - - /// - /// Increases the size of the image. - /// - public void IncreaseImageSize() - { - double newWidth = PrimaryImageWidth / ImageScale; - - ImageSize size = DrawingUtils.Resize(PrimaryImageWidth, PrimaryImageHeight, newWidth, null, null, null); - - PrimaryImageWidth = Convert.ToInt32(size.Width); - PrimaryImageHeight = Convert.ToInt32(size.Height); - } - - /// - /// Decreases the size of the image. - /// - public void DecreaseImageSize() - { - ImageSize size = DrawingUtils.Scale(PrimaryImageWidth, PrimaryImageHeight, ImageScale); - - PrimaryImageWidth = Convert.ToInt32(size.Width); - PrimaryImageHeight = Convert.ToInt32(size.Height); - } } } diff --git a/MediaBrowser.Model/IO/IStreamHelper.cs b/MediaBrowser.Model/IO/IStreamHelper.cs new file mode 100644 index 0000000000..7ed6015c00 --- /dev/null +++ b/MediaBrowser.Model/IO/IStreamHelper.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Model.IO +{ + public interface IStreamHelper + { + Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken); + + Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken); + + Task CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken); + Task CopyToAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken); + + Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 57f0c6c8d8..95b8d37fe8 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -97,6 +97,7 @@ + diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 6665da5d4a..d66d62fea2 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -87,7 +87,7 @@ private static Dictionary GetMimeTypeLookup() dict.Add(".asf", "video/x-ms-asf"); dict.Add(".m4v", "video/x-m4v"); dict.Add(".m4s", "video/mp4"); - dict.Add(".cbz", "application/epub+zip"); + dict.Add(".cbz", "application/x-cbz"); dict.Add(".cbr", "application/epub+zip"); dict.Add(".epub", "application/epub+zip"); dict.Add(".pdf", "application/pdf"); diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 55c9f4964b..c4d0c49293 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -39,7 +39,6 @@ public class ImageSaver private readonly ILibraryMonitor _libraryMonitor; private readonly IFileSystem _fileSystem; private readonly ILogger _logger; - private readonly IMemoryStreamFactory _memoryStreamProvider; /// /// Initializes a new instance of the class. @@ -48,13 +47,12 @@ public class ImageSaver /// The directory watchers. /// The file system. /// The logger. - public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger, IMemoryStreamFactory memoryStreamProvider) + public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger) { _config = config; _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; _logger = logger; - _memoryStreamProvider = memoryStreamProvider; } /// diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 8f040a7aca..185c420498 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -68,7 +68,6 @@ public class ProviderManager : IProviderManager, IDisposable private IExternalId[] _externalIds; private readonly Func _libraryManagerFactory; - private readonly IMemoryStreamFactory _memoryStreamProvider; private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); public event EventHandler> RefreshStarted; @@ -80,7 +79,7 @@ public class ProviderManager : IProviderManager, IDisposable /// /// Initializes a new instance of the class. /// - public ProviderManager(IHttpClient httpClient, ISubtitleManager subtitleManager, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func libraryManagerFactory, IJsonSerializer json, IMemoryStreamFactory memoryStreamProvider) + public ProviderManager(IHttpClient httpClient, ISubtitleManager subtitleManager, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func libraryManagerFactory, IJsonSerializer json) { _logger = logManager.GetLogger("ProviderManager"); _httpClient = httpClient; @@ -90,7 +89,6 @@ public ProviderManager(IHttpClient httpClient, ISubtitleManager subtitleManager, _appPaths = appPaths; _libraryManagerFactory = libraryManagerFactory; _json = json; - _memoryStreamProvider = memoryStreamProvider; _subtitleManager = subtitleManager; } @@ -176,7 +174,7 @@ public async Task SaveImage(BaseItem item, string url, ImageType type, int? imag public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken) { - return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken); + return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken); } public Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken) @@ -188,7 +186,7 @@ public Task SaveImage(BaseItem item, string source, string mimeType, ImageType t var fileStream = _fileSystem.GetFileStream(source, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, true); - return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken); + return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken); } public async Task> GetAvailableRemoteImages(BaseItem item, RemoteImageQuery query, CancellationToken cancellationToken) @@ -361,7 +359,7 @@ private bool CanRefresh(IMetadataProvider provider, BaseItem item, LibraryOption // If this restriction is ever lifted, movie xml providers will have to be updated to prevent owned items like trailers from reading those files if (checkIsOwnedItem && item.ExtraType.HasValue) { - if (provider is ILocalMetadataProvider || provider is IRemoteMetadataProvider) + if (provider is ILocalMetadataProvider) { return false; } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index b7bdadc623..2c8a7ef90c 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -36,10 +36,9 @@ public class TvdbSeriesProvider : IRemoteMetadataProvider, I private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; - private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly ILocalizationManager _localizationManager; - public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IMemoryStreamFactory memoryStreamProvider, IXmlReaderSettingsFactory xmlSettings, ILocalizationManager localizationManager) + public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IXmlReaderSettingsFactory xmlSettings, ILocalizationManager localizationManager) { _zipClient = zipClient; _httpClient = httpClient; @@ -47,7 +46,6 @@ public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSys _config = config; _logger = logger; _libraryManager = libraryManager; - _memoryStreamProvider = memoryStreamProvider; _xmlSettings = xmlSettings; _localizationManager = localizationManager; Current = this; diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 94915b0114..2f68b3ea96 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -119,13 +119,12 @@ public class DashboardService : IService, IRequiresRequest private readonly ILocalizationManager _localization; private readonly IJsonSerializer _jsonSerializer; private readonly IAssemblyInfo _assemblyInfo; - private readonly IMemoryStreamFactory _memoryStreamFactory; private IResourceFileManager _resourceFileManager; /// /// Initializes a new instance of the class. /// - public DashboardService(IServerApplicationHost appHost, IResourceFileManager resourceFileManager, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, ILocalizationManager localization, IJsonSerializer jsonSerializer, IAssemblyInfo assemblyInfo, ILogger logger, IHttpResultFactory resultFactory, IMemoryStreamFactory memoryStreamFactory) + public DashboardService(IServerApplicationHost appHost, IResourceFileManager resourceFileManager, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, ILocalizationManager localization, IJsonSerializer jsonSerializer, IAssemblyInfo assemblyInfo, ILogger logger, IHttpResultFactory resultFactory) { _appHost = appHost; _serverConfigurationManager = serverConfigurationManager; @@ -135,7 +134,6 @@ public DashboardService(IServerApplicationHost appHost, IResourceFileManager res _assemblyInfo = assemblyInfo; _logger = logger; _resultFactory = resultFactory; - _memoryStreamFactory = memoryStreamFactory; _resourceFileManager = resourceFileManager; } @@ -371,7 +369,7 @@ private Task GetResourceStream(string basePath, string virtualPath, stri private PackageCreator GetPackageCreator(string basePath) { - return new PackageCreator(basePath, _fileSystem, _logger, _serverConfigurationManager, _memoryStreamFactory, _resourceFileManager); + return new PackageCreator(basePath, _fileSystem, _logger, _serverConfigurationManager, _resourceFileManager); } public async Task Get(GetDashboardPackage request) diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 0161a22f06..cbd6ac8bbf 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -20,16 +20,14 @@ public class PackageCreator private readonly IFileSystem _fileSystem; private readonly ILogger _logger; private readonly IServerConfigurationManager _config; - private readonly IMemoryStreamFactory _memoryStreamFactory; private readonly string _basePath; private IResourceFileManager _resourceFileManager; - public PackageCreator(string basePath, IFileSystem fileSystem, ILogger logger, IServerConfigurationManager config, IMemoryStreamFactory memoryStreamFactory, IResourceFileManager resourceFileManager) + public PackageCreator(string basePath, IFileSystem fileSystem, ILogger logger, IServerConfigurationManager config, IResourceFileManager resourceFileManager) { _fileSystem = fileSystem; _logger = logger; _config = config; - _memoryStreamFactory = memoryStreamFactory; _basePath = basePath; _resourceFileManager = resourceFileManager; } diff --git a/MediaBrowser.WebDashboard/dashboard-ui/addplugin.html b/MediaBrowser.WebDashboard/dashboard-ui/addplugin.html index e0deb22aff..52395cc0cf 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/addplugin.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/addplugin.html @@ -6,7 +6,7 @@
-
+ diff --git a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js index 5213038bb3..2cc48e59cd 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js +++ b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js @@ -1 +1 @@ -define(["browser"],function(browser){"use strict";function canPlayH264(videoTestElement){return!(!videoTestElement.canPlayType||!videoTestElement.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/,""))}function canPlayH265(videoTestElement,options){if(browser.tizen||browser.orsay||browser.xboxOne||browser.web0s||options.supportsHevc)return!0;var userAgent=navigator.userAgent.toLowerCase();if(browser.chromecast){if(-1!==userAgent.indexOf("aarch64"))return!0}return!!(browser.iOS&&(browser.iOSVersion||0)>=11)||!(!videoTestElement.canPlayType||!videoTestElement.canPlayType('video/hevc; codecs="hevc, aac"').replace(/no/,""))}function supportsTextTracks(){return!(!browser.tizen&&!browser.orsay)||(null==_supportsTextTracks&&(_supportsTextTracks=null!=document.createElement("video").textTracks),_supportsTextTracks)}function canPlayHls(src){return null==_canPlayHls&&(_canPlayHls=canPlayNativeHls()||canPlayHlsWithMSE()),_canPlayHls}function canPlayNativeHls(){if(browser.tizen||browser.orsay)return!0;var media=document.createElement("video");return!(!media.canPlayType("application/x-mpegURL").replace(/no/,"")&&!media.canPlayType("application/vnd.apple.mpegURL").replace(/no/,""))}function canPlayHlsWithMSE(){return null!=window.MediaSource}function canPlayAudioFormat(format){var typeString;if("flac"===format){if(browser.tizen||browser.orsay||browser.web0s)return!0;if(browser.edgeUwp)return!0}else if("wma"===format){if(browser.tizen||browser.orsay)return!0;if(browser.edgeUwp)return!0}else{if("opus"===format)return typeString='audio/ogg; codecs="opus"',!!document.createElement("audio").canPlayType(typeString).replace(/no/,"");if("mp2"===format)return!1}if("webma"===format)typeString="audio/webm";else if("mp2"===format)typeString="audio/mpeg";else if("ogg"===format||"oga"===format){if(browser.chrome)return!1;typeString="audio/"+format}else typeString="audio/"+format;return!!document.createElement("audio").canPlayType(typeString).replace(/no/,"")}function testCanPlayMkv(videoTestElement){if(browser.tizen||browser.orsay||browser.web0s)return!0;if(videoTestElement.canPlayType("video/x-matroska").replace(/no/,"")||videoTestElement.canPlayType("video/mkv").replace(/no/,""))return!0;var userAgent=navigator.userAgent.toLowerCase();return browser.chrome?!browser.operaTv&&(-1===userAgent.indexOf("vivaldi")&&-1===userAgent.indexOf("opera")):!!browser.edgeUwp}function testCanPlayTs(){return browser.tizen||browser.orsay||browser.web0s||browser.edgeUwp}function supportsMpeg2Video(){return browser.orsay||browser.tizen||browser.edgeUwp||browser.web0s}function supportsVc1(){return browser.orsay||browser.tizen||browser.edgeUwp}function getDirectPlayProfileForVideoContainer(container,videoAudioCodecs,videoTestElement,options){var supported=!1,profileContainer=container,videoCodecs=[];switch(container){case"asf":supported=browser.tizen||browser.orsay||browser.edgeUwp,videoAudioCodecs=[];break;case"avi":supported=browser.tizen||browser.orsay||browser.edgeUwp;break;case"mpg":case"mpeg":supported=browser.edgeUwp||browser.tizen||browser.orsay;break;case"flv":supported=browser.tizen||browser.orsay;break;case"3gp":case"mts":case"trp":case"vob":case"vro":supported=browser.tizen||browser.orsay;break;case"mov":supported=browser.tizen||browser.orsay||browser.chrome||browser.edgeUwp,videoCodecs.push("h264");break;case"m2ts":supported=browser.tizen||browser.orsay||browser.web0s||browser.edgeUwp,videoCodecs.push("h264"),supportsVc1()&&videoCodecs.push("vc1"),supportsMpeg2Video()&&videoCodecs.push("mpeg2video");break;case"wmv":supported=browser.tizen||browser.orsay||browser.web0s||browser.edgeUwp,videoAudioCodecs=[];break;case"ts":supported=testCanPlayTs(),videoCodecs.push("h264"),canPlayH265(videoTestElement,options)&&(videoCodecs.push("h265"),videoCodecs.push("hevc")),supportsVc1()&&videoCodecs.push("vc1"),supportsMpeg2Video()&&videoCodecs.push("mpeg2video"),profileContainer="ts,mpegts"}return supported?{Container:profileContainer,Type:"Video",VideoCodec:videoCodecs.join(","),AudioCodec:videoAudioCodecs.join(",")}:null}function getGlobalMaxVideoBitrate(){var userAgent=navigator.userAgent.toLowerCase();if(browser.chromecast){return-1!==userAgent.indexOf("aarch64")?null:self.screen&&self.screen.width>=3800?null:3e7}var isTizenFhd=!1;if(browser.tizen)try{isTizenFhd=!webapis.productinfo.isUdPanelSupported(),console.log("isTizenFhd = "+isTizenFhd)}catch(error){console.log("isUdPanelSupported() error code = "+error.code)}return browser.ps4?8e6:browser.xboxOne?12e6:browser.edgeUwp?null:browser.tizen&&isTizenFhd?2e7:null}function supportsAc3(videoTestElement){return!!(browser.edgeUwp||browser.tizen||browser.orsay||browser.web0s)||videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/,"")&&!browser.osx&&!browser.iOS}function supportsEac3(videoTestElement){return!!(browser.tizen||browser.orsay||browser.web0s)||videoTestElement.canPlayType('audio/mp4; codecs="ec-3"').replace(/no/,"")}var _supportsTextTracks,_canPlayHls;return function(options){options=options||{};var physicalAudioChannels=options.audioChannels||(browser.tv||browser.ps4||browser.xboxOne?6:2),videoTestElement=document.createElement("video"),canPlayVp8=videoTestElement.canPlayType('video/webm; codecs="vp8"').replace(/no/,""),canPlayVp9=videoTestElement.canPlayType('video/webm; codecs="vp9"').replace(/no/,""),webmAudioCodecs=["vorbis"],canPlayMkv=testCanPlayMkv(videoTestElement),profile={};profile.MaxStreamingBitrate=12e7,profile.MaxStaticBitrate=1e8,profile.MusicStreamingTranscodingBitrate=Math.min(12e7,192e3),profile.DirectPlayProfiles=[];var videoAudioCodecs=[],hlsVideoAudioCodecs=[],supportsMp3VideoAudio=videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"').replace(/no/,"")||videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"').replace(/no/,""),supportsMp2VideoAudio=browser.edgeUwp||browser.tizen||browser.orsay||browser.web0s,maxVideoWidth=browser.xboxOne&&self.screen?self.screen.width:null;options.maxVideoWidth&&(maxVideoWidth=options.maxVideoWidth);var canPlayAacVideoAudio=videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"').replace(/no/,"");if(canPlayAacVideoAudio&&browser.chromecast&&videoAudioCodecs.push("aac"),supportsAc3(videoTestElement)){videoAudioCodecs.push("ac3");var eAc3=supportsEac3(videoTestElement);eAc3&&videoAudioCodecs.push("eac3");(!browser.edge||!browser.touch||browser.edgeUwp)&&(hlsVideoAudioCodecs.push("ac3"),eAc3&&hlsVideoAudioCodecs.push("eac3"))}canPlayAacVideoAudio&&browser.chromecast&&-1===videoAudioCodecs.indexOf("aac")&&videoAudioCodecs.push("aac"),supportsMp3VideoAudio&&(videoAudioCodecs.push("mp3"),browser.ps4||physicalAudioChannels<=2&&hlsVideoAudioCodecs.push("mp3")),canPlayAacVideoAudio&&(-1===videoAudioCodecs.indexOf("aac")&&videoAudioCodecs.push("aac"),hlsVideoAudioCodecs.push("aac")),supportsMp3VideoAudio&&(browser.ps4||-1===hlsVideoAudioCodecs.indexOf("mp3")&&hlsVideoAudioCodecs.push("mp3")),supportsMp2VideoAudio&&videoAudioCodecs.push("mp2"),(browser.tizen||browser.orsay||browser.web0s||options.supportsDts)&&(videoAudioCodecs.push("dca"),videoAudioCodecs.push("dts")),(browser.tizen||browser.orsay)&&(videoAudioCodecs.push("pcm_s16le"),videoAudioCodecs.push("pcm_s24le")),options.supportsTrueHd&&videoAudioCodecs.push("truehd"),(browser.tizen||browser.orsay)&&videoAudioCodecs.push("aac_latm"),canPlayAudioFormat("opus")&&(videoAudioCodecs.push("opus"),hlsVideoAudioCodecs.push("opus"),webmAudioCodecs.push("opus")),canPlayAudioFormat("flac")&&videoAudioCodecs.push("flac"),videoAudioCodecs=videoAudioCodecs.filter(function(c){return-1===(options.disableVideoAudioCodecs||[]).indexOf(c)}),hlsVideoAudioCodecs=hlsVideoAudioCodecs.filter(function(c){return-1===(options.disableHlsVideoAudioCodecs||[]).indexOf(c)});var mp4VideoCodecs=[],hlsVideoCodecs=[];canPlayH264(videoTestElement)&&(mp4VideoCodecs.push("h264"),hlsVideoCodecs.push("h264")),canPlayH265(videoTestElement,options)&&(mp4VideoCodecs.push("h265"),mp4VideoCodecs.push("hevc"),(browser.tizen||browser.web0s)&&(hlsVideoCodecs.push("h265"),hlsVideoCodecs.push("hevc"))),supportsMpeg2Video()&&mp4VideoCodecs.push("mpeg2video"),supportsVc1()&&mp4VideoCodecs.push("vc1"),(browser.tizen||browser.orsay)&&mp4VideoCodecs.push("msmpeg4v2"),canPlayVp8&&mp4VideoCodecs.push("vp8"),canPlayVp9&&mp4VideoCodecs.push("vp9"),(canPlayVp8||browser.tizen||browser.orsay)&&videoAudioCodecs.push("vorbis"),mp4VideoCodecs.length&&profile.DirectPlayProfiles.push({Container:"mp4,m4v",Type:"Video",VideoCodec:mp4VideoCodecs.join(","),AudioCodec:videoAudioCodecs.join(",")}),canPlayMkv&&mp4VideoCodecs.length&&profile.DirectPlayProfiles.push({Container:"mkv",Type:"Video",VideoCodec:mp4VideoCodecs.join(","),AudioCodec:videoAudioCodecs.join(",")}),["m2ts","wmv","ts","asf","avi","mpg","mpeg","flv","3gp","mts","trp","vob","vro","mov"].map(function(container){return getDirectPlayProfileForVideoContainer(container,videoAudioCodecs,videoTestElement,options)}).filter(function(i){return null!=i}).forEach(function(i){profile.DirectPlayProfiles.push(i)}),["opus","mp3","mp2","aac","flac","alac","webma","wma","wav","ogg","oga"].filter(canPlayAudioFormat).forEach(function(audioFormat){"mp2"===audioFormat?profile.DirectPlayProfiles.push({Container:"mp2,mp3",Type:"Audio",AudioCodec:audioFormat}):"mp3"===audioFormat?profile.DirectPlayProfiles.push({Container:audioFormat,Type:"Audio",AudioCodec:audioFormat}):profile.DirectPlayProfiles.push({Container:"webma"===audioFormat?"webma,webm":audioFormat,Type:"Audio"}),"aac"!==audioFormat&&"alac"!==audioFormat||profile.DirectPlayProfiles.push({Container:"m4a",AudioCodec:audioFormat,Type:"Audio"})}),canPlayVp8&&profile.DirectPlayProfiles.push({Container:"webm",Type:"Video",AudioCodec:webmAudioCodecs.join(","),VideoCodec:"VP8"}),canPlayVp9&&profile.DirectPlayProfiles.push({Container:"webm",Type:"Video",AudioCodec:webmAudioCodecs.join(","),VideoCodec:"VP9"}),profile.TranscodingProfiles=[];var hlsBreakOnNonKeyFrames=!(!(browser.iOS||browser.osx||browser.edge)&&canPlayNativeHls());canPlayHls()&&!1!==browser.enableHlsAudio&&profile.TranscodingProfiles.push({Container:!canPlayNativeHls()||browser.edge||browser.android?"ts":"aac",Type:"Audio",AudioCodec:"aac",Context:"Streaming",Protocol:"hls",MaxAudioChannels:physicalAudioChannels.toString(),MinSegments:browser.iOS||browser.osx?"2":"1",BreakOnNonKeyFrames:hlsBreakOnNonKeyFrames}),["aac","mp3","opus","wav"].filter(canPlayAudioFormat).forEach(function(audioFormat){profile.TranscodingProfiles.push({Container:audioFormat,Type:"Audio",AudioCodec:audioFormat,Context:"Streaming",Protocol:"http",MaxAudioChannels:physicalAudioChannels.toString()})}),["opus","mp3","aac","wav"].filter(canPlayAudioFormat).forEach(function(audioFormat){profile.TranscodingProfiles.push({Container:audioFormat,Type:"Audio",AudioCodec:audioFormat,Context:"Static",Protocol:"http",MaxAudioChannels:physicalAudioChannels.toString()})}),!canPlayMkv||browser.tizen||browser.orsay||!1===options.enableMkvProgressive||profile.TranscodingProfiles.push({Container:"mkv",Type:"Video",AudioCodec:videoAudioCodecs.join(","),VideoCodec:mp4VideoCodecs.join(","),Context:"Streaming",MaxAudioChannels:physicalAudioChannels.toString(),CopyTimestamps:!0}),canPlayMkv&&profile.TranscodingProfiles.push({Container:"mkv",Type:"Video",AudioCodec:videoAudioCodecs.join(","),VideoCodec:mp4VideoCodecs.join(","),Context:"Static",MaxAudioChannels:physicalAudioChannels.toString(),CopyTimestamps:!0}),canPlayHls()&&!1!==options.enableHls&&profile.TranscodingProfiles.push({Container:"ts",Type:"Video",AudioCodec:hlsVideoAudioCodecs.join(","),VideoCodec:hlsVideoCodecs.join(","),Context:"Streaming",Protocol:"hls",MaxAudioChannels:physicalAudioChannels.toString(),MinSegments:browser.iOS||browser.osx?"2":"1",BreakOnNonKeyFrames:hlsBreakOnNonKeyFrames}),canPlayVp8&&profile.TranscodingProfiles.push({Container:"webm",Type:"Video",AudioCodec:"vorbis",VideoCodec:"vpx",Context:"Streaming",Protocol:"http",MaxAudioChannels:physicalAudioChannels.toString()}),profile.TranscodingProfiles.push({Container:"mp4",Type:"Video",AudioCodec:videoAudioCodecs.join(","),VideoCodec:"h264",Context:"Static",Protocol:"http"}),profile.ContainerProfiles=[],profile.CodecProfiles=[];var supportsSecondaryAudio=browser.tizen||browser.orsay||browser.edge||browser.msie,aacCodecProfileConditions=[];videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.5"').replace(/no/,"")||aacCodecProfileConditions.push({Condition:"NotEquals",Property:"AudioProfile",Value:"HE-AAC"}),supportsSecondaryAudio||aacCodecProfileConditions.push({Condition:"Equals",Property:"IsSecondaryAudio",Value:"false",IsRequired:"false"}),browser.chromecast&&aacCodecProfileConditions.push({Condition:"LessThanEqual",Property:"AudioChannels",Value:"2",IsRequired:!0}),aacCodecProfileConditions.length&&profile.CodecProfiles.push({Type:"VideoAudio",Codec:"aac",Conditions:aacCodecProfileConditions}),supportsSecondaryAudio||profile.CodecProfiles.push({Type:"VideoAudio",Conditions:[{Condition:"Equals",Property:"IsSecondaryAudio",Value:"false",IsRequired:"false"}]});var maxH264Level=browser.chromecast?42:51,h264Profiles="high|main|baseline|constrained baseline";maxH264Level>=51&&browser.chrome&&!browser.osx&&(h264Profiles+="|high 10"),profile.CodecProfiles.push({Type:"Video",Codec:"h264",Conditions:[{Condition:"NotEquals",Property:"IsAnamorphic",Value:"true",IsRequired:!1},{Condition:"EqualsAny",Property:"VideoProfile",Value:h264Profiles},{Condition:"LessThanEqual",Property:"VideoLevel",Value:maxH264Level.toString()}]}),browser.edgeUwp||browser.tizen||browser.orsay||browser.web0s||(profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"NotEquals",Property:"IsAVC",Value:"false",IsRequired:!1}),profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"NotEquals",Property:"IsInterlaced",Value:"true",IsRequired:!1})),maxVideoWidth&&profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"LessThanEqual",Property:"Width",Value:maxVideoWidth.toString(),IsRequired:!1});var globalMaxVideoBitrate=(getGlobalMaxVideoBitrate()||"").toString(),h264MaxVideoBitrate=globalMaxVideoBitrate;h264MaxVideoBitrate&&profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"LessThanEqual",Property:"VideoBitrate",Value:h264MaxVideoBitrate,IsRequired:!0});var globalVideoConditions=[];return globalMaxVideoBitrate&&globalVideoConditions.push({Condition:"LessThanEqual",Property:"VideoBitrate",Value:globalMaxVideoBitrate}),maxVideoWidth&&globalVideoConditions.push({Condition:"LessThanEqual",Property:"Width",Value:maxVideoWidth.toString(),IsRequired:!1}),globalVideoConditions.length&&profile.CodecProfiles.push({Type:"Video",Conditions:globalVideoConditions}),browser.chromecast&&profile.CodecProfiles.push({Type:"Audio",Codec:"flac",Conditions:[{Condition:"LessThanEqual",Property:"AudioSampleRate",Value:"96000"}]}),profile.SubtitleProfiles=[],supportsTextTracks()&&profile.SubtitleProfiles.push({Format:"vtt",Method:"External"}),profile.ResponseProfiles=[],profile.ResponseProfiles.push({Type:"Video",Container:"m4v",MimeType:"video/mp4"}),profile}}); \ No newline at end of file +define(["browser"],function(browser){"use strict";function canPlayH264(videoTestElement){return!(!videoTestElement.canPlayType||!videoTestElement.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/,""))}function canPlayH265(videoTestElement,options){if(browser.tizen||browser.orsay||browser.xboxOne||browser.web0s||options.supportsHevc)return!0;var userAgent=navigator.userAgent.toLowerCase();if(browser.chromecast){if(-1!==userAgent.indexOf("aarch64"))return!0}return!!(browser.iOS&&(browser.iOSVersion||0)>=11)||!(!videoTestElement.canPlayType||!videoTestElement.canPlayType('video/hevc; codecs="hevc, aac"').replace(/no/,""))}function supportsTextTracks(){return!(!browser.tizen&&!browser.orsay)||(null==_supportsTextTracks&&(_supportsTextTracks=null!=document.createElement("video").textTracks),_supportsTextTracks)}function canPlayHls(src){return null==_canPlayHls&&(_canPlayHls=canPlayNativeHls()||canPlayHlsWithMSE()),_canPlayHls}function canPlayNativeHls(){if(browser.tizen||browser.orsay)return!0;var media=document.createElement("video");return!(!media.canPlayType("application/x-mpegURL").replace(/no/,"")&&!media.canPlayType("application/vnd.apple.mpegURL").replace(/no/,""))}function canPlayHlsWithMSE(){return null!=window.MediaSource}function canPlayAudioFormat(format){var typeString;if("flac"===format){if(browser.tizen||browser.orsay||browser.web0s)return!0;if(browser.edgeUwp)return!0}else if("wma"===format){if(browser.tizen||browser.orsay)return!0;if(browser.edgeUwp)return!0}else{if("opus"===format)return typeString='audio/ogg; codecs="opus"',!!document.createElement("audio").canPlayType(typeString).replace(/no/,"");if("mp2"===format)return!1}if("webma"===format)typeString="audio/webm";else if("mp2"===format)typeString="audio/mpeg";else if("ogg"===format||"oga"===format){if(browser.chrome)return!1;typeString="audio/"+format}else typeString="audio/"+format;return!!document.createElement("audio").canPlayType(typeString).replace(/no/,"")}function testCanPlayMkv(videoTestElement){if(browser.tizen||browser.orsay||browser.web0s)return!0;if(videoTestElement.canPlayType("video/x-matroska").replace(/no/,"")||videoTestElement.canPlayType("video/mkv").replace(/no/,""))return!0;var userAgent=navigator.userAgent.toLowerCase();return browser.chrome?!browser.operaTv&&(-1===userAgent.indexOf("vivaldi")&&-1===userAgent.indexOf("opera")):!!browser.edgeUwp}function testCanPlayTs(){return browser.tizen||browser.orsay||browser.web0s||browser.edgeUwp}function supportsMpeg2Video(){return browser.orsay||browser.tizen||browser.edgeUwp||browser.web0s}function supportsVc1(){return browser.orsay||browser.tizen||browser.edgeUwp}function getDirectPlayProfileForVideoContainer(container,videoAudioCodecs,videoTestElement,options){var supported=!1,profileContainer=container,videoCodecs=[];switch(container){case"asf":supported=browser.tizen||browser.orsay||browser.edgeUwp,videoAudioCodecs=[];break;case"avi":supported=browser.tizen||browser.orsay||browser.edgeUwp;break;case"mpg":case"mpeg":supported=browser.edgeUwp||browser.tizen||browser.orsay;break;case"flv":supported=browser.tizen||browser.orsay;break;case"3gp":case"mts":case"trp":case"vob":case"vro":supported=browser.tizen||browser.orsay;break;case"mov":supported=browser.tizen||browser.orsay||browser.chrome||browser.edgeUwp,videoCodecs.push("h264");break;case"m2ts":supported=browser.tizen||browser.orsay||browser.web0s||browser.edgeUwp,videoCodecs.push("h264"),supportsVc1()&&videoCodecs.push("vc1"),supportsMpeg2Video()&&videoCodecs.push("mpeg2video");break;case"wmv":supported=browser.tizen||browser.orsay||browser.web0s||browser.edgeUwp,videoAudioCodecs=[];break;case"ts":supported=testCanPlayTs(),videoCodecs.push("h264"),canPlayH265(videoTestElement,options)&&(videoCodecs.push("h265"),videoCodecs.push("hevc")),supportsVc1()&&videoCodecs.push("vc1"),supportsMpeg2Video()&&videoCodecs.push("mpeg2video"),profileContainer="ts,mpegts"}return supported?{Container:profileContainer,Type:"Video",VideoCodec:videoCodecs.join(","),AudioCodec:videoAudioCodecs.join(",")}:null}function getGlobalMaxVideoBitrate(){var userAgent=navigator.userAgent.toLowerCase();if(browser.chromecast){return-1!==userAgent.indexOf("aarch64")?null:self.screen&&self.screen.width>=3800?null:3e7}var isTizenFhd=!1;if(browser.tizen)try{isTizenFhd=!webapis.productinfo.isUdPanelSupported(),console.log("isTizenFhd = "+isTizenFhd)}catch(error){console.log("isUdPanelSupported() error code = "+error.code)}return browser.ps4?8e6:browser.xboxOne?12e6:browser.edgeUwp?null:browser.tizen&&isTizenFhd?2e7:null}function supportsAc3(videoTestElement){return!!(browser.edgeUwp||browser.tizen||browser.orsay||browser.web0s)||videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/,"")&&!browser.osx&&!browser.iOS}function supportsEac3(videoTestElement){return!!(browser.tizen||browser.orsay||browser.web0s)||videoTestElement.canPlayType('audio/mp4; codecs="ec-3"').replace(/no/,"")}var _supportsTextTracks,_canPlayHls;return function(options){options=options||{};var physicalAudioChannels=options.audioChannels||(browser.tv||browser.ps4||browser.xboxOne?6:2),videoTestElement=document.createElement("video"),canPlayVp8=videoTestElement.canPlayType('video/webm; codecs="vp8"').replace(/no/,""),canPlayVp9=videoTestElement.canPlayType('video/webm; codecs="vp9"').replace(/no/,""),webmAudioCodecs=["vorbis"],canPlayMkv=testCanPlayMkv(videoTestElement),profile={};profile.MaxStreamingBitrate=12e7,profile.MaxStaticBitrate=1e8,profile.MusicStreamingTranscodingBitrate=Math.min(12e7,192e3),profile.DirectPlayProfiles=[];var videoAudioCodecs=[],hlsVideoAudioCodecs=[],supportsMp3VideoAudio=videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"').replace(/no/,"")||videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"').replace(/no/,""),supportsMp2VideoAudio=browser.edgeUwp||browser.tizen||browser.orsay||browser.web0s,maxVideoWidth=browser.xboxOne&&self.screen?self.screen.width:null;options.maxVideoWidth&&(maxVideoWidth=options.maxVideoWidth);var canPlayAacVideoAudio=videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"').replace(/no/,"");if(canPlayAacVideoAudio&&browser.chromecast&&videoAudioCodecs.push("aac"),supportsAc3(videoTestElement)){videoAudioCodecs.push("ac3");var eAc3=supportsEac3(videoTestElement);eAc3&&videoAudioCodecs.push("eac3");(!browser.edge||!browser.touch||browser.edgeUwp)&&(hlsVideoAudioCodecs.push("ac3"),eAc3&&hlsVideoAudioCodecs.push("eac3"))}canPlayAacVideoAudio&&browser.chromecast&&-1===videoAudioCodecs.indexOf("aac")&&videoAudioCodecs.push("aac"),supportsMp3VideoAudio&&(videoAudioCodecs.push("mp3"),browser.ps4||physicalAudioChannels<=2&&hlsVideoAudioCodecs.push("mp3")),canPlayAacVideoAudio&&(-1===videoAudioCodecs.indexOf("aac")&&videoAudioCodecs.push("aac"),hlsVideoAudioCodecs.push("aac")),supportsMp3VideoAudio&&(browser.ps4||-1===hlsVideoAudioCodecs.indexOf("mp3")&&hlsVideoAudioCodecs.push("mp3")),supportsMp2VideoAudio&&videoAudioCodecs.push("mp2");var supportsDts=browser.tizen||browser.orsay||browser.web0s||options.supportsDts;if(browser.tizen){var v=tizen.systeminfo.getCapability("http://tizen.org/feature/platform.version");v&&parseFloat(v)>=parseFloat("4.0")&&(supportsDts=!1)}supportsDts&&(videoAudioCodecs.push("dca"),videoAudioCodecs.push("dts")),(browser.tizen||browser.orsay)&&(videoAudioCodecs.push("pcm_s16le"),videoAudioCodecs.push("pcm_s24le")),options.supportsTrueHd&&videoAudioCodecs.push("truehd"),(browser.tizen||browser.orsay)&&videoAudioCodecs.push("aac_latm"),canPlayAudioFormat("opus")&&(videoAudioCodecs.push("opus"),hlsVideoAudioCodecs.push("opus"),webmAudioCodecs.push("opus")),canPlayAudioFormat("flac")&&videoAudioCodecs.push("flac"),videoAudioCodecs=videoAudioCodecs.filter(function(c){return-1===(options.disableVideoAudioCodecs||[]).indexOf(c)}),hlsVideoAudioCodecs=hlsVideoAudioCodecs.filter(function(c){return-1===(options.disableHlsVideoAudioCodecs||[]).indexOf(c)});var mp4VideoCodecs=[],hlsVideoCodecs=[];canPlayH264(videoTestElement)&&(mp4VideoCodecs.push("h264"),hlsVideoCodecs.push("h264")),canPlayH265(videoTestElement,options)&&(mp4VideoCodecs.push("h265"),mp4VideoCodecs.push("hevc"),(browser.tizen||browser.web0s)&&(hlsVideoCodecs.push("h265"),hlsVideoCodecs.push("hevc"))),supportsMpeg2Video()&&mp4VideoCodecs.push("mpeg2video"),supportsVc1()&&mp4VideoCodecs.push("vc1"),(browser.tizen||browser.orsay)&&mp4VideoCodecs.push("msmpeg4v2"),canPlayVp8&&mp4VideoCodecs.push("vp8"),canPlayVp9&&mp4VideoCodecs.push("vp9"),(canPlayVp8||browser.tizen||browser.orsay)&&videoAudioCodecs.push("vorbis"),mp4VideoCodecs.length&&profile.DirectPlayProfiles.push({Container:"mp4,m4v",Type:"Video",VideoCodec:mp4VideoCodecs.join(","),AudioCodec:videoAudioCodecs.join(",")}),canPlayMkv&&mp4VideoCodecs.length&&profile.DirectPlayProfiles.push({Container:"mkv",Type:"Video",VideoCodec:mp4VideoCodecs.join(","),AudioCodec:videoAudioCodecs.join(",")}),["m2ts","wmv","ts","asf","avi","mpg","mpeg","flv","3gp","mts","trp","vob","vro","mov"].map(function(container){return getDirectPlayProfileForVideoContainer(container,videoAudioCodecs,videoTestElement,options)}).filter(function(i){return null!=i}).forEach(function(i){profile.DirectPlayProfiles.push(i)}),["opus","mp3","mp2","aac","flac","alac","webma","wma","wav","ogg","oga"].filter(canPlayAudioFormat).forEach(function(audioFormat){"mp2"===audioFormat?profile.DirectPlayProfiles.push({Container:"mp2,mp3",Type:"Audio",AudioCodec:audioFormat}):"mp3"===audioFormat?profile.DirectPlayProfiles.push({Container:audioFormat,Type:"Audio",AudioCodec:audioFormat}):profile.DirectPlayProfiles.push({Container:"webma"===audioFormat?"webma,webm":audioFormat,Type:"Audio"}),"aac"!==audioFormat&&"alac"!==audioFormat||profile.DirectPlayProfiles.push({Container:"m4a",AudioCodec:audioFormat,Type:"Audio"})}),canPlayVp8&&profile.DirectPlayProfiles.push({Container:"webm",Type:"Video",AudioCodec:webmAudioCodecs.join(","),VideoCodec:"VP8"}),canPlayVp9&&profile.DirectPlayProfiles.push({Container:"webm",Type:"Video",AudioCodec:webmAudioCodecs.join(","),VideoCodec:"VP9"}),profile.TranscodingProfiles=[];var hlsBreakOnNonKeyFrames=!(!(browser.iOS||browser.osx||browser.edge)&&canPlayNativeHls());canPlayHls()&&!1!==browser.enableHlsAudio&&profile.TranscodingProfiles.push({Container:!canPlayNativeHls()||browser.edge||browser.android?"ts":"aac",Type:"Audio",AudioCodec:"aac",Context:"Streaming",Protocol:"hls",MaxAudioChannels:physicalAudioChannels.toString(),MinSegments:browser.iOS||browser.osx?"2":"1",BreakOnNonKeyFrames:hlsBreakOnNonKeyFrames}),["aac","mp3","opus","wav"].filter(canPlayAudioFormat).forEach(function(audioFormat){profile.TranscodingProfiles.push({Container:audioFormat,Type:"Audio",AudioCodec:audioFormat,Context:"Streaming",Protocol:"http",MaxAudioChannels:physicalAudioChannels.toString()})}),["opus","mp3","aac","wav"].filter(canPlayAudioFormat).forEach(function(audioFormat){profile.TranscodingProfiles.push({Container:audioFormat,Type:"Audio",AudioCodec:audioFormat,Context:"Static",Protocol:"http",MaxAudioChannels:physicalAudioChannels.toString()})}),!canPlayMkv||browser.tizen||browser.orsay||!1===options.enableMkvProgressive||profile.TranscodingProfiles.push({Container:"mkv",Type:"Video",AudioCodec:videoAudioCodecs.join(","),VideoCodec:mp4VideoCodecs.join(","),Context:"Streaming",MaxAudioChannels:physicalAudioChannels.toString(),CopyTimestamps:!0}),canPlayMkv&&profile.TranscodingProfiles.push({Container:"mkv",Type:"Video",AudioCodec:videoAudioCodecs.join(","),VideoCodec:mp4VideoCodecs.join(","),Context:"Static",MaxAudioChannels:physicalAudioChannels.toString(),CopyTimestamps:!0}),canPlayHls()&&!1!==options.enableHls&&profile.TranscodingProfiles.push({Container:"ts",Type:"Video",AudioCodec:hlsVideoAudioCodecs.join(","),VideoCodec:hlsVideoCodecs.join(","),Context:"Streaming",Protocol:"hls",MaxAudioChannels:physicalAudioChannels.toString(),MinSegments:browser.iOS||browser.osx?"2":"1",BreakOnNonKeyFrames:hlsBreakOnNonKeyFrames}),canPlayVp8&&profile.TranscodingProfiles.push({Container:"webm",Type:"Video",AudioCodec:"vorbis",VideoCodec:"vpx",Context:"Streaming",Protocol:"http",MaxAudioChannels:physicalAudioChannels.toString()}),profile.TranscodingProfiles.push({Container:"mp4",Type:"Video",AudioCodec:videoAudioCodecs.join(","),VideoCodec:"h264",Context:"Static",Protocol:"http"}),profile.ContainerProfiles=[],profile.CodecProfiles=[];var supportsSecondaryAudio=browser.tizen||browser.orsay||browser.edge||browser.msie,aacCodecProfileConditions=[];videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.5"').replace(/no/,"")||aacCodecProfileConditions.push({Condition:"NotEquals",Property:"AudioProfile",Value:"HE-AAC"}),supportsSecondaryAudio||aacCodecProfileConditions.push({Condition:"Equals",Property:"IsSecondaryAudio",Value:"false",IsRequired:"false"}),browser.chromecast&&aacCodecProfileConditions.push({Condition:"LessThanEqual",Property:"AudioChannels",Value:"2",IsRequired:!0}),aacCodecProfileConditions.length&&profile.CodecProfiles.push({Type:"VideoAudio",Codec:"aac",Conditions:aacCodecProfileConditions}),supportsSecondaryAudio||profile.CodecProfiles.push({Type:"VideoAudio",Conditions:[{Condition:"Equals",Property:"IsSecondaryAudio",Value:"false",IsRequired:"false"}]});var maxH264Level=browser.chromecast?42:51,h264Profiles="high|main|baseline|constrained baseline";maxH264Level>=51&&browser.chrome&&!browser.osx&&(h264Profiles+="|high 10"),profile.CodecProfiles.push({Type:"Video",Codec:"h264",Conditions:[{Condition:"NotEquals",Property:"IsAnamorphic",Value:"true",IsRequired:!1},{Condition:"EqualsAny",Property:"VideoProfile",Value:h264Profiles},{Condition:"LessThanEqual",Property:"VideoLevel",Value:maxH264Level.toString()}]}),browser.edgeUwp||browser.tizen||browser.orsay||browser.web0s||(profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"NotEquals",Property:"IsAVC",Value:"false",IsRequired:!1}),profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"NotEquals",Property:"IsInterlaced",Value:"true",IsRequired:!1})),maxVideoWidth&&profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"LessThanEqual",Property:"Width",Value:maxVideoWidth.toString(),IsRequired:!1});var globalMaxVideoBitrate=(getGlobalMaxVideoBitrate()||"").toString(),h264MaxVideoBitrate=globalMaxVideoBitrate;h264MaxVideoBitrate&&profile.CodecProfiles[profile.CodecProfiles.length-1].Conditions.push({Condition:"LessThanEqual",Property:"VideoBitrate",Value:h264MaxVideoBitrate,IsRequired:!0});var globalVideoConditions=[];return globalMaxVideoBitrate&&globalVideoConditions.push({Condition:"LessThanEqual",Property:"VideoBitrate",Value:globalMaxVideoBitrate}),maxVideoWidth&&globalVideoConditions.push({Condition:"LessThanEqual",Property:"Width",Value:maxVideoWidth.toString(),IsRequired:!1}),globalVideoConditions.length&&profile.CodecProfiles.push({Type:"Video",Conditions:globalVideoConditions}),browser.chromecast&&profile.CodecProfiles.push({Type:"Audio",Codec:"flac",Conditions:[{Condition:"LessThanEqual",Property:"AudioSampleRate",Value:"96000"}]}),profile.SubtitleProfiles=[],supportsTextTracks()&&profile.SubtitleProfiles.push({Format:"vtt",Method:"External"}),profile.ResponseProfiles=[],profile.ResponseProfiles.push({Type:"Video",Container:"m4v",MimeType:"video/mp4"}),profile}}); \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/card.css b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/card.css index 227dbecb26..94882a42c8 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/card.css +++ b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/card.css @@ -1 +1 @@ -.card,.card:focus{font-weight:inherit!important}.card,.cardBox,.cardContent,.textActionButton{-webkit-tap-highlight-color:transparent;outline:0!important}button::-moz-focus-inner{padding:0;border:0}button{-webkit-border-fit:border!important}.card{border:0;font-size:inherit!important;font-family:inherit!important;text-transform:none;background:0 0!important;margin:0;padding:0;display:block;color:inherit!important;cursor:pointer;contain:layout style;-webkit-flex-shrink:0;flex-shrink:0}.cardContent-button,.textActionButton{cursor:pointer;vertical-align:middle;font-family:inherit}.card-nofocustransform{contain:layout style paint}.itemsContainer{display:-webkit-box;display:-webkit-flex;display:flex}.vertical-list,.vertical-wrap{display:-webkit-box;display:-webkit-flex;-webkit-box-direction:normal}.vertical-list{display:flex;-webkit-box-orient:vertical;-webkit-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;flex-wrap:nowrap}.vertical-wrap{display:flex;-webkit-box-orient:horizontal;-webkit-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;flex-wrap:wrap}.cardImageContainer,.mediaSourceIndicator{display:-webkit-flex;-webkit-box-align:center}.vertical-wrap.centered{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.cardScalable{position:relative;contain:layout style}.cardPadder-backdrop,.cardPadder-mixedBackdrop,.cardPadder-overflowBackdrop,.cardPadder-overflowSmallBackdrop,.cardPadder-smallBackdrop{padding-bottom:56.25%;contain:strict}.cardPadder-mixedSquare,.cardPadder-overflowSquare,.cardPadder-square,.overflowSquareCard-textCardPadder{padding-bottom:100%;contain:strict}.cardPadder-mixedPortrait,.cardPadder-overflowPortrait,.cardPadder-portrait,.overflowPortraitCard-textCardPadder{padding-bottom:150%;contain:strict}.cardPadder-banner{padding-bottom:18.5%;contain:strict}.cardBox{padding:0!important;margin:.64em;-webkit-transition:none;-o-transition:none;transition:none;border:0 solid transparent;contain:layout style}@media all and (max-width:50em){.cardBox{margin:.32em .24em}}.card-focuscontent{border:.12em solid transparent;-webkit-border-radius:.12em;border-radius:.12em}.card-focuscontent-large{border-width:.24em}.cardBox-focustransform{will-change:transform;-webkit-transition:-webkit-transform .2s ease-out;-o-transition:transform .2s ease-out;transition:transform .2s ease-out}.card:focus>.cardBox-focustransform{-webkit-transform:scale(1.16,1.16);transform:scale(1.16,1.16)}.cardBox-bottompadded{margin-bottom:1.8em!important}.layout-mobile .cardBox-bottompadded{margin-bottom:1.2em!important}.card:focus{position:relative!important;z-index:10!important}.btnCardOptions{position:absolute;bottom:.25em;right:0;margin:0!important;z-index:1}.mediaSourceIndicator{display:-webkit-box;display:flex;position:absolute;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;top:.3em;left:.3em;text-align:center;vertical-align:middle;width:1.6em;height:1.6em;-webkit-border-radius:50%;border-radius:50%;color:#fff;background:#38c}.cardText,.innerCardFooter{overflow:hidden;text-align:left}.cardImageContainer{-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;background-position:center center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;position:relative;-webkit-background-clip:content-box!important;background-clip:content-box!important;color:inherit;height:100%;contain:strict}.cardContent,.cardImage{position:absolute;right:0;top:0;left:0;bottom:0}.chapterCardImageContainer{background-color:#000;-webkit-border-radius:0;border-radius:0}.textCardImageContainer{background-color:#333}.cardContent{overflow:hidden;display:block;margin:0!important;height:100%;-webkit-border-radius:.08em;border-radius:.08em;contain:strict}.cardContent-button{border:0!important;padding:0!important;color:inherit;width:100%;font-size:inherit}.cardContent-button:not(.defaultCardBackground){background-color:transparent}.visualCardBox .cardContent{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}.cardContent-shadow{-webkit-box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37)}.cardImageContainer{display:-webkit-box;display:-webkit-flex;display:flex}.cardImage{-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;background-position:center bottom}.cardImage-img{max-height:100%;max-width:100%;min-height:70%;min-width:70%;margin:auto}.coveredImage-img{width:100%;height:100%}.coveredImage-noscale-img{max-height:none;max-width:none}.coveredImage{-webkit-background-size:100% 100%;background-size:100% 100%;background-position:center center}.coveredImage-noScale{-webkit-background-size:cover;background-size:cover}.cardFooter{padding:.3em .3em .5em;position:relative}.visualCardBox{-webkit-box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);-webkit-border-radius:.145em;border-radius:.145em}.innerCardFooter{background:rgba(0,0,0,.7);position:absolute;bottom:0;left:0;z-index:1;max-width:100%;color:#fff}.innerCardFooterClear{background-color:transparent}.fullInnerCardFooter{right:0}.cardText{padding:.06em .5em;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis}.cardDefaultText,.cardTextCentered{text-align:center}.cardText-secondary{font-size:84%}.cardText-first{padding-top:.24em}.innerCardFooter>.cardText{padding:.3em .5em}.cardFooter-withlogo{padding-left:4em;position:relative}.cardFooterLogo{position:absolute;top:0;bottom:0;left:0;width:4.5em;-webkit-background-size:70% auto;background-size:70% auto;background-repeat:no-repeat;background-position:center center}.cardText-rightmargin{margin-right:2em}.cardDefaultText{white-space:normal}.textActionButton{background:0 0;border:0!important;padding:0!important;color:inherit;font-size:inherit}.textActionButton:hover{text-decoration:underline}.cardImageIcon{width:1em;height:1em;font-size:5em;color:inherit}.cardImageIcon-small{font-size:3em;margin-bottom:.1em}.cardIndicators{right:.225em;top:.225em;position:absolute;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;contain:layout style}.cardProgramAttributeIndicators{top:0;left:0;position:absolute;display:-webkit-box;display:-webkit-flex;display:flex;text-transform:uppercase;font-size:92%}.programAttributeIndicator{padding:.18em .5em;color:#fff;font-weight:500}.cardOverlayButton{color:rgba(255,255,255,.76)!important;margin:0;z-index:1;padding:.75em;font-size:88%}.cardOverlayButton-hover{background:0 0;padding:.5em;color:#fff!important}.cardOverlayButton-br{position:absolute;bottom:0;right:0}.cardOverlayButtonIcon{background-color:rgba(0,0,0,.7)!important;-webkit-border-radius:100em;border-radius:100em;width:1.5em!important;height:1.5em!important;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:flex;font-size:1.66956521739130434em!important}.cardOverlayButton-centered{bottom:initial;right:initial;position:static;position:absolute;display:-webkit-box;display:-webkit-flex;display:flex;font-size:112%;margin:-1.3em 0 0 -1.3em;width:2.6em;height:2.6em;top:50%;left:50%;background-color:rgba(0,0,0,.5)!important;border:.06em solid rgba(255,255,255,.6);padding:.38em!important;color:rgba(255,255,255,.76);-webkit-transition:-webkit-transform .2s ease-out;-o-transition:transform .2s ease-out;transition:transform .2s ease-out}.cardOverlayButton-centered:hover{-webkit-transform:scale(1.2,1.2);transform:scale(1.2,1.2)}.backdropCard,.bannerCard{width:100%}.smallBackdropCard,.squareCard{width:50%}.portraitCard{width:33.333333333333333333333333333333%}.mixedPortraitCard{width:12em}.mixedSquareCard{width:18em}.mixedBackdropCard{width:32em}@media all and (min-width:400px){.backdropCard{width:50%}}@media all and (min-width:500px){.portraitCard,.smallBackdropCard,.squareCard{width:33.333333333333333333333333333333%}}@media all and (min-width:700px){.portraitCard,.squareCard{width:25%}}@media all and (min-width:770px){.backdropCard{width:33.333333333333333333333333333333%}}@media all and (min-width:800px){.bannerCard{width:50%}.portraitCard,.squareCard{width:20%}.smallBackdropCard{width:25%}}@media all and (min-width:1000px){.smallBackdropCard{width:20%}}@media all and (min-width:1200px){.backdropCard{width:25%}.portraitCard,.squareCard{width:16.666666666666666666666666666667%}.bannerCard{width:33.333333333333333333333333333333%}.smallBackdropCard{width:16.666666666666666666666666666667%}}@media all and (min-width:1400px){.portraitCard,.smallBackdropCard,.squareCard{width:14.285714285714285714285714285714%}}@media all and (min-width:1600px){.smallBackdropCard{width:12.5%}.backdropCard{width:20%}.portraitCard,.squareCard{width:12.5%}}@media all and (min-width:1920px){.portraitCard,.squareCard{width:11.111111111111111111111111111111%}}@media all and (min-width:2100px){.backdropCard{width:20%}}@media all and (min-width:2200px){.bannerCard{width:25%}.portraitCard,.squareCard{width:10%}}@media all and (min-width:2500px){.backdropCard{width:16.666666666666666666666666666667%}}.itemsContainer-tv>.backdropCard{width:25%}.itemsContainer-tv>.portraitCard,.itemsContainer-tv>.squareCard{width:16.666666666666666666666666666667%}@media all and (orientation:portrait){.overflowPortraitCard{width:42vw}.overflowBackdropCard,.overflowSmallBackdropCard{width:72vw}.overflowSquareCard{width:42vw}}@media all and (orientation:landscape){.overflowBackdropCard,.overflowSmallBackdropCard{width:23.3vw}.overflowPortraitCard,.overflowSquareCard{width:15.5vw}}@media all and (orientation:portrait) and (min-width:540px){.overflowSmallBackdropCard{width:30vw}}@media all and (orientation:landscape) and (min-width:800px){.overflowSmallBackdropCard{width:15.5vw}}@media all and (orientation:landscape) and (min-width:1700px){.overflowBackdropCard{width:18.5vw}.overflowPortraitCard,.overflowSquareCard{width:11.6vw}}@media all and (orientation:portrait) and (min-width:400px){.overflowPortraitCard{width:31.5vw}}@media all and (orientation:portrait) and (min-width:540px){.overflowBackdropCard{width:64vw}.overflowSquareCard{width:31.5vw}}@media all and (orientation:portrait) and (min-width:640px){.overflowBackdropCard{width:56vw}}@media all and (orientation:portrait) and (min-width:760px){.overflowPortraitCard{width:23vw}.overflowBackdropCard{width:40vw}.overflowSquareCard{width:23vw}}@media all and (orientation:portrait) and (min-width:1200px){.overflowPortraitCard,.overflowSquareCard{width:18vw}}@media all and (orientation:portrait) and (min-width:1400px){.overflowPortraitCard,.overflowSquareCard{width:15vw}.overflowBackdropCard{width:30vw}}@media all and (orientation:portrait) and (min-width:1800px){.overflowBackdropCard{width:23.5vw}}.itemsContainer-tv>.overflowBackdropCard{width:23.3vw}.overflowBackdropCard-textCard{width:15.5vw!important}.overflowBackdropCard-textCardPadder{padding-bottom:87.75%}.itemsContainer-tv>.overflowPortraitCard,.itemsContainer-tv>.overflowSquareCard{width:15.5vw}.itemsContainer-tv>.overflowSmallBackdropCard{width:18.9vw}.cardOverlayTarget{position:absolute;right:0;left:0;bottom:0;top:0;background-color:rgba(0,0,0,.75);-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;opacity:0;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-transition:opacity 160ms ease-in,-webkit-transform 40ms ease-in;-o-transition:opacity 160ms ease-in,transform 40ms ease-in;transition:opacity 160ms ease-in,transform 40ms ease-in;-webkit-transition-delay:540ms;-o-transition-delay:540ms;transition-delay:540ms;-webkit-transform:scale(0);transform:scale(0)}.card:hover .cardOverlayTarget{opacity:1;-webkit-transform:none;transform:none}.cardOverlayFab-primary{font-size:140%;padding:0}.cardOverlayFab-primary i{border:.08em solid rgba(255,255,255,.6)}.cardOverlayButtonIcon-hover{background:0 0!important} \ No newline at end of file +.card,.card:focus{font-weight:inherit!important}.card,.cardBox,.cardContent,.textActionButton{-webkit-tap-highlight-color:transparent;outline:0!important}button::-moz-focus-inner{padding:0;border:0}button{-webkit-border-fit:border!important}.card{border:0;font-size:inherit!important;font-family:inherit!important;text-transform:none;background:0 0!important;margin:0;padding:0;display:block;color:inherit!important;cursor:pointer;contain:layout style;-webkit-flex-shrink:0;flex-shrink:0}.cardContent-button,.textActionButton{cursor:pointer;vertical-align:middle;font-family:inherit}.card-nofocustransform{contain:layout style paint}.itemsContainer{display:-webkit-box;display:-webkit-flex;display:flex}.vertical-list,.vertical-wrap{display:-webkit-box;display:-webkit-flex;-webkit-box-direction:normal}.vertical-list{display:flex;-webkit-box-orient:vertical;-webkit-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;flex-wrap:nowrap}.vertical-wrap{display:flex;-webkit-box-orient:horizontal;-webkit-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;flex-wrap:wrap}.vertical-wrap.centered{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.cardScalable{position:relative;contain:layout style}.cardPadder-backdrop,.cardPadder-mixedBackdrop,.cardPadder-overflowBackdrop,.cardPadder-overflowSmallBackdrop,.cardPadder-smallBackdrop{padding-bottom:56.25%;contain:strict}.cardPadder-mixedSquare,.cardPadder-overflowSquare,.cardPadder-square,.overflowSquareCard-textCardPadder{padding-bottom:100%;contain:strict}.cardPadder-mixedPortrait,.cardPadder-overflowPortrait,.cardPadder-portrait,.overflowPortraitCard-textCardPadder{padding-bottom:150%;contain:strict}.cardPadder-banner{padding-bottom:18.5%;contain:strict}.cardBox{padding:0!important;margin:.64em;-webkit-transition:none;-o-transition:none;transition:none;border:0 solid transparent;contain:layout style}@media all and (max-width:50em){.cardBox{margin:.4em}}.card-focuscontent{border:.12em solid transparent;-webkit-border-radius:.12em;border-radius:.12em}.card-focuscontent-large{border-width:.24em}.cardBox-focustransform{will-change:transform;-webkit-transition:-webkit-transform .2s ease-out;-o-transition:transform .2s ease-out;transition:transform .2s ease-out}.card:focus>.cardBox-focustransform{-webkit-transform:scale(1.16,1.16);transform:scale(1.16,1.16)}.cardBox-bottompadded{margin-bottom:1.8em!important}@media all and (max-width:50em){.cardBox-bottompadded{margin-bottom:1.2em!important}}.card:focus{position:relative!important;z-index:10!important}.btnCardOptions{position:absolute;bottom:.25em;right:0;margin:0!important;z-index:1}.mediaSourceIndicator{display:-webkit-box;display:-webkit-flex;display:flex;position:absolute;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;top:.3em;left:.3em;text-align:center;vertical-align:middle;width:1.6em;height:1.6em;-webkit-border-radius:50%;border-radius:50%;color:#fff;background:#38c}.cardText,.innerCardFooter{overflow:hidden;text-align:left}.cardImageContainer{-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;background-position:center center;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;position:relative;-webkit-background-clip:content-box!important;background-clip:content-box!important;color:inherit;height:100%;contain:strict}.cardContent,.cardImage{position:absolute;right:0;top:0;left:0;bottom:0}.chapterCardImageContainer{background-color:#000;-webkit-border-radius:0;border-radius:0}.textCardImageContainer{background-color:#333}.cardContent{overflow:hidden;display:block;margin:0!important;height:100%;-webkit-border-radius:.08em;border-radius:.08em;contain:strict}.cardImageContainer,.cardIndicators{display:-webkit-box;display:-webkit-flex}.cardContent-button{border:0!important;padding:0!important;color:inherit;width:100%;font-size:inherit}.cardContent-button:not(.defaultCardBackground){background-color:transparent}.visualCardBox .cardContent{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}.cardContent-shadow{-webkit-box-shadow:0 0 .68em rgba(0,0,0,.3);box-shadow:0 0 .68em rgba(0,0,0,.3)}.cardImageContainer{display:flex}.cardImage{-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;background-position:center bottom}.cardImage-img{max-height:100%;max-width:100%;min-height:70%;min-width:70%;margin:auto}.coveredImage-img{width:100%;height:100%}.coveredImage-noscale-img{max-height:none;max-width:none}.coveredImage{-webkit-background-size:100% 100%;background-size:100% 100%;background-position:center center}.coveredImage-noScale{-webkit-background-size:cover;background-size:cover}.cardFooter{padding:.3em .3em .5em;position:relative}.visualCardBox{-webkit-box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);-webkit-border-radius:.145em;border-radius:.145em}.innerCardFooter{background:rgba(0,0,0,.7);position:absolute;bottom:0;left:0;z-index:1;max-width:100%;color:#fff}.innerCardFooterClear{background-color:transparent}.fullInnerCardFooter{right:0}.cardText{padding:.06em .5em;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis}.cardDefaultText,.cardTextCentered{text-align:center}.cardText-secondary{font-size:84%}.cardText-first{padding-top:.24em}.innerCardFooter>.cardText{padding:.3em .5em}.cardFooter-withlogo{padding-left:4em;position:relative}.cardFooterLogo{position:absolute;top:0;bottom:0;left:0;width:4.5em;-webkit-background-size:70% auto;background-size:70% auto;background-repeat:no-repeat;background-position:center center}.cardText-rightmargin{margin-right:2em}.cardDefaultText{white-space:normal}.textActionButton{background:0 0;border:0!important;padding:0!important;color:inherit;font-size:inherit}.textActionButton:hover{text-decoration:underline}.cardImageIcon{width:1em;height:1em;font-size:5em;color:inherit}.cardImageIcon-small{font-size:3em;margin-bottom:.1em}.cardIndicators{right:.225em;top:.225em;position:absolute;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;contain:layout style}.cardProgramAttributeIndicators{top:0;left:0;position:absolute;display:-webkit-box;display:-webkit-flex;display:flex;text-transform:uppercase;font-size:92%}.programAttributeIndicator{padding:.18em .5em;color:#fff;font-weight:500}.cardOverlayButton{color:rgba(255,255,255,.76)!important;margin:0;z-index:1;padding:.75em;font-size:88%}.cardOverlayButton-hover{background:0 0;padding:.5em;color:#fff!important}.cardOverlayButton-br{position:absolute;bottom:0;right:0}.cardOverlayButtonIcon{background-color:rgba(0,0,0,.7)!important;-webkit-border-radius:100em;border-radius:100em;width:1.5em!important;height:1.5em!important;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:flex;font-size:1.66956521739130434em!important}.cardOverlayButton-centered{bottom:initial;right:initial;position:static;position:absolute;display:-webkit-box;display:-webkit-flex;display:flex;font-size:112%;margin:-1.3em 0 0 -1.3em;width:2.6em;height:2.6em;top:50%;left:50%;background-color:rgba(0,0,0,.5)!important;border:.06em solid rgba(255,255,255,.6);padding:.38em!important;color:rgba(255,255,255,.76);-webkit-transition:-webkit-transform .2s ease-out;-o-transition:transform .2s ease-out;transition:transform .2s ease-out}.cardOverlayButton-centered:hover{-webkit-transform:scale(1.2,1.2);transform:scale(1.2,1.2)}.backdropCard,.bannerCard{width:100%}.smallBackdropCard,.squareCard{width:50%}.portraitCard{width:33.333333333333333333333333333333%}.mixedPortraitCard{width:12em}.mixedSquareCard{width:18em}.mixedBackdropCard{width:32em}@media all and (min-width:400px){.backdropCard{width:50%}}@media all and (min-width:500px){.portraitCard,.smallBackdropCard,.squareCard{width:33.333333333333333333333333333333%}}@media all and (min-width:700px){.portraitCard,.squareCard{width:25%}}@media all and (min-width:770px){.backdropCard{width:33.333333333333333333333333333333%}}@media all and (min-width:800px){.bannerCard{width:50%}.portraitCard,.squareCard{width:20%}.smallBackdropCard{width:25%}}@media all and (min-width:1000px){.smallBackdropCard{width:20%}}@media all and (min-width:1200px){.backdropCard{width:25%}.portraitCard,.squareCard{width:16.666666666666666666666666666667%}.bannerCard{width:33.333333333333333333333333333333%}.smallBackdropCard{width:16.666666666666666666666666666667%}}@media all and (min-width:1400px){.portraitCard,.smallBackdropCard,.squareCard{width:14.285714285714285714285714285714%}}@media all and (min-width:1600px){.smallBackdropCard{width:12.5%}.backdropCard{width:20%}.portraitCard,.squareCard{width:12.5%}}@media all and (min-width:1920px){.portraitCard,.squareCard{width:11.111111111111111111111111111111%}}@media all and (min-width:2100px){.backdropCard{width:20%}}@media all and (min-width:2200px){.bannerCard{width:25%}.portraitCard,.squareCard{width:10%}}@media all and (min-width:2500px){.backdropCard{width:16.666666666666666666666666666667%}}.itemsContainer-tv>.backdropCard{width:25%}.itemsContainer-tv>.portraitCard,.itemsContainer-tv>.squareCard{width:16.666666666666666666666666666667%}@media all and (orientation:portrait){.overflowPortraitCard{width:42vw}.overflowBackdropCard,.overflowSmallBackdropCard{width:72vw}.overflowSquareCard{width:42vw}}@media all and (orientation:landscape){.overflowBackdropCard,.overflowSmallBackdropCard{width:23.3vw}.overflowPortraitCard,.overflowSquareCard{width:15.5vw}}@media all and (orientation:portrait) and (min-width:540px){.overflowSmallBackdropCard{width:30vw}}@media all and (orientation:landscape) and (min-width:800px){.overflowSmallBackdropCard{width:15.5vw}}@media all and (orientation:landscape) and (min-width:1700px){.overflowBackdropCard{width:18.5vw}.overflowPortraitCard,.overflowSquareCard{width:11.6vw}}@media all and (orientation:portrait) and (min-width:400px){.overflowPortraitCard{width:31.5vw}}@media all and (orientation:portrait) and (min-width:540px){.overflowBackdropCard{width:64vw}.overflowSquareCard{width:31.5vw}}@media all and (orientation:portrait) and (min-width:640px){.overflowBackdropCard{width:56vw}}@media all and (orientation:portrait) and (min-width:760px){.overflowPortraitCard{width:23vw}.overflowBackdropCard{width:40vw}.overflowSquareCard{width:23vw}}@media all and (orientation:portrait) and (min-width:1200px){.overflowPortraitCard,.overflowSquareCard{width:18vw}}@media all and (orientation:portrait) and (min-width:1400px){.overflowPortraitCard,.overflowSquareCard{width:15vw}.overflowBackdropCard{width:30vw}}@media all and (orientation:portrait) and (min-width:1800px){.overflowBackdropCard{width:23.5vw}}.itemsContainer-tv>.overflowBackdropCard{width:23.3vw}.overflowBackdropCard-textCard{width:15.5vw!important}.overflowBackdropCard-textCardPadder{padding-bottom:87.75%}.itemsContainer-tv>.overflowPortraitCard,.itemsContainer-tv>.overflowSquareCard{width:15.5vw}.itemsContainer-tv>.overflowSmallBackdropCard{width:18.9vw}.card-hoverable .cardContent{-webkit-transition-property:-webkit-filter,filter;-o-transition-property:filter;transition-property:filter;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s;-webkit-transition-timing-function:cubic-bezier(.3,0,0,1);-o-transition-timing-function:cubic-bezier(.3,0,0,1);transition-timing-function:cubic-bezier(.3,0,0,1)}.cardHoverItem{opacity:0;-webkit-transition:opacity .3s ease-in-out,-webkit-transform 10ms ease-in;-o-transition:opacity .3s ease-in-out,transform 10ms ease-in;transition:opacity .3s ease-in-out,transform 10ms ease-in;-webkit-transform:scale(0);transform:scale(0)}.card-hoverable:hover .cardHoverItem{opacity:1;-webkit-transition-delay:.4s;-o-transition-delay:.4s;transition-delay:.4s;-webkit-transform:scale(1);transform:scale(1)}.cardOverlayFab-primary{font-size:140%;padding:0;width:3em;height:3em;margin-top:-1.5em;margin-left:-1.5em;position:absolute;top:50%;left:50%}.cardOverlayFab-primary i{border:.08em solid rgba(255,255,255,.9);color:#fff} \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js index 774ff4a81f..2060ae85ae 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js +++ b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js @@ -1,2 +1,2 @@ -define(["datetime","imageLoader","connectionManager","itemHelper","focusManager","indicators","globalize","layoutManager","apphost","dom","browser","playbackManager","itemShortcuts","css!./card","paper-icon-button-light","programStyles"],function(datetime,imageLoader,connectionManager,itemHelper,focusManager,indicators,globalize,layoutManager,appHost,dom,browser,playbackManager,itemShortcuts){"use strict";function getCardsHtml(items,options){return 1===arguments.length&&(options=arguments[0],items=options.items),buildCardsHtmlInternal(items,options)}function getPostersPerRow(shape,screenWidth,isOrientationLandscape){switch(shape){case"portrait":return layoutManager.tv?5.9999999988:screenWidth>=2200?10:screenWidth>=1920?9.000000000009:screenWidth>=1600?8:screenWidth>=1400?7.0000000000021:screenWidth>=1200?5.9999999988:screenWidth>=800?5:screenWidth>=700?4:3.0000000003;case"square":return layoutManager.tv?5.9999999988:screenWidth>=2200?10:screenWidth>=1920?9.000000000009:screenWidth>=1600?8:screenWidth>=1400?7.0000000000021:screenWidth>=1200?5.9999999988:screenWidth>=800?5:screenWidth>=700?4:screenWidth>=500?3.0000000003:2;case"banner":return screenWidth>=2200?4:screenWidth>=1200?3.0000000003:screenWidth>=800?2:1;case"backdrop":return layoutManager.tv?4:screenWidth>=2500?6:screenWidth>=1600?5:screenWidth>=1200?4:screenWidth>=770?3:screenWidth>=420?2:1;case"smallBackdrop":return screenWidth>=1600?8:screenWidth>=1400?7.000000000007001:screenWidth>=1200?6:screenWidth>=1e3?5:screenWidth>=800?4:screenWidth>=500?3.0000000003:2;case"overflowSmallBackdrop":return layoutManager.tv?100/18.9:isOrientationLandscape?screenWidth>=800?100/15.5:100/23.3:screenWidth>=540?100/30:100/72;case"overflowPortrait":return layoutManager.tv?100/15.5:isOrientationLandscape?screenWidth>=1700?100/11.6:100/15.5:screenWidth>=1400?100/15:screenWidth>=1200?100/18:screenWidth>=760?100/23:screenWidth>=400?100/31.5:100/42;case"overflowSquare":return layoutManager.tv?100/15.5:isOrientationLandscape?screenWidth>=1700?100/11.6:100/15.5:screenWidth>=1400?100/15:screenWidth>=1200?100/18:screenWidth>=760?100/23:screenWidth>=540?100/31.5:100/42;case"overflowBackdrop":return layoutManager.tv?100/23.3:isOrientationLandscape?screenWidth>=1700?100/18.5:100/23.3:screenWidth>=1800?100/23.5:screenWidth>=1400?100/30:screenWidth>=760?2.5:screenWidth>=640?100/56:100/72;default:return 4}}function isResizable(windowWidth){var screen=window.screen;if(screen){if(screen.availWidth-windowWidth>20)return!0}return!1}function getImageWidth(shape,screenWidth,isOrientationLandscape){var imagesPerRow=getPostersPerRow(shape,screenWidth,isOrientationLandscape),shapeWidth=screenWidth/imagesPerRow;return Math.round(shapeWidth)}function setCardData(items,options){options.shape=options.shape||"auto";var primaryImageAspectRatio=imageLoader.getPrimaryImageAspectRatio(items);if("auto"===options.shape||"autohome"===options.shape||"autooverflow"===options.shape||"autoVertical"===options.shape){var requestedShape=options.shape;options.shape=null,primaryImageAspectRatio&&(primaryImageAspectRatio>=3?(options.shape="banner",options.coverImage=!0):options.shape=primaryImageAspectRatio>=1.33?"autooverflow"===requestedShape?"overflowBackdrop":"backdrop":primaryImageAspectRatio>.71?"autooverflow"===requestedShape?"overflowSquare":"square":"autooverflow"===requestedShape?"overflowPortrait":"portrait"),options.shape||(options.shape=options.defaultShape||("autooverflow"===requestedShape?"overflowSquare":"square"))}if("auto"===options.preferThumb&&(options.preferThumb="backdrop"===options.shape||"overflowBackdrop"===options.shape),options.uiAspect=getDesiredAspect(options.shape),options.primaryImageAspectRatio=primaryImageAspectRatio,!options.width&&options.widths&&(options.width=options.widths[options.shape]),options.rows&&"number"!=typeof options.rows&&(options.rows=options.rows[options.shape]),!options.width){var screenWidth=dom.getWindowSize().innerWidth,screenHeight=dom.getWindowSize().innerHeight;if(isResizable(screenWidth)){screenWidth=100*Math.floor(screenWidth/100)}options.width=getImageWidth(options.shape,screenWidth,screenWidth>1.3*screenHeight)}}function buildCardsHtmlInternal(items,options){var isVertical;"autoVertical"===options.shape&&(isVertical=!0),setCardData(items,options);var currentIndexValue,hasOpenRow,hasOpenSection,apiClient,lastServerId,i,length,html="",itemsInRow=0,sectionTitleTagName=options.sectionTitleTagName||"div";for(i=0,length=items.length;i=.5?.5:0)+"+":null);newIndexValue!==currentIndexValue&&(hasOpenRow&&(html+="
",hasOpenRow=!1,itemsInRow=0),hasOpenSection&&(html+="
",isVertical&&(html+="
"),hasOpenSection=!1),html+=isVertical?'
':'
',html+="<"+sectionTitleTagName+' class="sectionTitle">'+newIndexValue+"",isVertical&&(html+='
'),currentIndexValue=newIndexValue,hasOpenSection=!0)}options.rows&&0===itemsInRow&&(hasOpenRow&&(html+="
",hasOpenRow=!1),html+='
',hasOpenRow=!0),html+=buildCard(i,item,apiClient,options),itemsInRow++,options.rows&&itemsInRow>=options.rows&&(html+="
",hasOpenRow=!1,itemsInRow=0)}hasOpenRow&&(html+="
"),hasOpenSection&&(html+="
",isVertical&&(html+=""));var cardFooterHtml="";for(i=0,length=options.lines||0;i ':'
 
';if(options.leadingButtons)for(i=0,length=options.leadingButtons.length;i',cardBoxClass="cardBox";enableFocusTransfrom&&(cardBoxClass+=" cardBox-focustransform"),cardFooterHtml&&(cardBoxClass+=" cardBox-bottompadded");var cardScalableClass="cardScalable card-focuscontent";cardScalableClass+=" card-focuscontent",enableFocusTransfrom||(cardScalableClass+=" card-focuscontent-large"),html+='
';var icon="";return buttonInfo.icon&&(icon=''+buttonInfo.icon+""),html+='
'+icon+'
'+buttonInfo.name+"
",html+=cardFooterHtml,html+="
",buttonInfo.routeUrl?html+="":html+="",html}function getDesiredAspect(shape){if(shape){if(shape=shape.toLowerCase(),-1!==shape.indexOf("portrait"))return 2/3;if(-1!==shape.indexOf("backdrop"))return 16/9;if(-1!==shape.indexOf("square"))return 1;if(-1!==shape.indexOf("banner"))return 1e3/185}return null}function getCardImageUrl(item,apiClient,options,shape){item=item.ProgramInfo||item;var width=options.width,height=null,primaryImageAspectRatio=item.PrimaryImageAspectRatio,forceName=!1,imgUrl=null,coverImage=!1,uiAspect=null;return options.preferThumb&&item.ImageTags&&item.ImageTags.Thumb?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Thumb",maxWidth:width,tag:item.ImageTags.Thumb}):(options.preferBanner||"banner"===shape)&&item.ImageTags&&item.ImageTags.Banner?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Banner",maxWidth:width,tag:item.ImageTags.Banner}):options.preferDisc&&item.ImageTags&&item.ImageTags.Disc?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Disc",maxWidth:width,tag:item.ImageTags.Disc}):options.preferLogo&&item.ImageTags&&item.ImageTags.Logo?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Logo",maxWidth:width,tag:item.ImageTags.Logo}):options.preferLogo&&item.ParentLogoImageTag&&item.ParentLogoItemId?imgUrl=apiClient.getScaledImageUrl(item.ParentLogoItemId,{type:"Logo",maxWidth:width,tag:item.ParentLogoImageTag}):options.preferThumb&&item.SeriesThumbImageTag&&!1!==options.inheritThumb?imgUrl=apiClient.getScaledImageUrl(item.SeriesId,{type:"Thumb",maxWidth:width,tag:item.SeriesThumbImageTag}):options.preferThumb&&item.ParentThumbItemId&&!1!==options.inheritThumb&&"Photo"!==item.MediaType?imgUrl=apiClient.getScaledImageUrl(item.ParentThumbItemId,{type:"Thumb",maxWidth:width,tag:item.ParentThumbImageTag}):options.preferThumb&&item.BackdropImageTags&&item.BackdropImageTags.length?(imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Backdrop",maxWidth:width,tag:item.BackdropImageTags[0]}),forceName=!0):options.preferThumb&&item.ParentBackdropImageTags&&item.ParentBackdropImageTags.length&&!1!==options.inheritThumb&&"Episode"===item.Type?imgUrl=apiClient.getScaledImageUrl(item.ParentBackdropItemId,{type:"Backdrop",maxWidth:width,tag:item.ParentBackdropImageTags[0]}):item.ImageTags&&item.ImageTags.Primary?(height=width&&primaryImageAspectRatio?Math.round(width/primaryImageAspectRatio):null,imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Primary",maxHeight:height,maxWidth:width,tag:item.ImageTags.Primary}),options.preferThumb&&!1!==options.showTitle&&(forceName=!0),primaryImageAspectRatio&&(uiAspect=getDesiredAspect(shape))&&(coverImage=Math.abs(primaryImageAspectRatio-uiAspect)/uiAspect<=.2)):item.PrimaryImageTag?(height=width&&primaryImageAspectRatio?Math.round(width/primaryImageAspectRatio):null,imgUrl=apiClient.getScaledImageUrl(item.PrimaryImageItemId||item.Id||item.ItemId,{type:"Primary",maxHeight:height,maxWidth:width,tag:item.PrimaryImageTag}),options.preferThumb&&!1!==options.showTitle&&(forceName=!0),primaryImageAspectRatio&&(uiAspect=getDesiredAspect(shape))&&(coverImage=Math.abs(primaryImageAspectRatio-uiAspect)/uiAspect<=.2)):item.ParentPrimaryImageTag?imgUrl=apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId,{type:"Primary",maxWidth:width,tag:item.ParentPrimaryImageTag}):item.SeriesPrimaryImageTag?imgUrl=apiClient.getScaledImageUrl(item.SeriesId,{type:"Primary",maxWidth:width,tag:item.SeriesPrimaryImageTag}):item.AlbumId&&item.AlbumPrimaryImageTag?(width=primaryImageAspectRatio?Math.round(height*primaryImageAspectRatio):null,imgUrl=apiClient.getScaledImageUrl(item.AlbumId,{type:"Primary",maxHeight:height,maxWidth:width,tag:item.AlbumPrimaryImageTag}),primaryImageAspectRatio&&(uiAspect=getDesiredAspect(shape))&&(coverImage=Math.abs(primaryImageAspectRatio-uiAspect)/uiAspect<=.2)):"Season"===item.Type&&item.ImageTags&&item.ImageTags.Thumb?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Thumb",maxWidth:width,tag:item.ImageTags.Thumb}):item.BackdropImageTags&&item.BackdropImageTags.length?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Backdrop",maxWidth:width,tag:item.BackdropImageTags[0]}):item.ImageTags&&item.ImageTags.Thumb?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Thumb",maxWidth:width,tag:item.ImageTags.Thumb}):item.SeriesThumbImageTag&&!1!==options.inheritThumb?imgUrl=apiClient.getScaledImageUrl(item.SeriesId,{type:"Thumb",maxWidth:width,tag:item.SeriesThumbImageTag}):item.ParentThumbItemId&&!1!==options.inheritThumb?imgUrl=apiClient.getScaledImageUrl(item.ParentThumbItemId,{type:"Thumb",maxWidth:width,tag:item.ParentThumbImageTag}):item.ParentBackdropImageTags&&item.ParentBackdropImageTags.length&&!1!==options.inheritThumb&&(imgUrl=apiClient.getScaledImageUrl(item.ParentBackdropItemId,{type:"Backdrop",maxWidth:width,tag:item.ParentBackdropImageTags[0]})),{imgUrl:imgUrl,forceName:forceName,coverImage:coverImage}}function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min}function getDefaultColorIndex(str){if(str){for(var charIndex=Math.floor(str.length/2),character=String(str.substr(charIndex,1).charCodeAt()),sum=0,i=0;i0&&isOuterFooter?currentCssClass+=" cardText-secondary":0===valid&&isOuterFooter&&(currentCssClass+=" cardText-first"),addRightMargin&&(currentCssClass+=" cardText-rightmargin"),text&&(html+="
",html+=text,html+="
",valid++,maxLines&&valid>=maxLines))break}if(forceLines)for(length=maxLines||Math.min(lines.length,maxLines||lines.length);valid ",valid++;return html}function isUsingLiveTvNaming(item){return"Program"===item.Type||"Timer"===item.Type||"Recording"===item.Type}function getAirTimeText(item,showAirDateTime,showAirEndTime){var airTimeText="";if(item.StartDate)try{var date=datetime.parseISO8601Date(item.StartDate);showAirDateTime&&(airTimeText+=datetime.toLocaleDateString(date,{weekday:"short",month:"short",day:"numeric"})+" "),airTimeText+=datetime.getDisplayTime(date),item.EndDate&&showAirEndTime&&(date=datetime.parseISO8601Date(item.EndDate),airTimeText+=" - "+datetime.getDisplayTime(date))}catch(e){console.log("Error parsing date: "+item.StartDate)}return airTimeText}function getCardFooterText(item,apiClient,options,showTitle,forceName,overlayText,imgUrl,footerClass,progressHtml,logoUrl,isOuterFooter){var html="";logoUrl&&(html+='');var showOtherText=isOuterFooter?!overlayText:overlayText;if(isOuterFooter&&options.cardLayout&&!layoutManager.tv&&"none"!==options.cardFooterAside){html+=''}var titleAdded,cssClass=options.centerText?"cardText cardTextCentered":"cardText",lines=[],parentTitleUnderneath="MusicAlbum"===item.Type||"Audio"===item.Type||"MusicVideo"===item.Type;if(showOtherText&&(options.showParentTitle||options.showParentTitleOrTitle)&&!parentTitleUnderneath)if(isOuterFooter&&"Episode"===item.Type&&item.SeriesName)item.SeriesId?lines.push(getTextActionButton({Id:item.SeriesId,ServerId:item.ServerId,Name:item.SeriesName,Type:"Series",IsFolder:!0})):lines.push(item.SeriesName);else if(isUsingLiveTvNaming(item))lines.push(item.Name),item.EpisodeTitle||(titleAdded=!0);else{var parentTitle=item.SeriesName||item.Series||item.Album||item.AlbumArtist||item.GameSystem||"";(parentTitle||showTitle)&&lines.push(parentTitle)}var showMediaTitle=showTitle&&!titleAdded||options.showParentTitleOrTitle&&!lines.length;if(showMediaTitle||titleAdded||!showTitle&&!forceName||(showMediaTitle=!0),showMediaTitle){var name="auto"!==options.showTitle||item.IsFolder||"Photo"!==item.MediaType?itemHelper.getDisplayName(item,{includeParentInfo:options.includeParentInfoInTitle}):"";lines.push(name)}if(showOtherText){if(options.showParentTitle&&parentTitleUnderneath&&(isOuterFooter&&item.AlbumArtists&&item.AlbumArtists.length?(item.AlbumArtists[0].Type="MusicArtist",item.AlbumArtists[0].IsFolder=!0,lines.push(getTextActionButton(item.AlbumArtists[0],null,item.ServerId))):lines.push(isUsingLiveTvNaming(item)?item.Name:item.SeriesName||item.Series||item.Album||item.AlbumArtist||item.GameSystem||"")),options.showItemCounts){var itemCountHtml=getItemCountsHtml(options,item);lines.push(itemCountHtml)}if(options.textLines)for(var additionalLines=options.textLines(item),i=0,length=additionalLines.length;i'+html,html+=""),html}function getTextActionButton(item,text,serverId){if(text||(text=itemHelper.getDisplayName(item)),layoutManager.tv)return text;var html=""}function getItemCountsHtml(options,item){var childText,counts=[];if("Playlist"===item.Type){if(childText="",item.RunTimeTicks){var minutes=item.RunTimeTicks/6e8;minutes=minutes||1,childText+=globalize.translate("sharedcomponents#ValueMinutes",Math.round(minutes))}else childText+=globalize.translate("sharedcomponents#ValueMinutes",0);counts.push(childText)}else"Genre"===item.Type||"Studio"===item.Type?(item.MovieCount&&(childText=1===item.MovieCount?globalize.translate("sharedcomponents#ValueOneMovie"):globalize.translate("sharedcomponents#ValueMovieCount",item.MovieCount),counts.push(childText)),item.SeriesCount&&(childText=1===item.SeriesCount?globalize.translate("sharedcomponents#ValueOneSeries"):globalize.translate("sharedcomponents#ValueSeriesCount",item.SeriesCount),counts.push(childText)),item.EpisodeCount&&(childText=1===item.EpisodeCount?globalize.translate("sharedcomponents#ValueOneEpisode"):globalize.translate("sharedcomponents#ValueEpisodeCount",item.EpisodeCount),counts.push(childText)),item.GameCount&&(childText=1===item.GameCount?globalize.translate("sharedcomponents#ValueOneGame"):globalize.translate("sharedcomponents#ValueGameCount",item.GameCount),counts.push(childText))):"GameGenre"===item.Type?item.GameCount&&(childText=1===item.GameCount?globalize.translate("sharedcomponents#ValueOneGame"):globalize.translate("sharedcomponents#ValueGameCount",item.GameCount),counts.push(childText)):"MusicGenre"===item.Type||"MusicArtist"===options.context?(item.AlbumCount&&(childText=1===item.AlbumCount?globalize.translate("sharedcomponents#ValueOneAlbum"):globalize.translate("sharedcomponents#ValueAlbumCount",item.AlbumCount),counts.push(childText)),item.SongCount&&(childText=1===item.SongCount?globalize.translate("sharedcomponents#ValueOneSong"):globalize.translate("sharedcomponents#ValueSongCount",item.SongCount),counts.push(childText)),item.MusicVideoCount&&(childText=1===item.MusicVideoCount?globalize.translate("sharedcomponents#ValueOneMusicVideo"):globalize.translate("sharedcomponents#ValueMusicVideoCount",item.MusicVideoCount),counts.push(childText))):"Series"===item.Type&&(childText=1===item.RecursiveItemCount?globalize.translate("sharedcomponents#ValueOneEpisode"):globalize.translate("sharedcomponents#ValueEpisodeCount",item.RecursiveItemCount),counts.push(childText));return counts.join(", ")}function requireRefreshIndicator(){refreshIndicatorLoaded||(refreshIndicatorLoaded=!0,require(["emby-itemrefreshindicator"]))}function getDefaultBackgroundClass(str){return"defaultCardBackground defaultCardBackground"+getDefaultColorIndex(str)}function buildCard(index,item,apiClient,options){var action=options.action||"link";"play"===action&&item.IsFolder?action="link":"Photo"===item.MediaType&&(action="play");var shape=options.shape;if("mixed"===shape){shape=null;var primaryImageAspectRatio=item.PrimaryImageAspectRatio;primaryImageAspectRatio&&(shape=primaryImageAspectRatio>=1.33?"mixedBackdrop":primaryImageAspectRatio>.71?"mixedSquare":"mixedPortrait"),shape=shape||"mixedSquare"}var className="card";shape&&(className+=" "+shape+"Card"),options.cardCssClass&&(className+=" "+options.cardCssClass),options.cardClass&&(className+=" "+options.cardClass),enableFocusTransfrom&&layoutManager.tv||(className+=" card-nofocustransform");var imgInfo=getCardImageUrl(item,apiClient,options,shape),imgUrl=imgInfo.imgUrl,forceName=imgInfo.forceName,showTitle="auto"===options.showTitle||(options.showTitle||"PhotoAlbum"===item.Type||"Folder"===item.Type),overlayText=options.overlayText;forceName&&!options.cardLayout&&null==overlayText&&(overlayText=!0);var cardImageContainerClass="cardImageContainer";(options.coverImage||imgInfo.coverImage)&&(cardImageContainerClass+=" coveredImage",("Photo"===item.MediaType||"PhotoAlbum"===item.Type||"Folder"===item.Type||item.ProgramInfo||"Program"===item.Type||"Recording"===item.Type)&&(cardImageContainerClass+=" coveredImage-noScale")),imgUrl||(cardImageContainerClass+=" "+getDefaultBackgroundClass(item.Name));var cardBoxClass=options.cardLayout?"cardBox visualCardBox":"cardBox";layoutManager.tv&&(enableFocusTransfrom&&(cardBoxClass+=" cardBox-focustransform"),options.cardLayout&&(cardBoxClass+=" card-focuscontent",enableFocusTransfrom||(cardBoxClass+=" card-focuscontent-large")));var footerCssClass,logoUrl,progressHtml=indicators.getProgressBarHtml(item),innerCardFooter="",footerOverlayed=!1;options.showChannelLogo&&item.ChannelPrimaryImageTag?logoUrl=apiClient.getScaledImageUrl(item.ChannelId,{type:"Primary",height:40,tag:item.ChannelPrimaryImageTag}):options.showLogo&&item.ParentLogoImageTag&&(logoUrl=apiClient.getScaledImageUrl(item.ParentLogoItemId,{type:"Logo",height:40,tag:item.ParentLogoImageTag})),overlayText?(logoUrl=null,footerCssClass=progressHtml?"innerCardFooter fullInnerCardFooter":"innerCardFooter",innerCardFooter+=getCardFooterText(item,apiClient,options,showTitle,forceName,overlayText,imgUrl,footerCssClass,progressHtml,logoUrl,!1),footerOverlayed=!0):progressHtml&&(innerCardFooter+='
',innerCardFooter+=progressHtml,innerCardFooter+="
",progressHtml="");var mediaSourceCount=item.MediaSourceCount||1;mediaSourceCount>1&&(innerCardFooter+='
'+mediaSourceCount+"
");var outerCardFooter="";overlayText||footerOverlayed||(footerCssClass=options.cardLayout?"cardFooter":"cardFooter cardFooter-transparent",logoUrl&&(footerCssClass+=" cardFooter-withlogo"),options.cardLayout||(logoUrl=null),outerCardFooter=getCardFooterText(item,apiClient,options,showTitle,forceName,overlayText,imgUrl,footerCssClass,progressHtml,logoUrl,!0)),outerCardFooter&&!options.cardLayout&&(cardBoxClass+=" cardBox-bottompadded");var overlayButtons="";if(layoutManager.mobile){var overlayPlayButton=options.overlayPlayButton;null!=overlayPlayButton||options.overlayMoreButton||options.overlayInfoButton||options.cardLayout||(overlayPlayButton="Video"===item.MediaType);var btnCssClass="cardOverlayButton cardOverlayButton-br itemAction";if(options.centerPlayButton&&(overlayButtons+=''),!overlayPlayButton||item.IsPlaceHolder||"Virtual"===item.LocationType&&item.MediaType&&"Program"!==item.Type||"Person"===item.Type||(overlayButtons+=''),options.overlayMoreButton){overlayButtons+=''}}options.showChildCountIndicator&&item.ChildCount&&(className+=" groupedCard");var cardImageContainerOpen,cardImageContainerClose="",cardBoxClose="",cardScalableClose="",cardContentClass="cardContent";options.cardLayout||(cardContentClass+=" cardContent-shadow"),layoutManager.tv?(cardImageContainerOpen=imgUrl?'
':'
',cardImageContainerClose="
"):(cardImageContainerOpen=imgUrl?'");var cardScalableClass="cardScalable";layoutManager.tv&&!options.cardLayout&&(cardScalableClass+=" card-focuscontent",enableFocusTransfrom||(cardScalableClass+=" card-focuscontent-large")),cardImageContainerOpen='
'+cardImageContainerOpen,cardBoxClose="
",cardScalableClose="
";var indicatorsHtml="";if(!1!==options.missingIndicator&&(indicatorsHtml+=indicators.getMissingIndicator(item)),indicatorsHtml+=indicators.getSyncIndicator(item),indicatorsHtml+=indicators.getTimerIndicator(item),indicatorsHtml+=indicators.getTypeIndicator(item),options.showGroupCount?indicatorsHtml+=indicators.getChildCountIndicatorHtml(item,{minCount:1}):indicatorsHtml+=indicators.getPlayedIndicatorHtml(item),"CollectionFolder"===item.Type||item.CollectionType){indicatorsHtml+='
',requireRefreshIndicator()}indicatorsHtml&&(cardImageContainerOpen+='
'+indicatorsHtml+"
"),imgUrl||(cardImageContainerOpen+=getCardDefaultText(item,options));var tagName=layoutManager.tv&&!overlayButtons?"button":"div",nameWithPrefix=item.SortName||item.Name||"",prefix=nameWithPrefix.substring(0,Math.min(3,nameWithPrefix.length));prefix&&(prefix=prefix.toUpperCase());var timerAttributes="";item.TimerId&&(timerAttributes+=' data-timerid="'+item.TimerId+'"'),item.SeriesTimerId&&(timerAttributes+=' data-seriestimerid="'+item.SeriesTimerId+'"');var actionAttribute;"button"===tagName?(className+=" itemAction",actionAttribute=' data-action="'+action+'"'):actionAttribute="","MusicAlbum"!==item.Type&&"MusicArtist"!==item.Type&&"Audio"!==item.Type&&(className+=" card-withuserdata");var positionTicksData=item.UserData&&item.UserData.PlaybackPositionTicks?' data-positionticks="'+item.UserData.PlaybackPositionTicks+'"':"",collectionIdData=options.collectionId?' data-collectionid="'+options.collectionId+'"':"",playlistIdData=options.playlistId?' data-playlistid="'+options.playlistId+'"':"",mediaTypeData=item.MediaType?' data-mediatype="'+item.MediaType+'"':"",collectionTypeData=item.CollectionType?' data-collectiontype="'+item.CollectionType+'"':"",channelIdData=item.ChannelId?' data-channelid="'+item.ChannelId+'"':"",contextData=options.context?' data-context="'+options.context+'"':"",parentIdData=options.parentId?' data-parentid="'+options.parentId+'"':"",additionalCardContent="";return layoutManager.desktop&&(additionalCardContent+=getHoverMenuHtml(item)),"<"+tagName+' data-index="'+index+'"'+timerAttributes+actionAttribute+' data-isfolder="'+(item.IsFolder||!1)+'" data-serverid="'+(item.ServerId||options.serverId)+'" data-id="'+(item.Id||item.ItemId)+'" data-type="'+item.Type+'"'+mediaTypeData+collectionTypeData+channelIdData+positionTicksData+collectionIdData+playlistIdData+contextData+parentIdData+' data-prefix="'+prefix+'" class="'+className+'">'+cardImageContainerOpen+innerCardFooter+cardImageContainerClose+overlayButtons+additionalCardContent+cardScalableClose+outerCardFooter+cardBoxClose+""}function getHoverMenuHtml(item){var html="";html+='
';var btnCssClass="cardOverlayButton cardOverlayButton-hover itemAction";playbackManager.canPlay(item)&&(html+=''),html+='
';html+='';var userData=item.UserData||{};if(itemHelper.canMarkPlayed(item)&&(require(["emby-playstatebutton"]),html+=''),itemHelper.canRate(item)){var likes=null==userData.Likes?"":userData.Likes;require(["emby-ratingbutton"]),html+=''}return html+="
",html+="
"}function getCardDefaultText(item,options){var collectionType=item.CollectionType +define(["datetime","imageLoader","connectionManager","itemHelper","focusManager","indicators","globalize","layoutManager","apphost","dom","browser","playbackManager","itemShortcuts","css!./card","paper-icon-button-light","programStyles"],function(datetime,imageLoader,connectionManager,itemHelper,focusManager,indicators,globalize,layoutManager,appHost,dom,browser,playbackManager,itemShortcuts){"use strict";function getCardsHtml(items,options){return 1===arguments.length&&(options=arguments[0],items=options.items),buildCardsHtmlInternal(items,options)}function getPostersPerRow(shape,screenWidth,isOrientationLandscape){switch(shape){case"portrait":return layoutManager.tv?5.9999999988:screenWidth>=2200?10:screenWidth>=1920?9.000000000009:screenWidth>=1600?8:screenWidth>=1400?7.0000000000021:screenWidth>=1200?5.9999999988:screenWidth>=800?5:screenWidth>=700?4:3.0000000003;case"square":return layoutManager.tv?5.9999999988:screenWidth>=2200?10:screenWidth>=1920?9.000000000009:screenWidth>=1600?8:screenWidth>=1400?7.0000000000021:screenWidth>=1200?5.9999999988:screenWidth>=800?5:screenWidth>=700?4:screenWidth>=500?3.0000000003:2;case"banner":return screenWidth>=2200?4:screenWidth>=1200?3.0000000003:screenWidth>=800?2:1;case"backdrop":return layoutManager.tv?4:screenWidth>=2500?6:screenWidth>=1600?5:screenWidth>=1200?4:screenWidth>=770?3:screenWidth>=420?2:1;case"smallBackdrop":return screenWidth>=1600?8:screenWidth>=1400?7.000000000007001:screenWidth>=1200?6:screenWidth>=1e3?5:screenWidth>=800?4:screenWidth>=500?3.0000000003:2;case"overflowSmallBackdrop":return layoutManager.tv?100/18.9:isOrientationLandscape?screenWidth>=800?100/15.5:100/23.3:screenWidth>=540?100/30:100/72;case"overflowPortrait":return layoutManager.tv?100/15.5:isOrientationLandscape?screenWidth>=1700?100/11.6:100/15.5:screenWidth>=1400?100/15:screenWidth>=1200?100/18:screenWidth>=760?100/23:screenWidth>=400?100/31.5:100/42;case"overflowSquare":return layoutManager.tv?100/15.5:isOrientationLandscape?screenWidth>=1700?100/11.6:100/15.5:screenWidth>=1400?100/15:screenWidth>=1200?100/18:screenWidth>=760?100/23:screenWidth>=540?100/31.5:100/42;case"overflowBackdrop":return layoutManager.tv?100/23.3:isOrientationLandscape?screenWidth>=1700?100/18.5:100/23.3:screenWidth>=1800?100/23.5:screenWidth>=1400?100/30:screenWidth>=760?2.5:screenWidth>=640?100/56:100/72;default:return 4}}function isResizable(windowWidth){var screen=window.screen;if(screen){if(screen.availWidth-windowWidth>20)return!0}return!1}function getImageWidth(shape,screenWidth,isOrientationLandscape){var imagesPerRow=getPostersPerRow(shape,screenWidth,isOrientationLandscape),shapeWidth=screenWidth/imagesPerRow;return Math.round(shapeWidth)}function setCardData(items,options){options.shape=options.shape||"auto";var primaryImageAspectRatio=imageLoader.getPrimaryImageAspectRatio(items);if("auto"===options.shape||"autohome"===options.shape||"autooverflow"===options.shape||"autoVertical"===options.shape){var requestedShape=options.shape;options.shape=null,primaryImageAspectRatio&&(primaryImageAspectRatio>=3?(options.shape="banner",options.coverImage=!0):options.shape=primaryImageAspectRatio>=1.33?"autooverflow"===requestedShape?"overflowBackdrop":"backdrop":primaryImageAspectRatio>.71?"autooverflow"===requestedShape?"overflowSquare":"square":"autooverflow"===requestedShape?"overflowPortrait":"portrait"),options.shape||(options.shape=options.defaultShape||("autooverflow"===requestedShape?"overflowSquare":"square"))}if("auto"===options.preferThumb&&(options.preferThumb="backdrop"===options.shape||"overflowBackdrop"===options.shape),options.uiAspect=getDesiredAspect(options.shape),options.primaryImageAspectRatio=primaryImageAspectRatio,!options.width&&options.widths&&(options.width=options.widths[options.shape]),options.rows&&"number"!=typeof options.rows&&(options.rows=options.rows[options.shape]),!options.width){var screenWidth=dom.getWindowSize().innerWidth,screenHeight=dom.getWindowSize().innerHeight;if(isResizable(screenWidth)){screenWidth=100*Math.floor(screenWidth/100)}options.width=getImageWidth(options.shape,screenWidth,screenWidth>1.3*screenHeight)}}function buildCardsHtmlInternal(items,options){var isVertical;"autoVertical"===options.shape&&(isVertical=!0),setCardData(items,options);var currentIndexValue,hasOpenRow,hasOpenSection,apiClient,lastServerId,i,length,html="",itemsInRow=0,sectionTitleTagName=options.sectionTitleTagName||"div";for(i=0,length=items.length;i=.5?.5:0)+"+":null);newIndexValue!==currentIndexValue&&(hasOpenRow&&(html+="
",hasOpenRow=!1,itemsInRow=0),hasOpenSection&&(html+="",isVertical&&(html+=""),hasOpenSection=!1),html+=isVertical?'
':'
',html+="<"+sectionTitleTagName+' class="sectionTitle">'+newIndexValue+"",isVertical&&(html+='
'),currentIndexValue=newIndexValue,hasOpenSection=!0)}options.rows&&0===itemsInRow&&(hasOpenRow&&(html+="
",hasOpenRow=!1),html+='
',hasOpenRow=!0),html+=buildCard(i,item,apiClient,options),itemsInRow++,options.rows&&itemsInRow>=options.rows&&(html+="
",hasOpenRow=!1,itemsInRow=0)}hasOpenRow&&(html+="
"),hasOpenSection&&(html+="
",isVertical&&(html+=""));var cardFooterHtml="";for(i=0,length=options.lines||0;i ':'
 
';if(options.leadingButtons)for(i=0,length=options.leadingButtons.length;i',cardBoxClass="cardBox";enableFocusTransfrom&&(cardBoxClass+=" cardBox-focustransform"),cardFooterHtml&&(cardBoxClass+=" cardBox-bottompadded");var cardScalableClass="cardScalable card-focuscontent";cardScalableClass+=" card-focuscontent",enableFocusTransfrom||(cardScalableClass+=" card-focuscontent-large"),html+='
';var icon="";return buttonInfo.icon&&(icon=''+buttonInfo.icon+""),html+='
'+icon+'
'+buttonInfo.name+"
",html+=cardFooterHtml,html+="
",buttonInfo.routeUrl?html+="":html+="",html}function getDesiredAspect(shape){if(shape){if(shape=shape.toLowerCase(),-1!==shape.indexOf("portrait"))return 2/3;if(-1!==shape.indexOf("backdrop"))return 16/9;if(-1!==shape.indexOf("square"))return 1;if(-1!==shape.indexOf("banner"))return 1e3/185}return null}function getCardImageUrl(item,apiClient,options,shape){item=item.ProgramInfo||item;var width=options.width,height=null,primaryImageAspectRatio=item.PrimaryImageAspectRatio,forceName=!1,imgUrl=null,coverImage=!1,uiAspect=null;return options.preferThumb&&item.ImageTags&&item.ImageTags.Thumb?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Thumb",maxWidth:width,tag:item.ImageTags.Thumb}):(options.preferBanner||"banner"===shape)&&item.ImageTags&&item.ImageTags.Banner?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Banner",maxWidth:width,tag:item.ImageTags.Banner}):options.preferDisc&&item.ImageTags&&item.ImageTags.Disc?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Disc",maxWidth:width,tag:item.ImageTags.Disc}):options.preferLogo&&item.ImageTags&&item.ImageTags.Logo?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Logo",maxWidth:width,tag:item.ImageTags.Logo}):options.preferLogo&&item.ParentLogoImageTag&&item.ParentLogoItemId?imgUrl=apiClient.getScaledImageUrl(item.ParentLogoItemId,{type:"Logo",maxWidth:width,tag:item.ParentLogoImageTag}):options.preferThumb&&item.SeriesThumbImageTag&&!1!==options.inheritThumb?imgUrl=apiClient.getScaledImageUrl(item.SeriesId,{type:"Thumb",maxWidth:width,tag:item.SeriesThumbImageTag}):options.preferThumb&&item.ParentThumbItemId&&!1!==options.inheritThumb&&"Photo"!==item.MediaType?imgUrl=apiClient.getScaledImageUrl(item.ParentThumbItemId,{type:"Thumb",maxWidth:width,tag:item.ParentThumbImageTag}):options.preferThumb&&item.BackdropImageTags&&item.BackdropImageTags.length?(imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Backdrop",maxWidth:width,tag:item.BackdropImageTags[0]}),forceName=!0):options.preferThumb&&item.ParentBackdropImageTags&&item.ParentBackdropImageTags.length&&!1!==options.inheritThumb&&"Episode"===item.Type?imgUrl=apiClient.getScaledImageUrl(item.ParentBackdropItemId,{type:"Backdrop",maxWidth:width,tag:item.ParentBackdropImageTags[0]}):item.ImageTags&&item.ImageTags.Primary?(height=width&&primaryImageAspectRatio?Math.round(width/primaryImageAspectRatio):null,imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Primary",maxHeight:height,maxWidth:width,tag:item.ImageTags.Primary}),options.preferThumb&&!1!==options.showTitle&&(forceName=!0),primaryImageAspectRatio&&(uiAspect=getDesiredAspect(shape))&&(coverImage=Math.abs(primaryImageAspectRatio-uiAspect)/uiAspect<=.2)):item.PrimaryImageTag?(height=width&&primaryImageAspectRatio?Math.round(width/primaryImageAspectRatio):null,imgUrl=apiClient.getScaledImageUrl(item.PrimaryImageItemId||item.Id||item.ItemId,{type:"Primary",maxHeight:height,maxWidth:width,tag:item.PrimaryImageTag}),options.preferThumb&&!1!==options.showTitle&&(forceName=!0),primaryImageAspectRatio&&(uiAspect=getDesiredAspect(shape))&&(coverImage=Math.abs(primaryImageAspectRatio-uiAspect)/uiAspect<=.2)):item.ParentPrimaryImageTag?imgUrl=apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId,{type:"Primary",maxWidth:width,tag:item.ParentPrimaryImageTag}):item.SeriesPrimaryImageTag?imgUrl=apiClient.getScaledImageUrl(item.SeriesId,{type:"Primary",maxWidth:width,tag:item.SeriesPrimaryImageTag}):item.AlbumId&&item.AlbumPrimaryImageTag?(width=primaryImageAspectRatio?Math.round(height*primaryImageAspectRatio):null,imgUrl=apiClient.getScaledImageUrl(item.AlbumId,{type:"Primary",maxHeight:height,maxWidth:width,tag:item.AlbumPrimaryImageTag}),primaryImageAspectRatio&&(uiAspect=getDesiredAspect(shape))&&(coverImage=Math.abs(primaryImageAspectRatio-uiAspect)/uiAspect<=.2)):"Season"===item.Type&&item.ImageTags&&item.ImageTags.Thumb?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Thumb",maxWidth:width,tag:item.ImageTags.Thumb}):item.BackdropImageTags&&item.BackdropImageTags.length?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Backdrop",maxWidth:width,tag:item.BackdropImageTags[0]}):item.ImageTags&&item.ImageTags.Thumb?imgUrl=apiClient.getScaledImageUrl(item.Id,{type:"Thumb",maxWidth:width,tag:item.ImageTags.Thumb}):item.SeriesThumbImageTag&&!1!==options.inheritThumb?imgUrl=apiClient.getScaledImageUrl(item.SeriesId,{type:"Thumb",maxWidth:width,tag:item.SeriesThumbImageTag}):item.ParentThumbItemId&&!1!==options.inheritThumb?imgUrl=apiClient.getScaledImageUrl(item.ParentThumbItemId,{type:"Thumb",maxWidth:width,tag:item.ParentThumbImageTag}):item.ParentBackdropImageTags&&item.ParentBackdropImageTags.length&&!1!==options.inheritThumb&&(imgUrl=apiClient.getScaledImageUrl(item.ParentBackdropItemId,{type:"Backdrop",maxWidth:width,tag:item.ParentBackdropImageTags[0]})),{imgUrl:imgUrl,forceName:forceName,coverImage:coverImage}}function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min}function getDefaultColorIndex(str){if(str){for(var charIndex=Math.floor(str.length/2),character=String(str.substr(charIndex,1).charCodeAt()),sum=0,i=0;i0&&isOuterFooter?currentCssClass+=" cardText-secondary":0===valid&&isOuterFooter&&(currentCssClass+=" cardText-first"),addRightMargin&&(currentCssClass+=" cardText-rightmargin"),text&&(html+="
",html+=text,html+="
",valid++,maxLines&&valid>=maxLines))break}if(forceLines)for(length=maxLines||Math.min(lines.length,maxLines||lines.length);valid ",valid++;return html}function isUsingLiveTvNaming(item){return"Program"===item.Type||"Timer"===item.Type||"Recording"===item.Type}function getAirTimeText(item,showAirDateTime,showAirEndTime){var airTimeText="";if(item.StartDate)try{var date=datetime.parseISO8601Date(item.StartDate);showAirDateTime&&(airTimeText+=datetime.toLocaleDateString(date,{weekday:"short",month:"short",day:"numeric"})+" "),airTimeText+=datetime.getDisplayTime(date),item.EndDate&&showAirEndTime&&(date=datetime.parseISO8601Date(item.EndDate),airTimeText+=" - "+datetime.getDisplayTime(date))}catch(e){console.log("Error parsing date: "+item.StartDate)}return airTimeText}function getCardFooterText(item,apiClient,options,showTitle,forceName,overlayText,imgUrl,footerClass,progressHtml,logoUrl,isOuterFooter){var html="";logoUrl&&(html+='');var showOtherText=isOuterFooter?!overlayText:overlayText;if(isOuterFooter&&options.cardLayout&&!layoutManager.tv&&"none"!==options.cardFooterAside){html+=''}var titleAdded,cssClass=options.centerText?"cardText cardTextCentered":"cardText",lines=[],parentTitleUnderneath="MusicAlbum"===item.Type||"Audio"===item.Type||"MusicVideo"===item.Type;if(showOtherText&&(options.showParentTitle||options.showParentTitleOrTitle)&&!parentTitleUnderneath)if(isOuterFooter&&"Episode"===item.Type&&item.SeriesName)item.SeriesId?lines.push(getTextActionButton({Id:item.SeriesId,ServerId:item.ServerId,Name:item.SeriesName,Type:"Series",IsFolder:!0})):lines.push(item.SeriesName);else if(isUsingLiveTvNaming(item))lines.push(item.Name),item.EpisodeTitle||(titleAdded=!0);else{var parentTitle=item.SeriesName||item.Series||item.Album||item.AlbumArtist||item.GameSystem||"";(parentTitle||showTitle)&&lines.push(parentTitle)}var showMediaTitle=showTitle&&!titleAdded||options.showParentTitleOrTitle&&!lines.length;if(showMediaTitle||titleAdded||!showTitle&&!forceName||(showMediaTitle=!0),showMediaTitle){var name="auto"!==options.showTitle||item.IsFolder||"Photo"!==item.MediaType?itemHelper.getDisplayName(item,{includeParentInfo:options.includeParentInfoInTitle}):"";lines.push(name)}if(showOtherText){if(options.showParentTitle&&parentTitleUnderneath&&(isOuterFooter&&item.AlbumArtists&&item.AlbumArtists.length?(item.AlbumArtists[0].Type="MusicArtist",item.AlbumArtists[0].IsFolder=!0,lines.push(getTextActionButton(item.AlbumArtists[0],null,item.ServerId))):lines.push(isUsingLiveTvNaming(item)?item.Name:item.SeriesName||item.Series||item.Album||item.AlbumArtist||item.GameSystem||"")),options.showItemCounts){var itemCountHtml=getItemCountsHtml(options,item);lines.push(itemCountHtml)}if(options.textLines)for(var additionalLines=options.textLines(item),i=0,length=additionalLines.length;i'+html,html+=""),html}function getTextActionButton(item,text,serverId){if(text||(text=itemHelper.getDisplayName(item)),layoutManager.tv)return text;var html=""}function getItemCountsHtml(options,item){var childText,counts=[];if("Playlist"===item.Type){if(childText="",item.RunTimeTicks){var minutes=item.RunTimeTicks/6e8;minutes=minutes||1,childText+=globalize.translate("sharedcomponents#ValueMinutes",Math.round(minutes))}else childText+=globalize.translate("sharedcomponents#ValueMinutes",0);counts.push(childText)}else"Genre"===item.Type||"Studio"===item.Type?(item.MovieCount&&(childText=1===item.MovieCount?globalize.translate("sharedcomponents#ValueOneMovie"):globalize.translate("sharedcomponents#ValueMovieCount",item.MovieCount),counts.push(childText)),item.SeriesCount&&(childText=1===item.SeriesCount?globalize.translate("sharedcomponents#ValueOneSeries"):globalize.translate("sharedcomponents#ValueSeriesCount",item.SeriesCount),counts.push(childText)),item.EpisodeCount&&(childText=1===item.EpisodeCount?globalize.translate("sharedcomponents#ValueOneEpisode"):globalize.translate("sharedcomponents#ValueEpisodeCount",item.EpisodeCount),counts.push(childText)),item.GameCount&&(childText=1===item.GameCount?globalize.translate("sharedcomponents#ValueOneGame"):globalize.translate("sharedcomponents#ValueGameCount",item.GameCount),counts.push(childText))):"GameGenre"===item.Type?item.GameCount&&(childText=1===item.GameCount?globalize.translate("sharedcomponents#ValueOneGame"):globalize.translate("sharedcomponents#ValueGameCount",item.GameCount),counts.push(childText)):"MusicGenre"===item.Type||"MusicArtist"===options.context?(item.AlbumCount&&(childText=1===item.AlbumCount?globalize.translate("sharedcomponents#ValueOneAlbum"):globalize.translate("sharedcomponents#ValueAlbumCount",item.AlbumCount),counts.push(childText)),item.SongCount&&(childText=1===item.SongCount?globalize.translate("sharedcomponents#ValueOneSong"):globalize.translate("sharedcomponents#ValueSongCount",item.SongCount),counts.push(childText)),item.MusicVideoCount&&(childText=1===item.MusicVideoCount?globalize.translate("sharedcomponents#ValueOneMusicVideo"):globalize.translate("sharedcomponents#ValueMusicVideoCount",item.MusicVideoCount),counts.push(childText))):"Series"===item.Type&&(childText=1===item.RecursiveItemCount?globalize.translate("sharedcomponents#ValueOneEpisode"):globalize.translate("sharedcomponents#ValueEpisodeCount",item.RecursiveItemCount),counts.push(childText));return counts.join(", ")}function requireRefreshIndicator(){refreshIndicatorLoaded||(refreshIndicatorLoaded=!0,require(["emby-itemrefreshindicator"]))}function getDefaultBackgroundClass(str){return"defaultCardBackground defaultCardBackground"+getDefaultColorIndex(str)}function buildCard(index,item,apiClient,options){var action=options.action||"link";"play"===action&&item.IsFolder?action="link":"Photo"===item.MediaType&&(action="play");var shape=options.shape;if("mixed"===shape){shape=null;var primaryImageAspectRatio=item.PrimaryImageAspectRatio;primaryImageAspectRatio&&(shape=primaryImageAspectRatio>=1.33?"mixedBackdrop":primaryImageAspectRatio>.71?"mixedSquare":"mixedPortrait"),shape=shape||"mixedSquare"}var className="card";shape&&(className+=" "+shape+"Card"),options.cardCssClass&&(className+=" "+options.cardCssClass),options.cardClass&&(className+=" "+options.cardClass),layoutManager.desktop&&(className+=" card-hoverable"),enableFocusTransfrom&&layoutManager.tv||(className+=" card-nofocustransform");var imgInfo=getCardImageUrl(item,apiClient,options,shape),imgUrl=imgInfo.imgUrl,forceName=imgInfo.forceName,showTitle="auto"===options.showTitle||(options.showTitle||"PhotoAlbum"===item.Type||"Folder"===item.Type),overlayText=options.overlayText;forceName&&!options.cardLayout&&null==overlayText&&(overlayText=!0);var cardImageContainerClass="cardImageContainer";(options.coverImage||imgInfo.coverImage)&&(cardImageContainerClass+=" coveredImage",("Photo"===item.MediaType||"PhotoAlbum"===item.Type||"Folder"===item.Type||item.ProgramInfo||"Program"===item.Type||"Recording"===item.Type)&&(cardImageContainerClass+=" coveredImage-noScale")),imgUrl||(cardImageContainerClass+=" "+getDefaultBackgroundClass(item.Name));var cardBoxClass=options.cardLayout?"cardBox visualCardBox":"cardBox";layoutManager.tv&&(enableFocusTransfrom&&(cardBoxClass+=" cardBox-focustransform"),options.cardLayout&&(cardBoxClass+=" card-focuscontent",enableFocusTransfrom||(cardBoxClass+=" card-focuscontent-large")));var footerCssClass,logoUrl,progressHtml=indicators.getProgressBarHtml(item),innerCardFooter="",footerOverlayed=!1;options.showChannelLogo&&item.ChannelPrimaryImageTag?logoUrl=apiClient.getScaledImageUrl(item.ChannelId,{type:"Primary",height:40,tag:item.ChannelPrimaryImageTag}):options.showLogo&&item.ParentLogoImageTag&&(logoUrl=apiClient.getScaledImageUrl(item.ParentLogoItemId,{type:"Logo",height:40,tag:item.ParentLogoImageTag})),overlayText?(logoUrl=null,footerCssClass=progressHtml?"innerCardFooter fullInnerCardFooter":"innerCardFooter",innerCardFooter+=getCardFooterText(item,apiClient,options,showTitle,forceName,overlayText,imgUrl,footerCssClass,progressHtml,logoUrl,!1),footerOverlayed=!0):progressHtml&&(innerCardFooter+='
',innerCardFooter+=progressHtml,innerCardFooter+="
",progressHtml="");var mediaSourceCount=item.MediaSourceCount||1;mediaSourceCount>1&&(innerCardFooter+='
'+mediaSourceCount+"
");var outerCardFooter="";overlayText||footerOverlayed||(footerCssClass=options.cardLayout?"cardFooter":"cardFooter cardFooter-transparent",logoUrl&&(footerCssClass+=" cardFooter-withlogo"),options.cardLayout||(logoUrl=null),outerCardFooter=getCardFooterText(item,apiClient,options,showTitle,forceName,overlayText,imgUrl,footerCssClass,progressHtml,logoUrl,!0)),outerCardFooter&&!options.cardLayout&&(cardBoxClass+=" cardBox-bottompadded");var overlayButtons="";if(layoutManager.mobile){var overlayPlayButton=options.overlayPlayButton;null!=overlayPlayButton||options.overlayMoreButton||options.overlayInfoButton||options.cardLayout||(overlayPlayButton="Video"===item.MediaType);var btnCssClass="cardOverlayButton cardOverlayButton-br itemAction";if(options.centerPlayButton&&(overlayButtons+=''),!overlayPlayButton||item.IsPlaceHolder||"Virtual"===item.LocationType&&item.MediaType&&"Program"!==item.Type||"Person"===item.Type||(overlayButtons+=''),options.overlayMoreButton){overlayButtons+=''}}options.showChildCountIndicator&&item.ChildCount&&(className+=" groupedCard");var cardImageContainerOpen,cardImageContainerClose="",cardBoxClose="",cardScalableClose="",cardContentClass="cardContent";options.cardLayout||(cardContentClass+=" cardContent-shadow"),layoutManager.tv?(cardImageContainerOpen=imgUrl?'
':'
',cardImageContainerClose="
"):(cardImageContainerOpen=imgUrl?'");var cardScalableClass="cardScalable";layoutManager.tv&&!options.cardLayout&&(cardScalableClass+=" card-focuscontent",enableFocusTransfrom||(cardScalableClass+=" card-focuscontent-large")),cardImageContainerOpen='
'+cardImageContainerOpen,cardBoxClose="
",cardScalableClose="
";var indicatorsHtml="";if(!1!==options.missingIndicator&&(indicatorsHtml+=indicators.getMissingIndicator(item)),indicatorsHtml+=indicators.getSyncIndicator(item),indicatorsHtml+=indicators.getTimerIndicator(item),indicatorsHtml+=indicators.getTypeIndicator(item),options.showGroupCount?indicatorsHtml+=indicators.getChildCountIndicatorHtml(item,{minCount:1}):indicatorsHtml+=indicators.getPlayedIndicatorHtml(item),"CollectionFolder"===item.Type||item.CollectionType){indicatorsHtml+='
',requireRefreshIndicator()}indicatorsHtml&&(cardImageContainerOpen+='
'+indicatorsHtml+"
"),imgUrl||(cardImageContainerOpen+=getCardDefaultText(item,options));var tagName=layoutManager.tv&&!overlayButtons?"button":"div",nameWithPrefix=item.SortName||item.Name||"",prefix=nameWithPrefix.substring(0,Math.min(3,nameWithPrefix.length));prefix&&(prefix=prefix.toUpperCase());var timerAttributes="";item.TimerId&&(timerAttributes+=' data-timerid="'+item.TimerId+'"'),item.SeriesTimerId&&(timerAttributes+=' data-seriestimerid="'+item.SeriesTimerId+'"');var actionAttribute;"button"===tagName?(className+=" itemAction",actionAttribute=' data-action="'+action+'"'):actionAttribute="","MusicAlbum"!==item.Type&&"MusicArtist"!==item.Type&&"Audio"!==item.Type&&(className+=" card-withuserdata");var positionTicksData=item.UserData&&item.UserData.PlaybackPositionTicks?' data-positionticks="'+item.UserData.PlaybackPositionTicks+'"':"",collectionIdData=options.collectionId?' data-collectionid="'+options.collectionId+'"':"",playlistIdData=options.playlistId?' data-playlistid="'+options.playlistId+'"':"",mediaTypeData=item.MediaType?' data-mediatype="'+item.MediaType+'"':"",collectionTypeData=item.CollectionType?' data-collectiontype="'+item.CollectionType+'"':"",channelIdData=item.ChannelId?' data-channelid="'+item.ChannelId+'"':"",contextData=options.context?' data-context="'+options.context+'"':"",parentIdData=options.parentId?' data-parentid="'+options.parentId+'"':"",additionalCardContent="";return layoutManager.desktop&&(additionalCardContent+=getHoverMenuHtml(item)),"<"+tagName+' data-index="'+index+'"'+timerAttributes+actionAttribute+' data-isfolder="'+(item.IsFolder||!1)+'" data-serverid="'+(item.ServerId||options.serverId)+'" data-id="'+(item.Id||item.ItemId)+'" data-type="'+item.Type+'"'+mediaTypeData+collectionTypeData+channelIdData+positionTicksData+collectionIdData+playlistIdData+contextData+parentIdData+' data-prefix="'+prefix+'" class="'+className+'">'+cardImageContainerOpen+innerCardFooter+cardImageContainerClose+overlayButtons+additionalCardContent+cardScalableClose+outerCardFooter+cardBoxClose+""}function getHoverMenuHtml(item){var html="",btnCssClass="cardOverlayButton cardOverlayButton-hover itemAction";playbackManager.canPlay(item)&&(html+=''),html+='
';var userData=item.UserData||{};return itemHelper.canMarkPlayed(item)&&(require(["emby-playstatebutton"]),html+=''),html+='',html+="
"}function getCardDefaultText(item,options){var collectionType=item.CollectionType ;return"livetv"===collectionType?'':"homevideos"===collectionType||"photos"===collectionType?'':"music"===collectionType?'':"MusicAlbum"===item.Type?'':"MusicArtist"===item.Type||"Person"===item.Type?'':options.defaultCardImageIcon?''+options.defaultCardImageIcon+"":'
'+(isUsingLiveTvNaming(item)?item.Name:itemHelper.getDisplayName(item))+"
"}function buildCards(items,options){if(document.body.contains(options.itemsContainer)){if(options.parentContainer){if(!items.length)return void options.parentContainer.classList.add("hide");options.parentContainer.classList.remove("hide")}var html=buildCardsHtmlInternal(items,options);html?(options.itemsContainer.cardBuilderHtml!==html&&(options.itemsContainer.innerHTML=html,items.length<50?options.itemsContainer.cardBuilderHtml=html:options.itemsContainer.cardBuilderHtml=null),imageLoader.lazyChildren(options.itemsContainer)):(options.itemsContainer.innerHTML=html,options.itemsContainer.cardBuilderHtml=null),options.autoFocus&&focusManager.autoFocus(options.itemsContainer,!0)}}function ensureIndicators(card,indicatorsElem){if(indicatorsElem)return indicatorsElem;if(!(indicatorsElem=card.querySelector(".cardIndicators"))){var cardImageContainer=card.querySelector(".cardImageContainer");indicatorsElem=document.createElement("div"),indicatorsElem.classList.add("cardIndicators"),cardImageContainer.appendChild(indicatorsElem)}return indicatorsElem}function updateUserData(card,userData){var type=card.getAttribute("data-type"),enableCountIndicator="Series"===type||"BoxSet"===type||"Season"===type,indicatorsElem=null,playedIndicator=null,countIndicator=null,itemProgressBar=null;userData.Played?(playedIndicator=card.querySelector(".playedIndicator"),playedIndicator||(playedIndicator=document.createElement("div"),playedIndicator.classList.add("playedIndicator"),playedIndicator.classList.add("indicator"),indicatorsElem=ensureIndicators(card,indicatorsElem),indicatorsElem.appendChild(playedIndicator)),playedIndicator.innerHTML=''):(playedIndicator=card.querySelector(".playedIndicator"))&&playedIndicator.parentNode.removeChild(playedIndicator),userData.UnplayedItemCount?(countIndicator=card.querySelector(".countIndicator"),countIndicator||(countIndicator=document.createElement("div"),countIndicator.classList.add("countIndicator"),indicatorsElem=ensureIndicators(card,indicatorsElem),indicatorsElem.appendChild(countIndicator)),countIndicator.innerHTML=userData.UnplayedItemCount):enableCountIndicator&&(countIndicator=card.querySelector(".countIndicator"))&&countIndicator.parentNode.removeChild(countIndicator);var progressHtml=indicators.getProgressBarHtml({Type:type,UserData:userData,MediaType:"Video"});if(progressHtml){if(!(itemProgressBar=card.querySelector(".itemProgressBar"))){itemProgressBar=document.createElement("div"),itemProgressBar.classList.add("itemProgressBar");var innerCardFooter=card.querySelector(".innerCardFooter");if(!innerCardFooter){innerCardFooter=document.createElement("div"),innerCardFooter.classList.add("innerCardFooter");card.querySelector(".cardImageContainer").appendChild(innerCardFooter)}innerCardFooter.appendChild(itemProgressBar)}itemProgressBar.innerHTML=progressHtml}else(itemProgressBar=card.querySelector(".itemProgressBar"))&&itemProgressBar.parentNode.removeChild(itemProgressBar)}function onUserDataChanged(userData,scope){for(var cards=(scope||document.body).querySelectorAll('.card-withuserdata[data-id="'+userData.ItemId+'"]'),i=0,length=cards.length;i')}cell.setAttribute("data-timerid",newTimerId)}}function onTimerCancelled(id,itemsContainer){for(var cells=itemsContainer.querySelectorAll('.card[data-timerid="'+id+'"]'),i=0,length=cells.length;i
';elem.innerHTML=html,elem.classList.add("homeSectionsContainer");var promises=[],sections=getAllSectionsToShow(userSettings,7);for(i=0,length=sections.length;i",layoutManager.tv||(html+=''),html+="",html+='
';for(var i=0,length=items.length;i'+icon+""+item.Name+""}return html+="
",html+=""}function loadlibraryButtons(elem,apiClient,user,userSettings,userViews){return Promise.all([getAppInfo(apiClient),getDownloadsSectionHtml(apiClient,user,userSettings)]).then(function(responses){var infoHtml=responses[0],downloadsHtml=responses[1];elem.classList.remove("verticalSection");var html=getLibraryButtonsHtml(userViews);elem.innerHTML=html+downloadsHtml+infoHtml,bindHomeScreenSettingsIcon(elem,apiClient,user.Id,userSettings),infoHtml&&bindAppInfoEvents(elem),imageLoader.lazyChildren(elem)})}function bindAppInfoEvents(elem){elem.querySelector(".appInfoSection").addEventListener("click",function(e){dom.parentWithClass(e.target,"card")&®istrationServices.showPremiereInfo()})}function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min}function getAppInfo(apiClient){var cacheKey="lastappinfopresent5",lastDatePresented=parseInt(appSettings.get(cacheKey)||"0");return lastDatePresented?(new Date).getTime()-lastDatePresented<1728e5?Promise.resolve(""):registrationServices.validateFeature("dvr",{showDialog:!1,viewOnly:!0}).then(function(){return appSettings.set(cacheKey,(new Date).getTime()),""},function(){appSettings.set(cacheKey,(new Date).getTime());var infos=[getPremiereInfo];return appHost.supports("otherapppromotions")&&infos.push(getTheaterInfo),infos[getRandomInt(0,infos.length-1)]()}):(appSettings.set(cacheKey,(new Date).getTime()),Promise.resolve(""))}function getCard(img,shape){shape=shape||"backdropCard";var html='
';return html+='
',html+='
',html+="
",html+="
"}function getTheaterInfo(){var html="";html+='
',html+='
',html+='

Discover Emby Theater

',html+='',html+="
";return html+='
',html+='

A beautiful app for your TV and large screen tablet. Emby Theater runs on Windows, Xbox One, Raspberry Pi, Samsung Smart TVs, Sony PS4, Web Browsers, and more.

',html+='
',html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater1.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater2.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater3.png"),html+="
",html+="
",html+="
"}function getPremiereInfo(){var html="";return html+='
',html+='
',html+='

Discover Emby Premiere

',html+='',html+="
",html+='
',html+='

Enjoy Emby DVR, get free access to Emby apps, and more.

',html+='
',html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater1.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater2.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater3.png"),html+="
",html+="
",html+="
"}function getFetchLatestItemsFn(serverId,parentId,collectionType){return function(){var apiClient=connectionManager.getApiClient(serverId),limit=16;enableScrollX()?"music"===collectionType&&(limit=30):limit="tvshows"===collectionType?5:"music"===collectionType?9:8;var options={Limit:limit,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Thumb",ParentId:parentId};return apiClient.getLatestItems(options)}}function getLatestItemsHtmlFn(itemType,viewType){return function(items){var shape="Channel"===itemType||"movies"===viewType?getPortraitShape():"music"===viewType?getSquareShape():getThumbShape();return cardBuilder.getCardsHtml({items:items,shape:shape,preferThumb:"movies"!==viewType&&"Channel"!==itemType&&"music"!==viewType?"auto":null,showUnplayedIndicator:!1,showChildCountIndicator:!0,context:"home",overlayText:!1,centerText:!0,overlayPlayButton:"photos"!==viewType,allowBottomPadding:!enableScrollX()&&!0,cardLayout:!1,showTitle:"photos"!==viewType,showYear:"movies"===viewType||"tvshows"===viewType||!viewType,showParentTitle:"music"===viewType||"tvshows"===viewType||!viewType||!1,lines:2})}}function renderLatestSection(elem,apiClient,user,parent){var html="";html+='
',layoutManager.tv?html+='

'+globalize.translate("sharedcomponents#LatestFromLibrary",parent.Name)+"

":(html+='',html+='

',html+=globalize.translate("sharedcomponents#LatestFromLibrary",parent.Name),html+="

",html+='',html+="
"),html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getFetchLatestItemsFn(apiClient.serverId(),parent.Id,parent.CollectionType),itemsContainer.getItemsHtml=getLatestItemsHtmlFn(parent.Type,parent.CollectionType),itemsContainer.parentContainer=elem}function loadRecentlyAdded(elem,apiClient,user,userViews){elem.classList.remove("verticalSection");for(var excludeViewTypes=["playlists","livetv","boxsets","channels"],i=0,length=userViews.length;i":(html+='',html+='

',html+=globalize.translate("sharedcomponents#HeaderMyDownloads"),html+="

",html+='',html+="
",html+=''),html+="
",html+='
',html+=cardBuilder.getCardsHtml({items:items,preferThumb:"auto",shape:"autooverflow",overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,showDetailsMenu:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!1,cardLayout:!1,showYear:!0,lines:2}),html+="
",html+="
"}):Promise.resolve("")}function loadLibraryTiles(elem,apiClient,user,userSettings,shape,userViews,allSections){elem.classList.remove("verticalSection");var html="",scrollX=!layoutManager.desktop;return userViews.length&&(html+='
',html+='
',html+='

'+globalize.translate("sharedcomponents#HeaderMyMedia")+"

",layoutManager.tv||(html+=''),html+="
",html+=scrollX?'
':'
',html+=cardBuilder.getCardsHtml({items:userViews,shape:scrollX?"overflowSmallBackdrop":shape,showTitle:!0,centerText:!0,overlayText:!1,lazy:!0,transition:!1,allowBottomPadding:!scrollX}),scrollX&&(html+="
"),html+="
",html+="
"),Promise.all([getAppInfo(apiClient),getDownloadsSectionHtml(apiClient,user,userSettings)]).then(function(responses){var infoHtml=responses[0],downloadsHtml=responses[1];elem.innerHTML=html+downloadsHtml+infoHtml,bindHomeScreenSettingsIcon(elem,apiClient,user.Id,userSettings),infoHtml&&bindAppInfoEvents(elem),imageLoader.lazyChildren(elem)})}function getContinueWatchingFetchFn(serverId){return function(){var limit,apiClient=connectionManager.getApiClient(serverId),screenWidth=dom.getWindowSize().innerWidth;enableScrollX()?limit=12:(limit=screenWidth>=1920?8:screenWidth>=1600?8:screenWidth>=1200?9:6,limit=Math.min(limit,5));var options={Limit:limit,Recursive:!0,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Thumb",EnableTotalRecordCount:!1,MediaTypes:"Video"};return apiClient.getResumableItems(apiClient.getCurrentUserId(),options)}}function getContinueWatchingItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:!0,shape:getThumbShape(),overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,showDetailsMenu:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!1,cardLayout:!1,showYear:!0,lines:2})}function loadResumeVideo(elem,apiClient,userId){var html="";html+='

'+globalize.translate("sharedcomponents#HeaderContinueWatching")+"

",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getContinueWatchingFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getContinueWatchingItemsHtml,itemsContainer.parentContainer=elem}function getContinueListeningFetchFn(serverId){return function(){var limit,apiClient=connectionManager.getApiClient(serverId),screenWidth=dom.getWindowSize().innerWidth;enableScrollX()?limit=12:(limit=screenWidth>=1920?8:screenWidth>=1600?8:screenWidth>=1200?9:6,limit=Math.min(limit,5));var options={Limit:limit,Recursive:!0,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Thumb",EnableTotalRecordCount:!1,MediaTypes:"Audio"};return apiClient.getResumableItems(apiClient.getCurrentUserId(),options)}}function getContinueListeningItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:!0,shape:getThumbShape(),overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,showDetailsMenu:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!1,cardLayout:!1,showYear:!0,lines:2})}function loadResumeAudio(elem,apiClient,userId){var html="";html+='

'+globalize.translate("sharedcomponents#HeaderContinueWatching")+"

",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getContinueListeningFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getContinueListeningItemsHtml,itemsContainer.parentContainer=elem}function bindUnlockClick(elem){var btnUnlock=elem.querySelector(".btnUnlock");btnUnlock&&btnUnlock.addEventListener("click",function(e){registrationServices.validateFeature("livetv",{viewOnly:!0}).then(function(){dom.parentWithClass(elem,"homeSectionsContainer").dispatchEvent(new CustomEvent("settingschange",{cancelable:!1}))})})}function getOnNowFetchFn(serverId){return function(){var apiClient=connectionManager.getApiClient(serverId);return apiClient.getLiveTvRecommendedPrograms({userId:apiClient.getCurrentUserId(),IsAiring:!0,limit:24,ImageTypeLimit:1,EnableImageTypes:"Primary,Thumb,Backdrop",EnableTotalRecordCount:!1,Fields:"ChannelInfo,PrimaryImageAspectRatio"})}}function getOnNowItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:"auto",inheritThumb:!1,shape:enableScrollX()?"autooverflow":"auto",showParentTitleOrTitle:!0,showTitle:!0,centerText:!0,coverImage:!0,overlayText:!1,allowBottomPadding:!enableScrollX(),showAirTime:!0,showChannelName:!1,showAirDateTime:!1,showAirEndTime:!0,defaultShape:getThumbShape(),lines:3,overlayPlayButton:!0})}function loadOnNow(elem,apiClient,user){if(!user.Policy.EnableLiveTvAccess)return Promise.resolve();var promises=[];promises.push(registrationServices.validateFeature("livetv",{viewOnly:!0,showDialog:!1}).then(function(){return!0},function(){return!1}));user.Id;return promises.push(apiClient.getLiveTvRecommendedPrograms({userId:apiClient.getCurrentUserId(),IsAiring:!0,limit:1,ImageTypeLimit:1,EnableImageTypes:"Primary,Thumb,Backdrop",EnableTotalRecordCount:!1,Fields:"ChannelInfo,PrimaryImageAspectRatio"})),Promise.all(promises).then(function(responses){var registered=responses[0],result=responses[1],html="";if(result.Items.length&®istered){elem.classList.remove("padded-left"),elem.classList.remove("padded-right"),elem.classList.remove("padded-bottom"),elem.classList.remove("verticalSection"),html+='
',html+='
',html+='

'+globalize.translate("sharedcomponents#LiveTV")+"

",html+="
",enableScrollX()?(html+='",html+="
",html+='
',html+='
',layoutManager.tv?html+='

'+globalize.translate("sharedcomponents#HeaderOnNow")+"

":(html+='',html+='

',html+=globalize.translate("sharedcomponents#HeaderOnNow"),html+="

",html+='',html+="
"),html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",html+="
",elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.parentContainer=elem,itemsContainer.fetchData=getOnNowFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getOnNowItemsHtml}else result.Items.length&&!registered&&(elem.classList.add("padded-left"),elem.classList.add("padded-right"),elem.classList.add("padded-bottom"),html+='

'+globalize.translate("sharedcomponents#LiveTvRequiresUnlock")+"

",html+='",elem.innerHTML=html);bindUnlockClick(elem)})}function getNextUpFetchFn(serverId){return function(){var apiClient=connectionManager.getApiClient(serverId);return apiClient.getNextUpEpisodes({Limit:enableScrollX()?24:15,Fields:"PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo",UserId:apiClient.getCurrentUserId(),ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Banner,Thumb",EnableTotalRecordCount:!1})}}function getNextUpItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:!0,shape:getThumbShape(),overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!enableScrollX(),cardLayout:!1})}function loadNextUp(elem,apiClient,userId){var html="";html+='
',layoutManager.tv?html+='

'+globalize.translate("sharedcomponents#HeaderNextUp")+"

":(html+='',html+='

',html+=globalize.translate("sharedcomponents#HeaderNextUp"),html+="

",html+='',html+="
"),html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getNextUpFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getNextUpItemsHtml,itemsContainer.parentContainer=elem}function getLatestRecordingsFetchFn(serverId,activeRecordingsOnly){return function(){var apiClient=connectionManager.getApiClient(serverId);return apiClient.getLiveTvRecordings({userId:apiClient.getCurrentUserId(),Limit:enableScrollX()?12:5,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",EnableTotalRecordCount:!1,IsLibraryItem:!!activeRecordingsOnly&&null,IsInProgress:!!activeRecordingsOnly||null})}}function getLatestRecordingItemsHtml(activeRecordingsOnly){return function(items){return cardBuilder.getCardsHtml({items:items,shape:enableScrollX()?"autooverflow":"auto",showTitle:!0,showParentTitle:!0,coverImage:!0,lazy:!0,showDetailsMenu:!0,centerText:!0,overlayText:!1,showYear:!0,lines:2,overlayPlayButton:!activeRecordingsOnly,allowBottomPadding:!enableScrollX(),preferThumb:!0,cardLayout:!1,overlayMoreButton:activeRecordingsOnly,action:activeRecordingsOnly?"none":null,centerPlayButton:activeRecordingsOnly})}}function loadLatestLiveTvRecordings(elem,activeRecordingsOnly,apiClient,userId){var title=activeRecordingsOnly?globalize.translate("sharedcomponents#HeaderActiveRecordings"):globalize.translate("sharedcomponents#HeaderLatestRecordings"),html="";html+='
',html+='

'+title+"

",layoutManager.tv,html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getLatestRecordingsFetchFn(apiClient.serverId(),activeRecordingsOnly),itemsContainer.getItemsHtml=getLatestRecordingItemsHtml(activeRecordingsOnly),itemsContainer.parentContainer=elem}return{loadLibraryTiles:loadLibraryTiles,getDefaultSection:getDefaultSection,loadSections:loadSections,destroySections:destroySections,pause:pause,resume:resume}}); \ No newline at end of file +define(["connectionManager","cardBuilder","registrationServices","appSettings","dom","apphost","layoutManager","imageLoader","globalize","itemShortcuts","itemHelper","appRouter","emby-button","paper-icon-button-light","emby-itemscontainer","emby-scroller","emby-linkbutton","css!./homesections"],function(connectionManager,cardBuilder,registrationServices,appSettings,dom,appHost,layoutManager,imageLoader,globalize,itemShortcuts,itemHelper,appRouter){"use strict";function getDefaultSection(index){switch(index){case 0:return"smalllibrarytiles";case 1:return"resume";case 2:return"resumeaudio";case 3:return"livetv";case 4:return"nextup";case 5:return"latestmedia";case 6:return"none";default:return""}}function getAllSectionsToShow(userSettings,sectionCount){for(var sections=[],i=0,length=sectionCount;i
';elem.innerHTML=html,elem.classList.add("homeSectionsContainer");var promises=[],sections=getAllSectionsToShow(userSettings,7);for(i=0,length=sections.length;i",layoutManager.tv||(html+=''),html+="
",html+='
';for(var i=0,length=items.length;i'+icon+""+item.Name+""}return html+="
",html+="
"}function loadlibraryButtons(elem,apiClient,user,userSettings,userViews){return Promise.all([getAppInfo(apiClient),getDownloadsSectionHtml(apiClient,user,userSettings)]).then(function(responses){var infoHtml=responses[0],downloadsHtml=responses[1];elem.classList.remove("verticalSection");var html=getLibraryButtonsHtml(userViews);elem.innerHTML=html+downloadsHtml+infoHtml,bindHomeScreenSettingsIcon(elem,apiClient,user.Id,userSettings),infoHtml&&bindAppInfoEvents(elem),imageLoader.lazyChildren(elem)})}function bindAppInfoEvents(elem){elem.querySelector(".appInfoSection").addEventListener("click",function(e){dom.parentWithClass(e.target,"card")&®istrationServices.showPremiereInfo()})}function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min}function getAppInfo(apiClient){var cacheKey="lastappinfopresent5",lastDatePresented=parseInt(appSettings.get(cacheKey)||"0");return lastDatePresented?(new Date).getTime()-lastDatePresented<1728e5?Promise.resolve(""):registrationServices.validateFeature("dvr",{showDialog:!1,viewOnly:!0}).then(function(){return appSettings.set(cacheKey,(new Date).getTime()),""},function(){appSettings.set(cacheKey,(new Date).getTime());var infos=[getPremiereInfo];return appHost.supports("otherapppromotions")&&infos.push(getTheaterInfo),infos[getRandomInt(0,infos.length-1)]()}):(appSettings.set(cacheKey,(new Date).getTime()),Promise.resolve(""))}function getCard(img,shape){shape=shape||"backdropCard";var html='
';return html+='
',html+='
',html+="
",html+="
"}function getTheaterInfo(){var html="";html+='
',html+='
',html+='

Discover Emby Theater

',html+='',html+="
";return html+='
',html+='

A beautiful app for your TV and large screen tablet. Emby Theater runs on Windows, Xbox One, Raspberry Pi, Samsung Smart TVs, Sony PS4, Web Browsers, and more.

',html+='
',html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater1.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater2.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater3.png"),html+="
",html+="
",html+="
"}function getPremiereInfo(){var html="";return html+='
',html+='
',html+='

Discover Emby Premiere

',html+='',html+="
",html+='
',html+='

Enjoy Emby DVR, get free access to Emby apps, and more.

',html+='
',html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater1.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater2.png"),html+=getCard("https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/apps/theater3.png"),html+="
",html+="
",html+="
"}function getFetchLatestItemsFn(serverId,parentId,collectionType){return function(){var apiClient=connectionManager.getApiClient(serverId),limit=16;enableScrollX()?"music"===collectionType&&(limit=30):limit="tvshows"===collectionType?5:"music"===collectionType?9:8;var options={Limit:limit,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Thumb",ParentId:parentId};return apiClient.getLatestItems(options)}}function getLatestItemsHtmlFn(itemType,viewType){return function(items){var shape="Channel"===itemType||"movies"===viewType?getPortraitShape():"music"===viewType?getSquareShape():getThumbShape();return cardBuilder.getCardsHtml({items:items,shape:shape,preferThumb:"movies"!==viewType&&"Channel"!==itemType&&"music"!==viewType?"auto":null,showUnplayedIndicator:!1,showChildCountIndicator:!0,context:"home",overlayText:!1,centerText:!0,overlayPlayButton:"photos"!==viewType,allowBottomPadding:!enableScrollX()&&!0,cardLayout:!1,showTitle:"photos"!==viewType,showYear:"movies"===viewType||"tvshows"===viewType||!viewType,showParentTitle:"music"===viewType||"tvshows"===viewType||!viewType||!1,lines:2})}}function renderLatestSection(elem,apiClient,user,parent){var html="";html+='
',layoutManager.tv?html+='

'+globalize.translate("sharedcomponents#LatestFromLibrary",parent.Name)+"

":(html+='',html+='

',html+=globalize.translate("sharedcomponents#LatestFromLibrary",parent.Name),html+="

",html+='',html+="
"),html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getFetchLatestItemsFn(apiClient.serverId(),parent.Id,parent.CollectionType),itemsContainer.getItemsHtml=getLatestItemsHtmlFn(parent.Type,parent.CollectionType),itemsContainer.parentContainer=elem}function loadRecentlyAdded(elem,apiClient,user,userViews){elem.classList.remove("verticalSection");for(var excludeViewTypes=["playlists","livetv","boxsets","channels"],i=0,length=userViews.length;i":(html+='',html+='

',html+=globalize.translate("sharedcomponents#HeaderMyDownloads"),html+="

",html+='',html+="
",html+=''),html+="
",html+='
',html+=cardBuilder.getCardsHtml({items:items,preferThumb:"auto",shape:"autooverflow",overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,showDetailsMenu:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!1,cardLayout:!1,showYear:!0,lines:2}),html+="
",html+="
"}):Promise.resolve("")}function loadLibraryTiles(elem,apiClient,user,userSettings,shape,userViews,allSections){elem.classList.remove("verticalSection");var html="",scrollX=!layoutManager.desktop;return userViews.length&&(html+='
',html+='
',html+='

'+globalize.translate("sharedcomponents#HeaderMyMedia")+"

",layoutManager.tv||(html+=''),html+="
",html+=scrollX?'
':'
',html+=cardBuilder.getCardsHtml({items:userViews,shape:scrollX?"overflowSmallBackdrop":shape,showTitle:!0,centerText:!0,overlayText:!1,lazy:!0,transition:!1,allowBottomPadding:!scrollX}),scrollX&&(html+="
"),html+="
",html+="
"),Promise.all([getAppInfo(apiClient),getDownloadsSectionHtml(apiClient,user,userSettings)]).then(function(responses){var infoHtml=responses[0],downloadsHtml=responses[1];elem.innerHTML=html+downloadsHtml+infoHtml,bindHomeScreenSettingsIcon(elem,apiClient,user.Id,userSettings),infoHtml&&bindAppInfoEvents(elem),imageLoader.lazyChildren(elem)})}function getContinueWatchingFetchFn(serverId){return function(){var limit,apiClient=connectionManager.getApiClient(serverId),screenWidth=dom.getWindowSize().innerWidth;enableScrollX()?limit=12:(limit=screenWidth>=1920?8:screenWidth>=1600?8:screenWidth>=1200?9:6,limit=Math.min(limit,5));var options={Limit:limit,Recursive:!0,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Thumb",EnableTotalRecordCount:!1,MediaTypes:"Video"};return apiClient.getResumableItems(apiClient.getCurrentUserId(),options)}}function getContinueWatchingItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:!0,shape:getThumbShape(),overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,showDetailsMenu:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!1,cardLayout:!1,showYear:!0,lines:2})}function loadResumeVideo(elem,apiClient,userId){var html="";html+='

'+globalize.translate("sharedcomponents#HeaderContinueWatching")+"

",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getContinueWatchingFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getContinueWatchingItemsHtml,itemsContainer.parentContainer=elem}function getContinueListeningFetchFn(serverId){return function(){var limit,apiClient=connectionManager.getApiClient(serverId),screenWidth=dom.getWindowSize().innerWidth;enableScrollX()?limit=12:(limit=screenWidth>=1920?8:screenWidth>=1600?8:screenWidth>=1200?9:6,limit=Math.min(limit,5));var options={Limit:limit,Recursive:!0,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Thumb",EnableTotalRecordCount:!1,MediaTypes:"Audio"};return apiClient.getResumableItems(apiClient.getCurrentUserId(),options)}}function getContinueListeningItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:!0,shape:getThumbShape(),overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,showDetailsMenu:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!1,cardLayout:!1,showYear:!0,lines:2})}function loadResumeAudio(elem,apiClient,userId){var html="";html+='

'+globalize.translate("sharedcomponents#HeaderContinueWatching")+"

",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getContinueListeningFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getContinueListeningItemsHtml,itemsContainer.parentContainer=elem}function bindUnlockClick(elem){var btnUnlock=elem.querySelector(".btnUnlock");btnUnlock&&btnUnlock.addEventListener("click",function(e){registrationServices.validateFeature("livetv",{viewOnly:!0}).then(function(){dom.parentWithClass(elem,"homeSectionsContainer").dispatchEvent(new CustomEvent("settingschange",{cancelable:!1}))})})}function getOnNowFetchFn(serverId){return function(){var apiClient=connectionManager.getApiClient(serverId);return apiClient.getLiveTvRecommendedPrograms({userId:apiClient.getCurrentUserId(),IsAiring:!0,limit:24,ImageTypeLimit:1,EnableImageTypes:"Primary,Thumb,Backdrop",EnableTotalRecordCount:!1,Fields:"ChannelInfo,PrimaryImageAspectRatio"})}}function getOnNowItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:"auto",inheritThumb:!1,shape:enableScrollX()?"autooverflow":"auto",showParentTitleOrTitle:!0,showTitle:!0,centerText:!0,coverImage:!0,overlayText:!1,allowBottomPadding:!enableScrollX(),showAirTime:!0,showChannelName:!1,showAirDateTime:!1,showAirEndTime:!0,defaultShape:getThumbShape(),lines:3,overlayPlayButton:!0})}function loadOnNow(elem,apiClient,user){if(!user.Policy.EnableLiveTvAccess)return Promise.resolve();var promises=[];promises.push(registrationServices.validateFeature("livetv",{viewOnly:!0,showDialog:!1}).then(function(){return!0},function(){return!1}));user.Id;return promises.push(apiClient.getLiveTvRecommendedPrograms({userId:apiClient.getCurrentUserId(),IsAiring:!0,limit:1,ImageTypeLimit:1,EnableImageTypes:"Primary,Thumb,Backdrop",EnableTotalRecordCount:!1,Fields:"ChannelInfo,PrimaryImageAspectRatio"})),Promise.all(promises).then(function(responses){var registered=responses[0],result=responses[1],html="";if(result.Items.length&®istered){elem.classList.remove("padded-left"),elem.classList.remove("padded-right"),elem.classList.remove("padded-bottom"),elem.classList.remove("verticalSection"),html+='
',html+='
',html+='

'+globalize.translate("sharedcomponents#LiveTV")+"

",html+="
",enableScrollX()?(html+='",html+="
",html+='
',html+='
',layoutManager.tv?html+='

'+globalize.translate("sharedcomponents#HeaderOnNow")+"

":(html+='',html+='

',html+=globalize.translate("sharedcomponents#HeaderOnNow"),html+="

",html+='',html+="
"),html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",html+="
",elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.parentContainer=elem,itemsContainer.fetchData=getOnNowFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getOnNowItemsHtml}else result.Items.length&&!registered&&(elem.classList.add("padded-left"),elem.classList.add("padded-right"),elem.classList.add("padded-bottom"),html+='

'+globalize.translate("sharedcomponents#LiveTvRequiresUnlock")+"

",html+='",elem.innerHTML=html);bindUnlockClick(elem)})}function getNextUpFetchFn(serverId){return function(){var apiClient=connectionManager.getApiClient(serverId);return apiClient.getNextUpEpisodes({Limit:enableScrollX()?24:15,Fields:"PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo",UserId:apiClient.getCurrentUserId(),ImageTypeLimit:1,EnableImageTypes:"Primary,Backdrop,Banner,Thumb",EnableTotalRecordCount:!1})}}function getNextUpItemsHtml(items){return cardBuilder.getCardsHtml({items:items,preferThumb:!0,shape:getThumbShape(),overlayText:!1,showTitle:!0,showParentTitle:!0,lazy:!0,overlayPlayButton:!0,context:"home",centerText:!0,allowBottomPadding:!enableScrollX(),cardLayout:!1})}function loadNextUp(elem,apiClient,userId){var html="";html+='
',layoutManager.tv?html+='

'+globalize.translate("sharedcomponents#HeaderNextUp")+"

":(html+='',html+='

',html+=globalize.translate("sharedcomponents#HeaderNextUp"),html+="

",html+='',html+="
"),html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getNextUpFetchFn(apiClient.serverId()),itemsContainer.getItemsHtml=getNextUpItemsHtml,itemsContainer.parentContainer=elem}function getLatestRecordingsFetchFn(serverId,activeRecordingsOnly){return function(){var apiClient=connectionManager.getApiClient(serverId);return apiClient.getLiveTvRecordings({userId:apiClient.getCurrentUserId(),Limit:enableScrollX()?12:5,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",EnableTotalRecordCount:!1,IsLibraryItem:!!activeRecordingsOnly&&null,IsInProgress:!!activeRecordingsOnly||null})}}function getLatestRecordingItemsHtml(activeRecordingsOnly){return function(items){return cardBuilder.getCardsHtml({items:items,shape:enableScrollX()?"autooverflow":"auto",showTitle:!0,showParentTitle:!0,coverImage:!0,lazy:!0,showDetailsMenu:!0,centerText:!0,overlayText:!1,showYear:!0,lines:2,overlayPlayButton:!activeRecordingsOnly,allowBottomPadding:!enableScrollX(),preferThumb:!0,cardLayout:!1,overlayMoreButton:activeRecordingsOnly,action:activeRecordingsOnly?"none":null,centerPlayButton:activeRecordingsOnly})}}function loadLatestLiveTvRecordings(elem,activeRecordingsOnly,apiClient,userId){var title=activeRecordingsOnly?globalize.translate("sharedcomponents#HeaderActiveRecordings"):globalize.translate("sharedcomponents#HeaderLatestRecordings"),html="";html+='
',html+='

'+title+"

",layoutManager.tv,html+="
",enableScrollX()?html+='
':html+='
',enableScrollX()&&(html+="
"),html+="
",elem.classList.add("hide"),elem.innerHTML=html;var itemsContainer=elem.querySelector(".itemsContainer");itemsContainer.fetchData=getLatestRecordingsFetchFn(apiClient.serverId(),activeRecordingsOnly),itemsContainer.getItemsHtml=getLatestRecordingItemsHtml(activeRecordingsOnly),itemsContainer.parentContainer=elem}return{loadLibraryTiles:loadLibraryTiles,getDefaultSection:getDefaultSection,loadSections:loadSections,destroySections:destroySections,pause:pause,resume:resume}}); \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/htmlvideoplayer/plugin.js b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/htmlvideoplayer/plugin.js index 6cb92c1640..60e285a166 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/htmlvideoplayer/plugin.js +++ b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/htmlvideoplayer/plugin.js @@ -1 +1 @@ -define(["browser","require","events","apphost","loading","dom","playbackManager","appRouter","appSettings","connectionManager","htmlMediaHelper","itemHelper"],function(browser,require,events,appHost,loading,dom,playbackManager,appRouter,appSettings,connectionManager,htmlMediaHelper,itemHelper){"use strict";function tryRemoveElement(elem){var parentNode=elem.parentNode;if(parentNode)try{parentNode.removeChild(elem)}catch(err){console.log("Error removing dialog element: "+err)}}function enableNativeTrackSupport(currentSrc,track){if(track&&"Embed"===track.DeliveryMethod)return!0;if(browser.firefox&&-1!==(currentSrc||"").toLowerCase().indexOf(".m3u8"))return!1;if(browser.chromecast&&-1!==(currentSrc||"").toLowerCase().indexOf(".m3u8"))return!1;if(browser.ps4)return!1;if(browser.web0s)return!1;if(browser.edge)return!1;if(browser.iOS&&(browser.iosVersion||10)<10)return!1;if(track){var format=(track.Codec||"").toLowerCase();if("ssa"===format||"ass"===format)return!1}return!0}function requireHlsPlayer(callback){require(["hlsjs"],function(hls){window.Hls=hls,callback()})}function getMediaStreamAudioTracks(mediaSource){return mediaSource.MediaStreams.filter(function(s){return"Audio"===s.Type})}function getMediaStreamTextTracks(mediaSource){return mediaSource.MediaStreams.filter(function(s){return"Subtitle"===s.Type})}function zoomIn(elem){return new Promise(function(resolve,reject){elem.style.animation="htmlvideoplayer-zoomin 240ms ease-in normal",dom.addEventListener(elem,dom.whichAnimationEvent(),resolve,{once:!0})})}function normalizeTrackEventText(text){return text.replace(/\\N/gi,"\n")}function setTracks(elem,tracks,item,mediaSource){elem.innerHTML=getTracksHtml(tracks,item,mediaSource)}function getTextTrackUrl(track,item,format){if(itemHelper.isLocalItem(item)&&track.Path)return track.Path;var url=playbackManager.getSubtitleUrl(track,item.ServerId);return format&&(url=url.replace(".vtt",format)),url}function getTracksHtml(tracks,item,mediaSource){return tracks.map(function(t){if("External"!==t.DeliveryMethod)return"";var defaultAttribute=mediaSource.DefaultSubtitleStreamIndex===t.Index?" default":"",language=t.Language||"und",label=t.Language||"und";return'"}).join("")}function getDefaultProfile(){return new Promise(function(resolve,reject){require(["browserdeviceprofile"],function(profileBuilder){resolve(profileBuilder({}))})})}function HtmlVideoPlayer(){function updateVideoUrl(streamInfo){var isHls=-1!==streamInfo.url.toLowerCase().indexOf(".m3u8"),mediaSource=streamInfo.mediaSource,item=streamInfo.item;if(mediaSource&&item&&!mediaSource.RunTimeTicks&&isHls&&"Transcode"===streamInfo.playMethod&&(browser.iOS||browser.osx)){var hlsPlaylistUrl=streamInfo.url.replace("master.m3u8","live.m3u8");return loading.show(),console.log("prefetching hls playlist: "+hlsPlaylistUrl),connectionManager.getApiClient(item.ServerId).ajax({type:"GET",url:hlsPlaylistUrl}).then(function(){return console.log("completed prefetching hls playlist: "+hlsPlaylistUrl),loading.hide(),streamInfo.url=hlsPlaylistUrl,Promise.resolve()},function(){return console.log("error prefetching hls playlist: "+hlsPlaylistUrl),loading.hide(),Promise.resolve()})}return Promise.resolve()}function setSrcWithFlvJs(instance,elem,options,url){return new Promise(function(resolve,reject){require(["flvjs"],function(flvjs){var flvPlayer=flvjs.createPlayer({type:"flv",url:url},{seekType:"range",lazyLoad:!1});flvPlayer.attachMediaElement(elem),flvPlayer.load(),flvPlayer.play().then(resolve,reject),instance._flvPlayer=flvPlayer,self._currentSrc=url})})}function setSrcWithHlsJs(instance,elem,options,url){return new Promise(function(resolve,reject){requireHlsPlayer(function(){var hls=new Hls({manifestLoadingTimeOut:2e4});hls.loadSource(url),hls.attachMedia(elem),htmlMediaHelper.bindEventsToHlsPlayer(self,hls,elem,onError,resolve,reject),self._hlsPlayer=hls,self._currentSrc=url})})}function setCurrentSrcChromecast(instance,elem,options,url){elem.autoplay=!0;var lrd=new cast.receiver.MediaManager.LoadRequestData;lrd.currentTime=(options.playerStartPositionTicks||0)/1e7,lrd.autoplay=!0,lrd.media=new cast.receiver.media.MediaInformation,lrd.media.contentId=url,lrd.media.contentType=options.mimeType,lrd.media.streamType=cast.receiver.media.StreamType.OTHER,lrd.media.customData=options,console.log("loading media url into mediaManager");try{return mediaManager.load(lrd),self._currentSrc=url,Promise.resolve()}catch(err){return console.log("mediaManager error: "+err),Promise.reject()}}function onMediaManagerLoadMedia(event){self._castPlayer&&self._castPlayer.unload(),self._castPlayer=null;var protocol,data=event.data,media=event.data.media||{},url=media.contentId,contentType=media.contentType.toLowerCase(),mediaElement=(media.customData,self._mediaElement),host=new cast.player.api.Host({url:url,mediaElement:mediaElement});protocol=cast.player.api.CreateHlsStreamingProtocol(host),console.log("loading playback url: "+url),console.log("contentType: "+contentType),host.onError=function(errorCode){console.log("Fatal Error - "+errorCode)},mediaElement.autoplay=!1,self._castPlayer=new cast.player.api.Player(host),self._castPlayer.load(protocol,data.currentTime||0),self._castPlayer.playWhenHaveEnoughData()}function initMediaManager(){mediaManager.defaultOnLoad=mediaManager.onLoad.bind(mediaManager),mediaManager.onLoad=onMediaManagerLoadMedia.bind(self),mediaManager.defaultOnStop=mediaManager.onStop.bind(mediaManager),mediaManager.onStop=function(event){playbackManager.stop(),mediaManager.defaultOnStop(event)}}function setCurrentSrc(elem,options){elem.removeEventListener("error",onError);var val=options.url;console.log("playing url: "+val);var seconds=(options.playerStartPositionTicks||0)/1e7;seconds&&(val+="#t="+seconds),htmlMediaHelper.destroyHlsPlayer(self),htmlMediaHelper.destroyFlvPlayer(self),htmlMediaHelper.destroyCastPlayer(self);var tracks=getMediaStreamTextTracks(options.mediaSource);subtitleTrackIndexToSetOnPlaying=null==options.mediaSource.DefaultSubtitleStreamIndex?-1:options.mediaSource.DefaultSubtitleStreamIndex,audioTrackIndexToSetOnPlaying="Transcode"===options.playMethod?null:options.mediaSource.DefaultAudioStreamIndex,self._currentPlayOptions=options;var crossOrigin=htmlMediaHelper.getCrossOriginValue(options.mediaSource);return crossOrigin&&(elem.crossOrigin=crossOrigin),browser.chromecast&&-1!==val.indexOf(".m3u8")&&options.mediaSource.RunTimeTicks?(setTracks(elem,tracks,options.item,options.mediaSource),setCurrentSrcChromecast(self,elem,options,val)):htmlMediaHelper.enableHlsJsPlayer(options.mediaSource.RunTimeTicks,"Video")&&-1!==val.indexOf(".m3u8")?(setTracks(elem,tracks,options.item,options.mediaSource),setSrcWithHlsJs(self,elem,options,val)):"Transcode"!==options.playMethod&&"flv"===options.mediaSource.Container?(setTracks(elem,tracks,options.item,options.mediaSource),setSrcWithFlvJs(self,elem,options,val)):(elem.autoplay=!0,htmlMediaHelper.applySrc(elem,val,options).then(function(){return setTracks(elem,tracks,options.item,options.mediaSource),self._currentSrc=val,htmlMediaHelper.playWithPromise(elem,onError)}))}function onEnded(){destroyCustomTrack(this),htmlMediaHelper.onEndedInternal(self,this,onError)}function onTimeUpdate(e){var time=this.currentTime;time&&!self._timeUpdated&&(self._timeUpdated=!0,ensureValidVideo(this)),self._currentTime=time;var currentPlayOptions=self._currentPlayOptions;if(currentPlayOptions){var timeMs=1e3*time;timeMs+=(currentPlayOptions.transcodingOffsetTicks||0)/1e4,updateSubtitleText(timeMs)}events.trigger(self,"timeupdate")}function onVolumeChange(){htmlMediaHelper.saveVolume(this.volume),events.trigger(self,"volumechange")}function onNavigatedToOsd(){var dlg=videoDialog;dlg&&(dlg.classList.remove("videoPlayerContainer-withBackdrop"),dlg.classList.remove("videoPlayerContainer-onTop"),onStartedAndNavigatedToOsd())}function onStartedAndNavigatedToOsd(){setCurrentTrackElement(subtitleTrackIndexToSetOnPlaying),null!=audioTrackIndexToSetOnPlaying&&self.canSetAudioStreamIndex()&&self.setAudioStreamIndex(audioTrackIndexToSetOnPlaying)}function onPlaying(e){self._started||(self._started=!0,this.removeAttribute("controls"),loading.hide(),htmlMediaHelper.seekOnPlaybackStart(self,e.target,self._currentPlayOptions.playerStartPositionTicks),self._currentPlayOptions.fullscreen?appRouter.showVideoOsd().then(onNavigatedToOsd):(appRouter.setTransparency("backdrop"),videoDialog.classList.remove("videoPlayerContainer-withBackdrop"),videoDialog.classList.remove("videoPlayerContainer-onTop"),onStartedAndNavigatedToOsd())),events.trigger(self,"playing")}function onPlay(e){events.trigger(self,"unpause")}function ensureValidVideo(elem){if(elem===self._mediaElement&&0===elem.videoWidth&&0===elem.videoHeight){var mediaSource=(self._currentPlayOptions||{}).mediaSource;if(!mediaSource||mediaSource.RunTimeTicks)return void htmlMediaHelper.onErrorInternal(self,"mediadecodeerror")}}function onClick(){events.trigger(self,"click")}function onDblClick(){events.trigger(self,"dblclick")}function onPause(){events.trigger(self,"pause")}function onError(){var errorCode=this.error?this.error.code||0:0,errorMessage=this.error?this.error.message||"":"";console.log("Media element error: "+errorCode.toString()+" "+errorMessage);var type;switch(errorCode){case 1:return;case 2:type="network";break;case 3:if(self._hlsPlayer)return void htmlMediaHelper.handleHlsJsMediaError(self);type="mediadecodeerror";break;case 4:type="medianotsupported";break;default:return}htmlMediaHelper.onErrorInternal(self,type)}function destroyCustomTrack(videoElement){if(self._resizeObserver&&(self._resizeObserver.disconnect(),self._resizeObserver=null),window.removeEventListener("orientationchange",onVideoResize),videoSubtitlesElem){var subtitlesContainer=videoSubtitlesElem.parentNode;subtitlesContainer&&tryRemoveElement(subtitlesContainer),videoSubtitlesElem=null}if(currentTrackEvents=null,videoElement)for(var allTracks=videoElement.textTracks||[],i=0;i
',videoSubtitlesElem=subtitlesContainer.querySelector(".videoSubtitlesInner"),setSubtitleAppearance(subtitlesContainer,videoSubtitlesElem),videoElement.parentNode.appendChild(subtitlesContainer),currentTrackEvents=data.TrackEvents}})}function setSubtitleAppearance(elem,innerElem){require(["userSettings","subtitleAppearanceHelper"],function(userSettings,subtitleAppearanceHelper){subtitleAppearanceHelper.applyStyles({text:innerElem,window:elem},userSettings.getSubtitleAppearanceSettings())})}function getCueCss(appearance,selector){var html=selector+"::cue {";return html+=appearance.text.map(function(s){return s.name+":"+s.value+"!important;"}).join(""),html+="}"}function setCueAppearance(){require(["userSettings","subtitleAppearanceHelper"],function(userSettings,subtitleAppearanceHelper){var elementId=self.id+"-cuestyle",styleElem=document.querySelector("#"+elementId);styleElem||(styleElem=document.createElement("style"),styleElem.id=elementId,styleElem.type="text/css",document.getElementsByTagName("head")[0].appendChild(styleElem)),styleElem.innerHTML=getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings(),!0),".htmlvideoplayer")})}function renderTracksEvents(videoElement,track,item){if(!itemHelper.isLocalItem(item)||track.IsExternal){var format=(track.Codec||"").toLowerCase();if("ssa"===format||"ass"===format)return void renderWithLibjass(videoElement,track,item);if(requiresCustomSubtitlesElement())return void renderSubtitlesWithCustomElement(videoElement,track,item)}for(var trackElement=null,expectedId="manualTrack"+track.Index,allTracks=videoElement.textTracks,i=0;i=ticks){selectedTrackEvent=currentTrackEvent;break}}selectedTrackEvent&&selectedTrackEvent.Text?(subtitleTextElement.innerHTML=normalizeTrackEventText(selectedTrackEvent.Text),subtitleTextElement.classList.remove("hide")):subtitleTextElement.classList.add("hide")}}}function setCurrentTrackElement(streamIndex){console.log("Setting new text track index to: "+streamIndex);var mediaStreamTextTracks=getMediaStreamTextTracks(self._currentPlayOptions.mediaSource),track=-1===streamIndex?null:mediaStreamTextTracks.filter(function(t){return t.Index===streamIndex})[0];enableNativeTrackSupport(self._currentSrc,track)?(setTrackForCustomDisplay(self._mediaElement,null),-1!==streamIndex&&setCueAppearance()):(setTrackForCustomDisplay(self._mediaElement,track),streamIndex=-1,track=null);for(var expectedId="textTrack"+streamIndex,trackIndex=-1!==streamIndex&&track?mediaStreamTextTracks.indexOf(track):-1,modes=["disabled","showing","hidden"],allTracks=self._mediaElement.textTracks,i=0;i':html+='",dlg.innerHTML=html;var videoElement=dlg.querySelector("video");videoElement.volume=htmlMediaHelper.getSavedVolume(),videoElement.addEventListener("timeupdate",onTimeUpdate),videoElement.addEventListener("ended",onEnded),videoElement.addEventListener("volumechange",onVolumeChange),videoElement.addEventListener("pause",onPause),videoElement.addEventListener("playing",onPlaying),videoElement.addEventListener("play",onPlay),videoElement.addEventListener("click",onClick),videoElement.addEventListener("dblclick",onDblClick),document.body.insertBefore(dlg,document.body.firstChild),videoDialog=dlg,self._mediaElement=videoElement,mediaManager&&(mediaManager.embyInit||(initMediaManager(),mediaManager.embyInit=!0),mediaManager.setMediaElement(videoElement)),options.fullscreen&&browser.supportsCssAnimation()&&!browser.slow?zoomIn(dlg).then(function(){resolve(videoElement)}):resolve(videoElement)})})}browser.edgeUwp?this.name="Windows Video Player":this.name="Html Video Player",this.type="mediaplayer",this.id="htmlvideoplayer",this.priority=1;var videoDialog,subtitleTrackIndexToSetOnPlaying,audioTrackIndexToSetOnPlaying,currentClock,currentAssRenderer,videoSubtitlesElem,currentTrackEvents,lastCustomTrackMs=0,customTrackIndex=-1,self=this;self.currentSrc=function(){return self._currentSrc},self.play=function(options){return browser.msie&&"Transcode"===options.playMethod&&!window.MediaSource?(alert("Playback of this content is not supported in Internet Explorer. For a better experience, try a modern browser such as Microsoft Edge, Google Chrome, Firefox or Opera."),Promise.reject()):(self._started=!1,self._timeUpdated=!1,self._currentTime=null,createMediaElement(options).then(function(elem){return updateVideoUrl(options,options.mediaSource).then(function(){return setCurrentSrc(elem,options)})}))},self.setSubtitleStreamIndex=function(index){setCurrentTrackElement(index)},self.setAudioStreamIndex=function(index){var i,length,audioStreams=getMediaStreamAudioTracks(self._currentPlayOptions.mediaSource),audioTrackOffset=-1;for(i=0,length=audioStreams.length;i=100?"none":rawValue/100;elem.style["-webkit-filter"]="brightness("+cssValue+");",elem.style.filter="brightness("+cssValue+")",elem.brightnessValue=val,events.trigger(this,"brightnesschange")}},HtmlVideoPlayer.prototype.getBrightness=function(){var elem=this._mediaElement;if(elem){var val=elem.brightnessValue;return null==val?100:val}},HtmlVideoPlayer.prototype.seekable=function(){var mediaElement=this._mediaElement;if(mediaElement){var seekable=mediaElement.seekable;if(seekable&&seekable.length){var start=seekable.start(0),end=seekable.end(0);return htmlMediaHelper.isValidDuration(start)||(start=0),htmlMediaHelper.isValidDuration(end)||(end=0),end-start>0}return!1}},HtmlVideoPlayer.prototype.pause=function(){var mediaElement=this._mediaElement;mediaElement&&mediaElement.pause()},HtmlVideoPlayer.prototype.resume=function(){var mediaElement=this._mediaElement;mediaElement&&mediaElement.play()},HtmlVideoPlayer.prototype.unpause=function(){var mediaElement=this._mediaElement;mediaElement&&mediaElement.play()},HtmlVideoPlayer.prototype.paused=function(){var mediaElement=this._mediaElement;return!!mediaElement&&mediaElement.paused},HtmlVideoPlayer.prototype.setVolume=function(val){var mediaElement=this._mediaElement;mediaElement&&(mediaElement.volume=val/100)},HtmlVideoPlayer.prototype.getVolume=function(){var mediaElement=this._mediaElement;if(mediaElement)return Math.min(Math.round(100*mediaElement.volume),100)},HtmlVideoPlayer.prototype.volumeUp=function(){this.setVolume(Math.min(this.getVolume()+2,100))},HtmlVideoPlayer.prototype.volumeDown=function(){this.setVolume(Math.max(this.getVolume()-2,0))},HtmlVideoPlayer.prototype.setMute=function(mute){var mediaElement=this._mediaElement;mediaElement&&(mediaElement.muted=mute)},HtmlVideoPlayer.prototype.isMuted=function(){var mediaElement=this._mediaElement;return!!mediaElement&&mediaElement.muted},HtmlVideoPlayer.prototype.setAspectRatio=function(val){},HtmlVideoPlayer.prototype.getAspectRatio=function(){return this._currentAspectRatio},HtmlVideoPlayer.prototype.getSupportedAspectRatios=function(){return[]},HtmlVideoPlayer.prototype.togglePictureInPicture=function(){return this.setPictureInPictureEnabled(!this.isPictureInPictureEnabled())},HtmlVideoPlayer.prototype.getBufferedRanges=function(){var mediaElement=this._mediaElement;return mediaElement?htmlMediaHelper.getBufferedRanges(this,mediaElement):[]},HtmlVideoPlayer.prototype.getStats=function(){var mediaElement=this._mediaElement,playOptions=this._currentPlayOptions||[],categories=[];if(!mediaElement)return Promise.resolve({categories:categories});var mediaCategory={stats:[],type:"media"};if(categories.push(mediaCategory),playOptions.url){var link=document.createElement("a");link.setAttribute("href",playOptions.url);var protocol=(link.protocol||"").replace(":","");protocol&&mediaCategory.stats.push({label:"Protocol:",value:protocol}),link=null}this._hlsPlayer||this._shakaPlayer?mediaCategory.stats.push({label:"Stream type:",value:"HLS"}):mediaCategory.stats.push({label:"Stream type:",value:"Video"});var videoCategory={stats:[],type:"video"};categories.push(videoCategory);var rect=mediaElement.getBoundingClientRect?mediaElement.getBoundingClientRect():{},height=rect.height,width=rect.width;if(width&&height&&videoCategory.stats.push({label:"Player dimensions:",value:width+"x"+height}),height=mediaElement.videoHeight,width=mediaElement.videoWidth,width&&height&&videoCategory.stats.push({label:"Video resolution:",value:width+"x"+height}),mediaElement.getVideoPlaybackQuality){var playbackQuality=mediaElement.getVideoPlaybackQuality(),droppedVideoFrames=playbackQuality.droppedVideoFrames||0;videoCategory.stats.push({label:"Dropped frames:",value:droppedVideoFrames});var corruptedVideoFrames=playbackQuality.corruptedVideoFrames||0;videoCategory.stats.push({label:"Corrupted frames:",value:corruptedVideoFrames})}var audioCategory={stats:[],type:"audio"};categories.push(audioCategory);var sinkId=mediaElement.sinkId;return sinkId&&audioCategory.stats.push({label:"Sink Id:",value:sinkId}),Promise.resolve({categories:categories})},browser.chromecast&&(mediaManager=new cast.receiver.MediaManager(document.createElement("video"))),HtmlVideoPlayer}); \ No newline at end of file +define(["browser","require","events","apphost","loading","dom","playbackManager","appRouter","appSettings","connectionManager","htmlMediaHelper","itemHelper"],function(browser,require,events,appHost,loading,dom,playbackManager,appRouter,appSettings,connectionManager,htmlMediaHelper,itemHelper){"use strict";function tryRemoveElement(elem){var parentNode=elem.parentNode;if(parentNode)try{parentNode.removeChild(elem)}catch(err){console.log("Error removing dialog element: "+err)}}function enableNativeTrackSupport(currentSrc,track){if(track&&"Embed"===track.DeliveryMethod)return!0;if(browser.firefox&&-1!==(currentSrc||"").toLowerCase().indexOf(".m3u8"))return!1;if(browser.chromecast&&-1!==(currentSrc||"").toLowerCase().indexOf(".m3u8"))return!1;if(browser.ps4)return!1;if(browser.web0s)return!1;if(browser.edge)return!1;if(browser.iOS&&(browser.iosVersion||10)<10)return!1;if(track){var format=(track.Codec||"").toLowerCase();if("ssa"===format||"ass"===format)return!1}return!0}function requireHlsPlayer(callback){require(["hlsjs"],function(hls){window.Hls=hls,callback()})}function getMediaStreamAudioTracks(mediaSource){return mediaSource.MediaStreams.filter(function(s){return"Audio"===s.Type})}function getMediaStreamTextTracks(mediaSource){return mediaSource.MediaStreams.filter(function(s){return"Subtitle"===s.Type})}function zoomIn(elem){return new Promise(function(resolve,reject){elem.style.animation="htmlvideoplayer-zoomin 240ms ease-in normal",dom.addEventListener(elem,dom.whichAnimationEvent(),resolve,{once:!0})})}function normalizeTrackEventText(text){return text.replace(/\\N/gi,"\n")}function setTracks(elem,tracks,item,mediaSource){elem.innerHTML=getTracksHtml(tracks,item,mediaSource)}function getTextTrackUrl(track,item,format){if(itemHelper.isLocalItem(item)&&track.Path)return track.Path;var url=playbackManager.getSubtitleUrl(track,item.ServerId);return format&&(url=url.replace(".vtt",format)),url}function getTracksHtml(tracks,item,mediaSource){return tracks.map(function(t){if("External"!==t.DeliveryMethod)return"";var defaultAttribute=mediaSource.DefaultSubtitleStreamIndex===t.Index?" default":"",language=t.Language||"und",label=t.Language||"und";return'"}).join("")}function getDefaultProfile(){return new Promise(function(resolve,reject){require(["browserdeviceprofile"],function(profileBuilder){resolve(profileBuilder({}))})})}function HtmlVideoPlayer(){function updateVideoUrl(streamInfo){var isHls=-1!==streamInfo.url.toLowerCase().indexOf(".m3u8"),mediaSource=streamInfo.mediaSource,item=streamInfo.item;if(mediaSource&&item&&!mediaSource.RunTimeTicks&&isHls&&"Transcode"===streamInfo.playMethod&&(browser.iOS||browser.osx)){var hlsPlaylistUrl=streamInfo.url.replace("master.m3u8","live.m3u8");return loading.show(),console.log("prefetching hls playlist: "+hlsPlaylistUrl),connectionManager.getApiClient(item.ServerId).ajax({type:"GET",url:hlsPlaylistUrl}).then(function(){return console.log("completed prefetching hls playlist: "+hlsPlaylistUrl),loading.hide(),streamInfo.url=hlsPlaylistUrl,Promise.resolve()},function(){return console.log("error prefetching hls playlist: "+hlsPlaylistUrl),loading.hide(),Promise.resolve()})}return Promise.resolve()}function setSrcWithFlvJs(instance,elem,options,url){return new Promise(function(resolve,reject){require(["flvjs"],function(flvjs){var flvPlayer=flvjs.createPlayer({type:"flv",url:url},{seekType:"range",lazyLoad:!1});flvPlayer.attachMediaElement(elem),flvPlayer.load(),flvPlayer.play().then(resolve,reject),instance._flvPlayer=flvPlayer,self._currentSrc=url})})}function setSrcWithHlsJs(instance,elem,options,url){return new Promise(function(resolve,reject){requireHlsPlayer(function(){var hls=new Hls({manifestLoadingTimeOut:2e4});hls.loadSource(url),hls.attachMedia(elem),htmlMediaHelper.bindEventsToHlsPlayer(self,hls,elem,onError,resolve,reject),self._hlsPlayer=hls,self._currentSrc=url})})}function setCurrentSrcChromecast(instance,elem,options,url){elem.autoplay=!0;var lrd=new cast.receiver.MediaManager.LoadRequestData;lrd.currentTime=(options.playerStartPositionTicks||0)/1e7,lrd.autoplay=!0,lrd.media=new cast.receiver.media.MediaInformation,lrd.media.contentId=url,lrd.media.contentType=options.mimeType,lrd.media.streamType=cast.receiver.media.StreamType.OTHER,lrd.media.customData=options,console.log("loading media url into mediaManager");try{return mediaManager.load(lrd),self._currentSrc=url,Promise.resolve()}catch(err){return console.log("mediaManager error: "+err),Promise.reject()}}function onMediaManagerLoadMedia(event){self._castPlayer&&self._castPlayer.unload(),self._castPlayer=null;var protocol,data=event.data,media=event.data.media||{},url=media.contentId,contentType=media.contentType.toLowerCase(),mediaElement=(media.customData,self._mediaElement),host=new cast.player.api.Host({url:url,mediaElement:mediaElement});protocol=cast.player.api.CreateHlsStreamingProtocol(host),console.log("loading playback url: "+url),console.log("contentType: "+contentType),host.onError=function(errorCode){console.log("Fatal Error - "+errorCode)},mediaElement.autoplay=!1,self._castPlayer=new cast.player.api.Player(host),self._castPlayer.load(protocol,data.currentTime||0),self._castPlayer.playWhenHaveEnoughData()}function initMediaManager(){mediaManager.defaultOnLoad=mediaManager.onLoad.bind(mediaManager),mediaManager.onLoad=onMediaManagerLoadMedia.bind(self),mediaManager.defaultOnStop=mediaManager.onStop.bind(mediaManager),mediaManager.onStop=function(event){playbackManager.stop(),mediaManager.defaultOnStop(event)}}function setCurrentSrc(elem,options){elem.removeEventListener("error",onError);var val=options.url;console.log("playing url: "+val);var seconds=(options.playerStartPositionTicks||0)/1e7;seconds&&(val+="#t="+seconds),htmlMediaHelper.destroyHlsPlayer(self),htmlMediaHelper.destroyFlvPlayer(self),htmlMediaHelper.destroyCastPlayer(self);var tracks=getMediaStreamTextTracks(options.mediaSource);subtitleTrackIndexToSetOnPlaying=null==options.mediaSource.DefaultSubtitleStreamIndex?-1:options.mediaSource.DefaultSubtitleStreamIndex,audioTrackIndexToSetOnPlaying="Transcode"===options.playMethod?null:options.mediaSource.DefaultAudioStreamIndex,self._currentPlayOptions=options;var crossOrigin=htmlMediaHelper.getCrossOriginValue(options.mediaSource);return crossOrigin&&(elem.crossOrigin=crossOrigin),browser.chromecast&&-1!==val.indexOf(".m3u8")&&options.mediaSource.RunTimeTicks?(setTracks(elem,tracks,options.item,options.mediaSource),setCurrentSrcChromecast(self,elem,options,val)):htmlMediaHelper.enableHlsJsPlayer(options.mediaSource.RunTimeTicks,"Video")&&-1!==val.indexOf(".m3u8")?(setTracks(elem,tracks,options.item,options.mediaSource),setSrcWithHlsJs(self,elem,options,val)):"Transcode"!==options.playMethod&&"flv"===options.mediaSource.Container?(setTracks(elem,tracks,options.item,options.mediaSource),setSrcWithFlvJs(self,elem,options,val)):(elem.autoplay=!0,htmlMediaHelper.applySrc(elem,val,options).then(function(){return setTracks(elem,tracks,options.item,options.mediaSource),self._currentSrc=val,htmlMediaHelper.playWithPromise(elem,onError)}))}function onEnded(){destroyCustomTrack(this),htmlMediaHelper.onEndedInternal(self,this,onError)}function onTimeUpdate(e){var time=this.currentTime;time&&!self._timeUpdated&&(self._timeUpdated=!0,ensureValidVideo(this)),self._currentTime=time;var currentPlayOptions=self._currentPlayOptions;if(currentPlayOptions){var timeMs=1e3*time;timeMs+=(currentPlayOptions.transcodingOffsetTicks||0)/1e4,updateSubtitleText(timeMs)}events.trigger(self,"timeupdate")}function onVolumeChange(){htmlMediaHelper.saveVolume(this.volume),events.trigger(self,"volumechange")}function onNavigatedToOsd(){var dlg=videoDialog;dlg&&(dlg.classList.remove("videoPlayerContainer-withBackdrop"),dlg.classList.remove("videoPlayerContainer-onTop"),onStartedAndNavigatedToOsd())}function onStartedAndNavigatedToOsd(){setCurrentTrackElement(subtitleTrackIndexToSetOnPlaying),null!=audioTrackIndexToSetOnPlaying&&self.canSetAudioStreamIndex()&&self.setAudioStreamIndex(audioTrackIndexToSetOnPlaying)}function onPlaying(e){self._started||(self._started=!0,this.removeAttribute("controls"),loading.hide(),htmlMediaHelper.seekOnPlaybackStart(self,e.target,self._currentPlayOptions.playerStartPositionTicks),self._currentPlayOptions.fullscreen?appRouter.showVideoOsd().then(onNavigatedToOsd):(appRouter.setTransparency("backdrop"),videoDialog.classList.remove("videoPlayerContainer-withBackdrop"),videoDialog.classList.remove("videoPlayerContainer-onTop"),onStartedAndNavigatedToOsd())),events.trigger(self,"playing")}function onPlay(e){events.trigger(self,"unpause")}function ensureValidVideo(elem){if(elem===self._mediaElement&&0===elem.videoWidth&&0===elem.videoHeight){var mediaSource=(self._currentPlayOptions||{}).mediaSource;if(!mediaSource||mediaSource.RunTimeTicks)return void htmlMediaHelper.onErrorInternal(self,"mediadecodeerror")}}function onClick(){events.trigger(self,"click")}function onDblClick(){events.trigger(self,"dblclick")}function onPause(){events.trigger(self,"pause")}function onError(){var errorCode=this.error?this.error.code||0:0,errorMessage=this.error?this.error.message||"":"";console.log("Media element error: "+errorCode.toString()+" "+errorMessage);var type;switch(errorCode){case 1:return;case 2:type="network";break;case 3:if(self._hlsPlayer)return void htmlMediaHelper.handleHlsJsMediaError(self);type="mediadecodeerror";break;case 4:type="medianotsupported";break;default:return}htmlMediaHelper.onErrorInternal(self,type)}function destroyCustomTrack(videoElement){if(self._resizeObserver&&(self._resizeObserver.disconnect(),self._resizeObserver=null),window.removeEventListener("orientationchange",onVideoResize),videoSubtitlesElem){var subtitlesContainer=videoSubtitlesElem.parentNode;subtitlesContainer&&tryRemoveElement(subtitlesContainer),videoSubtitlesElem=null}if(currentTrackEvents=null,videoElement)for(var allTracks=videoElement.textTracks||[],i=0;i
',videoSubtitlesElem=subtitlesContainer.querySelector(".videoSubtitlesInner"),setSubtitleAppearance(subtitlesContainer,videoSubtitlesElem),videoElement.parentNode.appendChild(subtitlesContainer),currentTrackEvents=data.TrackEvents}})}function setSubtitleAppearance(elem,innerElem){require(["userSettings","subtitleAppearanceHelper"],function(userSettings,subtitleAppearanceHelper){subtitleAppearanceHelper.applyStyles({text:innerElem,window:elem},userSettings.getSubtitleAppearanceSettings())})}function getCueCss(appearance,selector){var html=selector+"::cue {";return html+=appearance.text.map(function(s){return s.name+":"+s.value+"!important;"}).join(""),html+="}"}function setCueAppearance(){require(["userSettings","subtitleAppearanceHelper"],function(userSettings,subtitleAppearanceHelper){var elementId=self.id+"-cuestyle",styleElem=document.querySelector("#"+elementId);styleElem||(styleElem=document.createElement("style"),styleElem.id=elementId,styleElem.type="text/css",document.getElementsByTagName("head")[0].appendChild(styleElem)),styleElem.innerHTML=getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings(),!0),".htmlvideoplayer")})}function renderTracksEvents(videoElement,track,item){if(!itemHelper.isLocalItem(item)||track.IsExternal){var format=(track.Codec||"").toLowerCase();if("ssa"===format||"ass"===format)return void renderWithLibjass(videoElement,track,item);if(requiresCustomSubtitlesElement())return void renderSubtitlesWithCustomElement(videoElement,track,item)}for(var trackElement=null,expectedId="manualTrack"+track.Index,allTracks=videoElement.textTracks,i=0;i=ticks){selectedTrackEvent=currentTrackEvent;break}}selectedTrackEvent&&selectedTrackEvent.Text?(subtitleTextElement.innerHTML=normalizeTrackEventText(selectedTrackEvent.Text),subtitleTextElement.classList.remove("hide")):subtitleTextElement.classList.add("hide")}}}function setCurrentTrackElement(streamIndex){console.log("Setting new text track index to: "+streamIndex);var mediaStreamTextTracks=getMediaStreamTextTracks(self._currentPlayOptions.mediaSource),track=-1===streamIndex?null:mediaStreamTextTracks.filter(function(t){return t.Index===streamIndex})[0];enableNativeTrackSupport(self._currentSrc,track)?(setTrackForCustomDisplay(self._mediaElement,null),-1!==streamIndex&&setCueAppearance()):(setTrackForCustomDisplay(self._mediaElement,track),streamIndex=-1,track=null);for(var expectedId="textTrack"+streamIndex,trackIndex=-1!==streamIndex&&track?mediaStreamTextTracks.indexOf(track):-1,modes=["disabled","showing","hidden"],allTracks=self._mediaElement.textTracks,i=0;i':html+='",dlg.innerHTML=html;var videoElement=dlg.querySelector("video");videoElement.volume=htmlMediaHelper.getSavedVolume(),videoElement.addEventListener("timeupdate",onTimeUpdate),videoElement.addEventListener("ended",onEnded),videoElement.addEventListener("volumechange",onVolumeChange),videoElement.addEventListener("pause",onPause),videoElement.addEventListener("playing",onPlaying),videoElement.addEventListener("play",onPlay),videoElement.addEventListener("click",onClick),videoElement.addEventListener("dblclick",onDblClick),document.body.insertBefore(dlg,document.body.firstChild),videoDialog=dlg,self._mediaElement=videoElement,mediaManager&&(mediaManager.embyInit||(initMediaManager(),mediaManager.embyInit=!0),mediaManager.setMediaElement(videoElement)),options.fullscreen&&browser.supportsCssAnimation()&&!browser.slow?zoomIn(dlg).then(function(){resolve(videoElement)}):resolve(videoElement)})})}browser.edgeUwp?this.name="Windows Video Player":this.name="Html Video Player",this.type="mediaplayer",this.id="htmlvideoplayer",this.priority=1;var videoDialog,subtitleTrackIndexToSetOnPlaying,audioTrackIndexToSetOnPlaying,currentClock,currentAssRenderer,videoSubtitlesElem,currentTrackEvents,lastCustomTrackMs=0,customTrackIndex=-1,self=this;self.currentSrc=function(){return self._currentSrc},self.play=function(options){return browser.msie&&"Transcode"===options.playMethod&&!window.MediaSource?(alert("Playback of this content is not supported in Internet Explorer. For a better experience, try a modern browser such as Microsoft Edge, Google Chrome, Firefox or Opera."),Promise.reject()):(self._started=!1,self._timeUpdated=!1,self._currentTime=null,createMediaElement(options).then(function(elem){return updateVideoUrl(options,options.mediaSource).then(function(){return setCurrentSrc(elem,options)})}))},self.setSubtitleStreamIndex=function(index){setCurrentTrackElement(index)},self.setAudioStreamIndex=function(index){var i,length,audioStreams=getMediaStreamAudioTracks(self._currentPlayOptions.mediaSource),audioTrackOffset=-1;for(i=0,length=audioStreams.length;i=100?"none":rawValue/100;elem.style["-webkit-filter"]="brightness("+cssValue+");",elem.style.filter="brightness("+cssValue+")",elem.brightnessValue=val,events.trigger(this,"brightnesschange")}},HtmlVideoPlayer.prototype.getBrightness=function(){var elem=this._mediaElement;if(elem){var val=elem.brightnessValue;return null==val?100:val}},HtmlVideoPlayer.prototype.seekable=function(){var mediaElement=this._mediaElement;if(mediaElement){var seekable=mediaElement.seekable;if(seekable&&seekable.length){var start=seekable.start(0),end=seekable.end(0);return htmlMediaHelper.isValidDuration(start)||(start=0),htmlMediaHelper.isValidDuration(end)||(end=0),end-start>0}return!1}},HtmlVideoPlayer.prototype.pause=function(){var mediaElement=this._mediaElement;mediaElement&&mediaElement.pause()},HtmlVideoPlayer.prototype.resume=function(){var mediaElement=this._mediaElement;mediaElement&&mediaElement.play()},HtmlVideoPlayer.prototype.unpause=function(){var mediaElement=this._mediaElement;mediaElement&&mediaElement.play()},HtmlVideoPlayer.prototype.paused=function(){var mediaElement=this._mediaElement;return!!mediaElement&&mediaElement.paused},HtmlVideoPlayer.prototype.setVolume=function(val){var mediaElement=this._mediaElement;mediaElement&&(mediaElement.volume=val/100)},HtmlVideoPlayer.prototype.getVolume=function(){var mediaElement=this._mediaElement;if(mediaElement)return Math.min(Math.round(100*mediaElement.volume),100)},HtmlVideoPlayer.prototype.volumeUp=function(){this.setVolume(Math.min(this.getVolume()+2,100))},HtmlVideoPlayer.prototype.volumeDown=function(){this.setVolume(Math.max(this.getVolume()-2,0))},HtmlVideoPlayer.prototype.setMute=function(mute){var mediaElement=this._mediaElement;mediaElement&&(mediaElement.muted=mute)},HtmlVideoPlayer.prototype.isMuted=function(){var mediaElement=this._mediaElement;return!!mediaElement&&mediaElement.muted},HtmlVideoPlayer.prototype.setAspectRatio=function(val){},HtmlVideoPlayer.prototype.getAspectRatio=function(){return this._currentAspectRatio},HtmlVideoPlayer.prototype.getSupportedAspectRatios=function(){return[]},HtmlVideoPlayer.prototype.togglePictureInPicture=function(){return this.setPictureInPictureEnabled(!this.isPictureInPictureEnabled())},HtmlVideoPlayer.prototype.getBufferedRanges=function(){var mediaElement=this._mediaElement;return mediaElement?htmlMediaHelper.getBufferedRanges(this,mediaElement):[]},HtmlVideoPlayer.prototype.getStats=function(){var mediaElement=this._mediaElement,playOptions=this._currentPlayOptions||[],categories=[];if(!mediaElement)return Promise.resolve({categories:categories});var mediaCategory={stats:[],type:"media"};if(categories.push(mediaCategory),playOptions.url){var link=document.createElement("a");link.setAttribute("href",playOptions.url);var protocol=(link.protocol||"").replace(":","");protocol&&mediaCategory.stats.push({label:"Protocol:",value:protocol}),link=null}this._hlsPlayer||this._shakaPlayer?mediaCategory.stats.push({label:"Stream type:",value:"HLS"}):mediaCategory.stats.push({label:"Stream type:",value:"Video"});var videoCategory={stats:[],type:"video"};categories.push(videoCategory);var rect=mediaElement.getBoundingClientRect?mediaElement.getBoundingClientRect():{},height=rect.height,width=rect.width;if(width&&height&&videoCategory.stats.push({label:"Player dimensions:",value:width+"x"+height}),height=mediaElement.videoHeight,width=mediaElement.videoWidth,width&&height&&videoCategory.stats.push({label:"Video resolution:",value:width+"x"+height}),mediaElement.getVideoPlaybackQuality){var playbackQuality=mediaElement.getVideoPlaybackQuality(),droppedVideoFrames=playbackQuality.droppedVideoFrames||0;videoCategory.stats.push({label:"Dropped frames:",value:droppedVideoFrames});var corruptedVideoFrames=playbackQuality.corruptedVideoFrames||0;videoCategory.stats.push({label:"Corrupted frames:",value:corruptedVideoFrames})}var audioCategory={stats:[],type:"audio"};categories.push(audioCategory);var sinkId=mediaElement.sinkId;return sinkId&&audioCategory.stats.push({label:"Sink Id:",value:sinkId}),Promise.resolve({categories:categories})},browser.chromecast&&(mediaManager=new cast.receiver.MediaManager(document.createElement("video"))),HtmlVideoPlayer}); \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js index 39151de2b7..550a347347 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js +++ b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js @@ -1 +1 @@ -define(["datetime","globalize","appRouter","itemHelper","indicators","material-icons","css!./mediainfo.css","programStyles","emby-linkbutton"],function(datetime,globalize,appRouter,itemHelper,indicators){"use strict";function getTimerIndicator(item){var status;if("SeriesTimer"===item.Type)return'';if(item.TimerId||item.SeriesTimerId)status=item.Status||"Cancelled";else{if("Timer"!==item.Type)return"";status=item.Status}return item.SeriesTimerId?"Cancelled"!==status?'':'':''}function getProgramInfoHtml(item,options){var text,date,html="",miscInfo=[];if(item.StartDate&&!1!==options.programTime)try{text="",date=datetime.parseISO8601Date(item.StartDate),!1!==options.startDate&&(text+=datetime.toLocaleDateString(date,{weekday:"short",month:"short",day:"numeric"})),text+=" "+datetime.getDisplayTime(date),item.EndDate&&(date=datetime.parseISO8601Date(item.EndDate),text+=" - "+datetime.getDisplayTime(date)),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.StartDate)}if(item.ChannelNumber&&miscInfo.push("CH "+item.ChannelNumber),item.ChannelName&&(options.interactive&&item.ChannelId?miscInfo.push({html:''+item.ChannelName+""}):miscInfo.push(item.ChannelName)),!1!==options.timerIndicator){var timerHtml=getTimerIndicator(item);timerHtml&&miscInfo.push({html:timerHtml})}return html+=miscInfo.map(function(m){return getMediaInfoItem(m)}).join("")}function getMediaInfoHtml(item,options){var html="",miscInfo=[];options=options||{};var text,date,minutes,count,showFolderRuntime="MusicAlbum"===item.Type||"MusicArtist"===item.MediaType||"Playlist"===item.MediaType||"MusicGenre"===item.MediaType;if(showFolderRuntime?(count=item.SongCount||item.ChildCount,count&&miscInfo.push(globalize.translate("sharedcomponents#TrackCount",count)),item.RunTimeTicks&&miscInfo.push(datetime.getDisplayRunningTime(item.RunTimeTicks))):"PhotoAlbum"!==item.Type&&"BoxSet"!==item.Type||(count=item.ChildCount)&&miscInfo.push(globalize.translate("sharedcomponents#ItemCount",count)),("Episode"===item.Type||"Photo"===item.MediaType)&&!1!==options.originalAirDate&&item.PremiereDate)try{date=datetime.parseISO8601Date(item.PremiereDate),text=datetime.toLocaleDateString(date),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.PremiereDate)}if("SeriesTimer"===item.Type&&(item.RecordAnyTime?miscInfo.push(globalize.translate("sharedcomponents#Anytime")):miscInfo.push(datetime.getDisplayTime(item.StartDate)),item.RecordAnyChannel?miscInfo.push(globalize.translate("sharedcomponents#AllChannels")):miscInfo.push(item.ChannelName||globalize.translate("sharedcomponents#OneChannel"))),item.StartDate&&"Program"!==item.Type&&"SeriesTimer"!==item.Type)try{date=datetime.parseISO8601Date(item.StartDate),text=datetime.toLocaleDateString(date),miscInfo.push(text),"Recording"!==item.Type&&(text=datetime.getDisplayTime(date),miscInfo.push(text))}catch(e){console.log("Error parsing date: "+item.StartDate)}if(!1!==options.year&&item.ProductionYear&&"Series"===item.Type)if("Continuing"===item.Status)miscInfo.push(globalize.translate("sharedcomponents#SeriesYearToPresent",item.ProductionYear));else if(item.ProductionYear){if(text=item.ProductionYear,item.EndDate)try{var endYear=datetime.parseISO8601Date(item.EndDate).getFullYear();endYear!==item.ProductionYear&&(text+="-"+datetime.parseISO8601Date(item.EndDate).getFullYear())}catch(e){console.log("Error parsing date: "+item.EndDate)}miscInfo.push(text)}if("Program"===item.Type)if(!1!==options.programIndicator&&(item.IsLive?miscInfo.push({html:'
'+globalize.translate("sharedcomponents#Live")+"
"}):item.IsPremiere?miscInfo.push({html:'
'+globalize.translate("sharedcomponents#Premiere")+"
"}):item.IsSeries&&!item.IsRepeat?miscInfo.push({html:'
'+globalize.translate("sharedcomponents#AttributeNew")+"
"}):item.IsSeries&&item.IsRepeat&&miscInfo.push({html:'
'+globalize.translate("sharedcomponents#Repeat")+"
"})),(item.IsSeries||item.EpisodeTitle)&&!1!==options.episodeTitle)(text=itemHelper.getDisplayName(item,{includeIndexNumber:options.episodeTitleIndexNumber}))&&miscInfo.push(text);else if(item.IsMovie&&item.ProductionYear&&!1!==options.originalAirDate)miscInfo.push(item.ProductionYear);else if(item.PremiereDate&&!1!==options.originalAirDate)try{date=datetime.parseISO8601Date(item.PremiereDate),text=globalize.translate("sharedcomponents#OriginalAirDateValue",datetime.toLocaleDateString(date)),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.PremiereDate)}else item.ProductionYear&&miscInfo.push(item.ProductionYear);if(!1!==options.year&&"Series"!==item.Type&&"Episode"!==item.Type&&"Person"!==item.Type&&"Photo"!==item.MediaType&&"Program"!==item.Type&&"Season"!==item.Type)if(item.ProductionYear)miscInfo.push(item.ProductionYear);else if(item.PremiereDate)try{text=datetime.parseISO8601Date(item.PremiereDate).getFullYear(),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.PremiereDate)}if(item.RunTimeTicks&&"Series"!==item.Type&&"Program"!==item.Type&&!showFolderRuntime&&!1!==options.runtime&&("Audio"===item.Type?miscInfo.push(datetime.getDisplayRunningTime(item.RunTimeTicks)):(minutes=item.RunTimeTicks/6e8,minutes=minutes||1,miscInfo.push(Math.round(minutes)+" mins"))),item.OfficialRating&&"Season"!==item.Type&&"Episode"!==item.Type&&miscInfo.push({text:item.OfficialRating,cssClass:"mediaInfoOfficialRating"}),item.Video3DFormat&&miscInfo.push("3D"),"Photo"===item.MediaType&&item.Width&&item.Height&&miscInfo.push(item.Width+"x"+item.Height),!1!==options.container&&"Audio"===item.Type&&item.Container&&miscInfo.push(item.Container),html+=miscInfo.map(function(m){return getMediaInfoItem(m)}).join(""),html+=getStarIconsHtml(item),item.HasSubtitles&&!1!==options.subtitles&&(html+='
CC
'),item.CriticRating&&!1!==options.criticRating&&(item.CriticRating>=60?html+='
'+item.CriticRating+"
":html+='
'+item.CriticRating+"
"),!1!==options.endsAt){var endsAt=getEndsAt(item);endsAt&&(html+=getMediaInfoItem(endsAt,"endsAt"))}return html+=indicators.getMissingIndicator(item)}function getEndsAt(item){if("Video"===item.MediaType&&item.RunTimeTicks&&!item.StartDate){var endDate=(new Date).getTime()+item.RunTimeTicks/1e4;endDate=new Date(endDate);var displayTime=datetime.getDisplayTime(endDate);return globalize.translate("sharedcomponents#EndsAtValue",displayTime)}return null}function getEndsAtFromPosition(runtimeTicks,positionTicks,includeText){var endDate=(new Date).getTime()+(runtimeTicks-(positionTicks||0))/1e4;endDate=new Date(endDate);var displayTime=datetime.getDisplayTime(endDate);return!1===includeText?displayTime:globalize.translate("sharedcomponents#EndsAtValue",displayTime)}function getMediaInfoItem(m,cssClass){cssClass=cssClass?cssClass+" mediaInfoItem":"mediaInfoItem";var mediaInfoText=m;if("string"!=typeof m&&"number"!=typeof m){if(m.html)return m.html;mediaInfoText=m.text,cssClass+=" "+m.cssClass}return'
'+mediaInfoText+"
"}function getStarIconsHtml(item){var html="",rating=item.CommunityRating;return rating&&(html+='
',html+='',html+=rating,html+="
"),html}function dynamicEndTime(elem,item){var interval=setInterval(function(){if(!document.body.contains(elem))return void clearInterval(interval);elem.innerHTML=getEndsAt(item)},6e4)}function fillPrimaryMediaInfo(elem,item,options){var html=getPrimaryMediaInfoHtml(item,options);elem.innerHTML=html,afterFill(elem,item,options)}function fillSecondaryMediaInfo(elem,item,options){var html=getSecondaryMediaInfoHtml(item,options);elem.innerHTML=html,afterFill(elem,item,options)}function afterFill(elem,item,options){if(!1!==options.endsAt){var endsAtElem=elem.querySelector(".endsAt");endsAtElem&&dynamicEndTime(endsAtElem,item)}var lnkChannel=elem.querySelector(".lnkChannel");lnkChannel&&lnkChannel.addEventListener("click",onChannelLinkClick)}function onChannelLinkClick(e){var channelId=this.getAttribute("data-id"),serverId=this.getAttribute("data-serverid");return appRouter.showItem(channelId,serverId),e.preventDefault(),!1}function getPrimaryMediaInfoHtml(item,options){return options=options||{},null==options.interactive&&(options.interactive=!1),getMediaInfoHtml(item,options)}function getSecondaryMediaInfoHtml(item,options){return options=options||{},null==options.interactive&&(options.interactive=!1),"Program"===item.Type?getProgramInfoHtml(item,options):""}function getResolutionText(i){var width=i.Width,height=i.Height;if(width&&height){if(width>=3800||height>=2e3)return"4K";if(width>=2500||height>=1400)return i.IsInterlaced?"1440i":"1440P";if(width>=1880||height>=1e3)return i.IsInterlaced?"1080i":"1080P";if(width>=1200||height>=700)return i.IsInterlaced?"720i":"720P";if(width>=700||height>=400)return i.IsInterlaced?"480i":"480P"}return null}function getAudioStreamForDisplay(item){if(!item.MediaSources)return null;var mediaSource=item.MediaSources[0];return mediaSource?(mediaSource.MediaStreams||[]).filter(function(i){return"Audio"===i.Type&&(i.Index===mediaSource.DefaultAudioStreamIndex||null==mediaSource.DefaultAudioStreamIndex)})[0]:null}function getMediaInfoStats(item,options){options=options||{};var list=[],mediaSource=(item.MediaSources||[])[0]||{},videoStream=(mediaSource.MediaStreams||[]).filter(function(i){return"Video"===i.Type})[0]||{},audioStream=getAudioStreamForDisplay(item)||{};"Dvd"===item.VideoType&&list.push({type:"mediainfo",text:"Dvd"}),"BluRay"===item.VideoType&&list.push({type:"mediainfo",text:"BluRay"});var resolutionText=getResolutionText(videoStream);resolutionText&&list.push({type:"mediainfo",text:resolutionText}),videoStream.Codec&&list.push({type:"mediainfo",text:videoStream.Codec});var channelText,channels=audioStream.Channels;8===channels?channelText="7.1":7===channels?channelText="6.1":6===channels?channelText="5.1":2===channels&&(channelText="2.0"),channelText&&list.push({type:"mediainfo",text:channelText});var audioCodec=(audioStream.Codec||"").toLowerCase();if("dca"!==audioCodec&&"dts"!==audioCodec||!audioStream.Profile?audioStream.Codec&&list.push({type:"mediainfo",text:audioStream.Codec}):list.push({type:"mediainfo",text:audioStream.Profile}),item.DateCreated&&itemHelper.enableDateAddedDisplay(item)){var dateCreated=datetime.parseISO8601Date(item.DateCreated);list.push({type:"added",text:globalize.translate("sharedcomponents#AddedOnValue",datetime.toLocaleDateString(dateCreated)+" "+datetime.getDisplayTime(dateCreated))})}return list}return{getMediaInfoHtml:getPrimaryMediaInfoHtml,fill:fillPrimaryMediaInfo,getEndsAt:getEndsAt,getEndsAtFromPosition:getEndsAtFromPosition,getPrimaryMediaInfoHtml:getPrimaryMediaInfoHtml,getSecondaryMediaInfoHtml:getSecondaryMediaInfoHtml,fillPrimaryMediaInfo:fillPrimaryMediaInfo,fillSecondaryMediaInfo:fillSecondaryMediaInfo,getMediaInfoStats:getMediaInfoStats,getResolutionText:getResolutionText}}); \ No newline at end of file +define(["datetime","globalize","appRouter","itemHelper","indicators","material-icons","css!./mediainfo.css","programStyles","emby-linkbutton"],function(datetime,globalize,appRouter,itemHelper,indicators){"use strict";function getTimerIndicator(item){var status;if("SeriesTimer"===item.Type)return'';if(item.TimerId||item.SeriesTimerId)status=item.Status||"Cancelled";else{if("Timer"!==item.Type)return"";status=item.Status}return item.SeriesTimerId?"Cancelled"!==status?'':'':''}function getProgramInfoHtml(item,options){var text,date,html="",miscInfo=[];if(item.StartDate&&!1!==options.programTime)try{text="",date=datetime.parseISO8601Date(item.StartDate),!1!==options.startDate&&(text+=datetime.toLocaleDateString(date,{weekday:"short",month:"short",day:"numeric"})),text+=" "+datetime.getDisplayTime(date),item.EndDate&&(date=datetime.parseISO8601Date(item.EndDate),text+=" - "+datetime.getDisplayTime(date)),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.StartDate)}if(item.ChannelNumber&&miscInfo.push("CH "+item.ChannelNumber),item.ChannelName&&(options.interactive&&item.ChannelId?miscInfo.push({html:''+item.ChannelName+""}):miscInfo.push(item.ChannelName)),!1!==options.timerIndicator){var timerHtml=getTimerIndicator(item);timerHtml&&miscInfo.push({html:timerHtml})}return html+=miscInfo.map(function(m){return getMediaInfoItem(m)}).join("")}function getMediaInfoHtml(item,options){var html="",miscInfo=[];options=options||{};var text,date,minutes,count,showFolderRuntime="MusicAlbum"===item.Type||"MusicArtist"===item.MediaType||"Playlist"===item.MediaType||"MusicGenre"===item.MediaType;if(showFolderRuntime?(count=item.SongCount||item.ChildCount,count&&miscInfo.push(globalize.translate("sharedcomponents#TrackCount",count)),item.RunTimeTicks&&miscInfo.push(datetime.getDisplayRunningTime(item.RunTimeTicks))):"PhotoAlbum"!==item.Type&&"BoxSet"!==item.Type||(count=item.ChildCount)&&miscInfo.push(globalize.translate("sharedcomponents#ItemCount",count)),("Episode"===item.Type||"Photo"===item.MediaType)&&!1!==options.originalAirDate&&item.PremiereDate)try{date=datetime.parseISO8601Date(item.PremiereDate),text=datetime.toLocaleDateString(date),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.PremiereDate)}if("SeriesTimer"===item.Type&&(item.RecordAnyTime?miscInfo.push(globalize.translate("sharedcomponents#Anytime")):miscInfo.push(datetime.getDisplayTime(item.StartDate)),item.RecordAnyChannel?miscInfo.push(globalize.translate("sharedcomponents#AllChannels")):miscInfo.push(item.ChannelName||globalize.translate("sharedcomponents#OneChannel"))),item.StartDate&&"Program"!==item.Type&&"SeriesTimer"!==item.Type)try{date=datetime.parseISO8601Date(item.StartDate),text=datetime.toLocaleDateString(date),miscInfo.push(text),"Recording"!==item.Type&&(text=datetime.getDisplayTime(date),miscInfo.push(text))}catch(e){console.log("Error parsing date: "+item.StartDate)}if(!1!==options.year&&item.ProductionYear&&"Series"===item.Type)if("Continuing"===item.Status)miscInfo.push(globalize.translate("sharedcomponents#SeriesYearToPresent",item.ProductionYear));else if(item.ProductionYear){if(text=item.ProductionYear,item.EndDate)try{var endYear=datetime.parseISO8601Date(item.EndDate).getFullYear();endYear!==item.ProductionYear&&(text+="-"+datetime.parseISO8601Date(item.EndDate).getFullYear())}catch(e){console.log("Error parsing date: "+item.EndDate)}miscInfo.push(text)}if("Program"===item.Type)if(!1!==options.programIndicator&&(item.IsLive?miscInfo.push({html:'
'+globalize.translate("sharedcomponents#Live")+"
"}):item.IsPremiere?miscInfo.push({html:'
'+globalize.translate("sharedcomponents#Premiere")+"
"}):item.IsSeries&&!item.IsRepeat?miscInfo.push({html:'
'+globalize.translate("sharedcomponents#AttributeNew")+"
"}):item.IsSeries&&item.IsRepeat&&miscInfo.push({html:'
'+globalize.translate("sharedcomponents#Repeat")+"
"})),(item.IsSeries||item.EpisodeTitle)&&!1!==options.episodeTitle)(text=itemHelper.getDisplayName(item,{includeIndexNumber:options.episodeTitleIndexNumber}))&&miscInfo.push(text);else if(item.IsMovie&&item.ProductionYear&&!1!==options.originalAirDate)miscInfo.push(item.ProductionYear);else if(item.PremiereDate&&!1!==options.originalAirDate)try{date=datetime.parseISO8601Date(item.PremiereDate),text=globalize.translate("sharedcomponents#OriginalAirDateValue",datetime.toLocaleDateString(date)),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.PremiereDate)}else item.ProductionYear&&miscInfo.push(item.ProductionYear);if(!1!==options.year&&"Series"!==item.Type&&"Episode"!==item.Type&&"Person"!==item.Type&&"Photo"!==item.MediaType&&"Program"!==item.Type&&"Season"!==item.Type)if(item.ProductionYear)miscInfo.push(item.ProductionYear);else if(item.PremiereDate)try{text=datetime.parseISO8601Date(item.PremiereDate).getFullYear(),miscInfo.push(text)}catch(e){console.log("Error parsing date: "+item.PremiereDate)}if(item.RunTimeTicks&&"Series"!==item.Type&&"Program"!==item.Type&&!showFolderRuntime&&!1!==options.runtime&&("Audio"===item.Type?miscInfo.push(datetime.getDisplayRunningTime(item.RunTimeTicks)):(minutes=item.RunTimeTicks/6e8,minutes=minutes||1,miscInfo.push(Math.round(minutes)+" mins"))),item.OfficialRating&&"Season"!==item.Type&&"Episode"!==item.Type&&miscInfo.push({text:item.OfficialRating,cssClass:"mediaInfoOfficialRating"}),item.Video3DFormat&&miscInfo.push("3D"),"Photo"===item.MediaType&&item.Width&&item.Height&&miscInfo.push(item.Width+"x"+item.Height),!1!==options.container&&"Audio"===item.Type&&item.Container&&miscInfo.push(item.Container),html+=miscInfo.map(function(m){return getMediaInfoItem(m)}).join(""),html+=getStarIconsHtml(item),item.HasSubtitles&&!1!==options.subtitles&&(html+='
CC
'),item.CriticRating&&!1!==options.criticRating&&(item.CriticRating>=60?html+='
'+item.CriticRating+"
":html+='
'+item.CriticRating+"
"),!1!==options.endsAt){var endsAt=getEndsAt(item);endsAt&&(html+=getMediaInfoItem(endsAt,"endsAt"))}return html+=indicators.getMissingIndicator(item)}function getEndsAt(item){if("Video"===item.MediaType&&item.RunTimeTicks&&!item.StartDate){var endDate=(new Date).getTime()+item.RunTimeTicks/1e4;endDate=new Date(endDate);var displayTime=datetime.getDisplayTime(endDate);return globalize.translate("sharedcomponents#EndsAtValue",displayTime)}return null}function getEndsAtFromPosition(runtimeTicks,positionTicks,includeText){var endDate=(new Date).getTime()+(runtimeTicks-(positionTicks||0))/1e4;endDate=new Date(endDate);var displayTime=datetime.getDisplayTime(endDate);return!1===includeText?displayTime:globalize.translate("sharedcomponents#EndsAtValue",displayTime)}function getMediaInfoItem(m,cssClass){cssClass=cssClass?cssClass+" mediaInfoItem":"mediaInfoItem";var mediaInfoText=m;if("string"!=typeof m&&"number"!=typeof m){if(m.html)return m.html;mediaInfoText=m.text,cssClass+=" "+m.cssClass}return'
'+mediaInfoText+"
"}function getStarIconsHtml(item){var html="",rating=item.CommunityRating;return rating&&(html+='
',html+='',html+=rating,html+="
"),html}function dynamicEndTime(elem,item){var interval=setInterval(function(){if(!document.body.contains(elem))return void clearInterval(interval);elem.innerHTML=getEndsAt(item)},6e4)}function fillPrimaryMediaInfo(elem,item,options){var html=getPrimaryMediaInfoHtml(item,options);elem.innerHTML=html,afterFill(elem,item,options)}function fillSecondaryMediaInfo(elem,item,options){var html=getSecondaryMediaInfoHtml(item,options);elem.innerHTML=html,afterFill(elem,item,options)}function afterFill(elem,item,options){if(!1!==options.endsAt){var endsAtElem=elem.querySelector(".endsAt");endsAtElem&&dynamicEndTime(endsAtElem,item)}var lnkChannel=elem.querySelector(".lnkChannel");lnkChannel&&lnkChannel.addEventListener("click",onChannelLinkClick)}function onChannelLinkClick(e){var channelId=this.getAttribute("data-id"),serverId=this.getAttribute("data-serverid");return appRouter.showItem(channelId,serverId),e.preventDefault(),!1}function getPrimaryMediaInfoHtml(item,options){return options=options||{},null==options.interactive&&(options.interactive=!1),getMediaInfoHtml(item,options)}function getSecondaryMediaInfoHtml(item,options){return options=options||{},null==options.interactive&&(options.interactive=!1),"Program"===item.Type?getProgramInfoHtml(item,options):""}function getResolutionText(i){var width=i.Width,height=i.Height;if(width&&height){if(width>=3800||height>=2e3)return"4K";if(width>=2500||height>=1400)return i.IsInterlaced?"1440i":"1440P";if(width>=1800||height>=1e3)return i.IsInterlaced?"1080i":"1080P";if(width>=1200||height>=700)return i.IsInterlaced?"720i":"720P";if(width>=700||height>=400)return i.IsInterlaced?"480i":"480P"}return null}function getAudioStreamForDisplay(item){if(!item.MediaSources)return null;var mediaSource=item.MediaSources[0];return mediaSource?(mediaSource.MediaStreams||[]).filter(function(i){return"Audio"===i.Type&&(i.Index===mediaSource.DefaultAudioStreamIndex||null==mediaSource.DefaultAudioStreamIndex)})[0]:null}function getMediaInfoStats(item,options){options=options||{};var list=[],mediaSource=(item.MediaSources||[])[0]||{},videoStream=(mediaSource.MediaStreams||[]).filter(function(i){return"Video"===i.Type})[0]||{},audioStream=getAudioStreamForDisplay(item)||{};"Dvd"===item.VideoType&&list.push({type:"mediainfo",text:"Dvd"}),"BluRay"===item.VideoType&&list.push({type:"mediainfo",text:"BluRay"});var resolutionText=getResolutionText(videoStream);resolutionText&&list.push({type:"mediainfo",text:resolutionText}),videoStream.Codec&&list.push({type:"mediainfo",text:videoStream.Codec});var channelText,channels=audioStream.Channels;8===channels?channelText="7.1":7===channels?channelText="6.1":6===channels?channelText="5.1":2===channels&&(channelText="2.0"),channelText&&list.push({type:"mediainfo",text:channelText});var audioCodec=(audioStream.Codec||"").toLowerCase();if("dca"!==audioCodec&&"dts"!==audioCodec||!audioStream.Profile?audioStream.Codec&&list.push({type:"mediainfo",text:audioStream.Codec}):list.push({type:"mediainfo",text:audioStream.Profile}),item.DateCreated&&itemHelper.enableDateAddedDisplay(item)){var dateCreated=datetime.parseISO8601Date(item.DateCreated);list.push({type:"added",text:globalize.translate("sharedcomponents#AddedOnValue",datetime.toLocaleDateString(dateCreated)+" "+datetime.getDisplayTime(dateCreated))})}return list}return{getMediaInfoHtml:getPrimaryMediaInfoHtml,fill:fillPrimaryMediaInfo,getEndsAt:getEndsAt,getEndsAtFromPosition:getEndsAtFromPosition,getPrimaryMediaInfoHtml:getPrimaryMediaInfoHtml,getSecondaryMediaInfoHtml:getSecondaryMediaInfoHtml,fillPrimaryMediaInfo:fillPrimaryMediaInfo,fillSecondaryMediaInfo:fillSecondaryMediaInfo,getMediaInfoStats:getMediaInfoStats,getResolutionText:getResolutionText}}); \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/howlerjs/dist/howler.min.js b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/howlerjs/dist/howler.min.js index 68102b31cb..46a59dbe42 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/bower_components/howlerjs/dist/howler.min.js +++ b/MediaBrowser.WebDashboard/dashboard-ui/bower_components/howlerjs/dist/howler.min.js @@ -1,4 +1,4 @@ -/*! howler.js v2.0.9 | (c) 2013-2018, James Simpson of GoldFire Studios | MIT License | howlerjs.com */ -!function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.mobileAutoEnable=!0,e._setup(),e},volume:function(e){var t=this||n;if(e=parseFloat(e),t.ctx||_(),void 0!==e&&e>=0&&e<=1){if(t._volume=e,t._muted)return t;t.usingWebAudio&&t.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var o=0;o=0;t--)e._howls[t].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"running":"running",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var t=new Audio;void 0===t.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var t=new Audio;t.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,t=null;try{t="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!t||"function"!=typeof t.canPlayType)return e;var o=t.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator&&e._navigator.userAgent.match(/OPR\/([0-6].)/g),a=r&&parseInt(r[0].split("/")[1],10)<33;return e._codecs={mp3:!(a||!o&&!t.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!o,opus:!!t.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!t.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),aac:!!t.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!t.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(t.canPlayType("audio/x-m4a;")||t.canPlayType("audio/m4a;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(t.canPlayType("audio/x-mp4;")||t.canPlayType("audio/mp4;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),webm:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),dolby:!!t.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(t.canPlayType("audio/x-flac;")||t.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_enableMobileAudio:function(){var e=this||n,t=/iPhone|iPad|iPod|Android|BlackBerry|BB10|Silk|Mobi/i.test(e._navigator&&e._navigator.userAgent),o=!!("ontouchend"in window||e._navigator&&e._navigator.maxTouchPoints>0||e._navigator&&e._navigator.msMaxTouchPoints>0);if(!e._mobileEnabled&&e.ctx&&(t||o)){e._mobileEnabled=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var r=function(){n._autoResume();var t=e.ctx.createBufferSource();t.buffer=e._scratchBuffer,t.connect(e.ctx.destination),void 0===t.start?t.noteOn(0):t.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),t.onended=function(){t.disconnect(0),e._mobileEnabled=!0,e.mobileAutoEnable=!1,document.removeEventListener("touchstart",r,!0),document.removeEventListener("touchend",r,!0)}};return document.addEventListener("touchstart",r,!0),document.addEventListener("touchend",r,!0),e}},_autoSuspend:function(){var e=this;if(e.autoSuspend&&e.ctx&&void 0!==e.ctx.suspend&&n.usingWebAudio){for(var t=0;t0?i._seek:o._sprite[e][0]/1e3),s=Math.max(0,(o._sprite[e][0]+o._sprite[e][1])/1e3-_),l=1e3*s/Math.abs(i._rate);i._paused=!1,i._ended=!1,i._sprite=e,i._seek=_,i._start=o._sprite[e][0]/1e3,i._stop=(o._sprite[e][0]+o._sprite[e][1])/1e3,i._loop=!(!i._loop&&!o._sprite[e][2]);var c=i._node;if(o._webAudio){var f=function(){o._refreshBuffer(i);var e=i._muted||o._muted?0:i._volume;c.gain.setValueAtTime(e,n.ctx.currentTime),i._playStart=n.ctx.currentTime,void 0===c.bufferSource.start?i._loop?c.bufferSource.noteGrainOn(0,_,86400):c.bufferSource.noteGrainOn(0,_,s):i._loop?c.bufferSource.start(0,_,86400):c.bufferSource.start(0,_,s),l!==1/0&&(o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l)),t||setTimeout(function(){o._emit("play",i._id)},0)};"running"===n.state?f():(o.once("resume",f),o._clearTimer(i._id))}else{var p=function(){c.currentTime=_,c.muted=i._muted||o._muted||n._muted||c.muted,c.volume=i._volume*n.volume(),c.playbackRate=i._rate;try{var r=c.play();if("undefined"!=typeof Promise&&r instanceof Promise){o._playLock=!0;var a=function(){o._playLock=!1,t||o._emit("play",i._id)};r.then(a,a)}else t||o._emit("play",i._id);if(c.paused)return void o._emit("playerror",i._id,"Playback was unable to start. This is most commonly an issue on mobile devices where playback was not within a user interaction.");"__default"!==e?o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l):(o._endTimers[i._id]=function(){o._ended(i),c.removeEventListener("ended",o._endTimers[i._id],!1)},c.addEventListener("ended",o._endTimers[i._id],!1))}catch(e){o._emit("playerror",i._id,e)}},m=window&&window.ejecta||!c.readyState&&n._navigator.isCocoonJS;if(c.readyState>=3||m)p();else{var v=function(){p(),c.removeEventListener(n._canPlayEvent,v,!1)};c.addEventListener(n._canPlayEvent,v,!1),o._clearTimer(i._id)}}return i._id},pause:function(e){var n=this;if("loaded"!==n._state||n._playLock)return n._queue.push({event:"pause",action:function(){n.pause(e)}}),n;for(var t=n._getSoundIds(e),o=0;o=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else r.length>=2&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var a;if(!(void 0!==e&&e>=0&&e<=1))return a=t?o._soundById(t):o._sounds[0],a?a._volume:0;if("loaded"!==o._state)return o._queue.push({event:"volume",action:function(){o.volume.apply(o,r)}}),o;void 0===t&&(o._volume=e),t=o._getSoundIds(t);for(var u=0;u0?o/_:o),l=Date.now();e._fadeTo=t,e._interval=setInterval(function(){var r=(Date.now()-l)/o;l=Date.now(),i+=d*r,i=Math.max(0,i),i=Math.min(1,i),i=Math.round(100*i)/100,u._webAudio?e._volume=i:u.volume(i,e._id,!0),a&&(u._volume=i),(tn&&i>=t)&&(clearInterval(e._interval),e._interval=null,e._fadeTo=null,u.volume(t,e._id),u._emit("fade",e._id))},s)},_stopFade:function(e){var t=this,o=t._soundById(e);return o&&o._interval&&(t._webAudio&&o._node.gain.cancelScheduledValues(n.ctx.currentTime),clearInterval(o._interval),o._interval=null,t.volume(o._fadeTo,e),o._fadeTo=null,t._emit("fade",e)),t},loop:function(){var e,n,t,o=this,r=arguments;if(0===r.length)return o._loop;if(1===r.length){if("boolean"!=typeof r[0])return!!(t=o._soundById(parseInt(r[0],10)))&&t._loop;e=r[0],o._loop=e}else 2===r.length&&(e=r[0],n=parseInt(r[1],10));for(var a=o._getSoundIds(n),u=0;u=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var i;if("number"!=typeof e)return i=o._soundById(t),i?i._rate:o._rate;if("loaded"!==o._state)return o._queue.push({event:"rate",action:function(){o.rate.apply(o,r)}}),o;void 0===t&&(o._rate=e),t=o._getSoundIds(t);for(var d=0;d=0?t=parseInt(r[0],10):o._sounds.length&&(t=o._sounds[0]._id,e=parseFloat(r[0]))}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));if(void 0===t)return o;if("loaded"!==o._state)return o._queue.push({event:"seek",action:function(){o.seek.apply(o,r)}}),o;var i=o._soundById(t);if(i){if(!("number"==typeof e&&e>=0)){if(o._webAudio){var d=o.playing(t)?n.ctx.currentTime-i._playStart:0,_=i._rateSeek?i._rateSeek-i._seek:0;return i._seek+(_+d*Math.abs(i._rate))}return i._node.currentTime}var s=o.playing(t);if(s&&o.pause(t,!0),i._seek=e,i._ended=!1,o._clearTimer(t),s&&o.play(t,!0),!o._webAudio&&i._node&&(i._node.currentTime=e),s&&!o._webAudio){var l=function(){o._playLock?setTimeout(l,0):o._emit("seek",t)};setTimeout(l,0)}else o._emit("seek",t)}return o},playing:function(e){var n=this;if("number"==typeof e){var t=n._soundById(e);return!!t&&!t._paused}for(var o=0;o=0&&n._howls.splice(a,1)}var u=!0;for(o=0;o=0;a--)r[a].id&&r[a].id!==n&&"load"!==e||(setTimeout(function(e){e.call(this,n,t)}.bind(o,r[a].fn),0),r[a].once&&o.off(e,r[a].fn,r[a].id));return o._loadQueue(e),o},_loadQueue:function(e){var n=this;if(n._queue.length>0){var t=n._queue[0];t.event===e&&(n._queue.shift(),n._loadQueue()),e||t.action()}return n},_ended:function(e){var t=this,o=e._sprite;if(!t._webAudio&&e._node&&!e._node.paused&&!e._node.ended&&e._node.currentTime=0;o--){if(t<=n)return;e._sounds[o]._ended&&(e._webAudio&&e._sounds[o]._node&&e._sounds[o]._node.disconnect(0),e._sounds.splice(o,1),t--)}}},_getSoundIds:function(e){var n=this;if(void 0===e){for(var t=[],o=0;o0&&(r[t._src]=e,d(t,e))},function(){t._emit("loaderror",null,"Decoding audio data failed.")})},d=function(e,n){n&&!e._duration&&(e._duration=n.duration),0===Object.keys(e._sprite).length&&(e._sprite={__default:[0,1e3*e._duration]}),"loaded"!==e._state&&(e._state="loaded",e._emit("load"),e._loadQueue())},_=function(){try{"undefined"!=typeof AudioContext?n.ctx=new AudioContext:"undefined"!=typeof webkitAudioContext?n.ctx=new webkitAudioContext:n.usingWebAudio=!1}catch(e){n.usingWebAudio=!1}var e=/iP(hone|od|ad)/.test(n._navigator&&n._navigator.platform),t=n._navigator&&n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),o=t?parseInt(t[1],10):null;if(e&&o&&o<9){var r=/safari/.test(n._navigator&&n._navigator.userAgent.toLowerCase());(n._navigator&&n._navigator.standalone&&!r||n._navigator&&!n._navigator.standalone&&!r)&&(n.usingWebAudio=!1)}n.usingWebAudio&&(n.masterGain=void 0===n.ctx.createGain?n.ctx.createGainNode():n.ctx.createGain(),n.masterGain.gain.setValueAtTime(n._muted?0:1,n.ctx.currentTime),n.masterGain.connect(n.ctx.destination)),n._setup()};"function"==typeof define&&define.amd&&define([],function(){return{Howler:n,Howl:t}}),"undefined"!=typeof exports&&(exports.Howler=n,exports.Howl=t),"undefined"!=typeof window?(window.HowlerGlobal=e,window.Howler=n,window.Howl=t,window.Sound=o):"undefined"!=typeof global&&(global.HowlerGlobal=e,global.Howler=n,global.Howl=t,global.Sound=o)}(); +/*! howler.js v2.0.12 | (c) 2013-2018, James Simpson of GoldFire Studios | MIT License | howlerjs.com */ +!function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.mobileAutoEnable=!0,e._setup(),e},volume:function(e){var t=this||n;if(e=parseFloat(e),t.ctx||_(),void 0!==e&&e>=0&&e<=1){if(t._volume=e,t._muted)return t;t.usingWebAudio&&t.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var o=0;o=0;t--)e._howls[t].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"running":"running",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var t=new Audio;void 0===t.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var t=new Audio;t.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,t=null;try{t="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!t||"function"!=typeof t.canPlayType)return e;var o=t.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator&&e._navigator.userAgent.match(/OPR\/([0-6].)/g),a=r&&parseInt(r[0].split("/")[1],10)<33;return e._codecs={mp3:!(a||!o&&!t.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!o,opus:!!t.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!t.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),aac:!!t.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!t.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(t.canPlayType("audio/x-m4a;")||t.canPlayType("audio/m4a;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(t.canPlayType("audio/x-mp4;")||t.canPlayType("audio/mp4;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),webm:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),dolby:!!t.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(t.canPlayType("audio/x-flac;")||t.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_enableMobileAudio:function(){var e=this||n,t=/iPhone|iPad|iPod|Android|BlackBerry|BB10|Silk|Mobi/i.test(e._navigator&&e._navigator.userAgent),o=!!("ontouchend"in window||e._navigator&&e._navigator.maxTouchPoints>0||e._navigator&&e._navigator.msMaxTouchPoints>0);if(!e._mobileEnabled&&e.ctx&&(t||o)){e._mobileEnabled=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var r=function(){n._autoResume();var t=e.ctx.createBufferSource();t.buffer=e._scratchBuffer,t.connect(e.ctx.destination),void 0===t.start?t.noteOn(0):t.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),t.onended=function(){t.disconnect(0),e._mobileEnabled=!0,e.mobileAutoEnable=!1,document.removeEventListener("touchstart",r,!0),document.removeEventListener("touchend",r,!0)}};return document.addEventListener("touchstart",r,!0),document.addEventListener("touchend",r,!0),e}},_autoSuspend:function(){var e=this;if(e.autoSuspend&&e.ctx&&void 0!==e.ctx.suspend&&n.usingWebAudio){for(var t=0;t0?i._seek:o._sprite[e][0]/1e3),s=Math.max(0,(o._sprite[e][0]+o._sprite[e][1])/1e3-_),l=1e3*s/Math.abs(i._rate);i._paused=!1,i._ended=!1,i._sprite=e,i._seek=_,i._start=o._sprite[e][0]/1e3,i._stop=(o._sprite[e][0]+o._sprite[e][1])/1e3,i._loop=!(!i._loop&&!o._sprite[e][2]);var c=i._node;if(o._webAudio){var f=function(){o._refreshBuffer(i);var e=i._muted||o._muted?0:i._volume;c.gain.setValueAtTime(e,n.ctx.currentTime),i._playStart=n.ctx.currentTime,void 0===c.bufferSource.start?i._loop?c.bufferSource.noteGrainOn(0,_,86400):c.bufferSource.noteGrainOn(0,_,s):i._loop?c.bufferSource.start(0,_,86400):c.bufferSource.start(0,_,s),l!==1/0&&(o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l)),t||setTimeout(function(){o._emit("play",i._id)},0)};"running"===n.state?f():(o.once("resume",f),o._clearTimer(i._id))}else{var p=function(){c.currentTime=_,c.muted=i._muted||o._muted||n._muted||c.muted,c.volume=i._volume*n.volume(),c.playbackRate=i._rate;try{var r=c.play();if("undefined"!=typeof Promise&&r instanceof Promise){o._playLock=!0;var a=function(){o._playLock=!1,t||o._emit("play",i._id)};r.then(a,a)}else t||o._emit("play",i._id);if(c.playbackRate=i._rate,c.paused)return void o._emit("playerror",i._id,"Playback was unable to start. This is most commonly an issue on mobile devices where playback was not within a user interaction.");"__default"!==e||i._loop?o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l):(o._endTimers[i._id]=function(){o._ended(i),c.removeEventListener("ended",o._endTimers[i._id],!1)},c.addEventListener("ended",o._endTimers[i._id],!1))}catch(e){o._emit("playerror",i._id,e)}},m=window&&window.ejecta||!c.readyState&&n._navigator.isCocoonJS;if(c.readyState>=3||m)p();else{var v=function(){p(),c.removeEventListener(n._canPlayEvent,v,!1)};c.addEventListener(n._canPlayEvent,v,!1),o._clearTimer(i._id)}}return i._id},pause:function(e){var n=this;if("loaded"!==n._state||n._playLock)return n._queue.push({event:"pause",action:function(){n.pause(e)}}),n;for(var t=n._getSoundIds(e),o=0;o=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else r.length>=2&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var a;if(!(void 0!==e&&e>=0&&e<=1))return a=t?o._soundById(t):o._sounds[0],a?a._volume:0;if("loaded"!==o._state)return o._queue.push({event:"volume",action:function(){o.volume.apply(o,r)}}),o;void 0===t&&(o._volume=e),t=o._getSoundIds(t);for(var u=0;u0?o/_:o),l=Date.now();e._fadeTo=t,e._interval=setInterval(function(){var r=(Date.now()-l)/o;l=Date.now(),i+=d*r,i=Math.max(0,i),i=Math.min(1,i),i=Math.round(100*i)/100,u._webAudio?e._volume=i:u.volume(i,e._id,!0),a&&(u._volume=i),(tn&&i>=t)&&(clearInterval(e._interval),e._interval=null,e._fadeTo=null,u.volume(t,e._id),u._emit("fade",e._id))},s)},_stopFade:function(e){var t=this,o=t._soundById(e);return o&&o._interval&&(t._webAudio&&o._node.gain.cancelScheduledValues(n.ctx.currentTime),clearInterval(o._interval),o._interval=null,t.volume(o._fadeTo,e),o._fadeTo=null,t._emit("fade",e)),t},loop:function(){var e,n,t,o=this,r=arguments;if(0===r.length)return o._loop;if(1===r.length){if("boolean"!=typeof r[0])return!!(t=o._soundById(parseInt(r[0],10)))&&t._loop;e=r[0],o._loop=e}else 2===r.length&&(e=r[0],n=parseInt(r[1],10));for(var a=o._getSoundIds(n),u=0;u=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var i;if("number"!=typeof e)return i=o._soundById(t),i?i._rate:o._rate;if("loaded"!==o._state)return o._queue.push({event:"rate",action:function(){o.rate.apply(o,r)}}),o;void 0===t&&(o._rate=e),t=o._getSoundIds(t);for(var d=0;d=0?t=parseInt(r[0],10):o._sounds.length&&(t=o._sounds[0]._id,e=parseFloat(r[0]))}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));if(void 0===t)return o;if("loaded"!==o._state)return o._queue.push({event:"seek",action:function(){o.seek.apply(o,r)}}),o;var i=o._soundById(t);if(i){if(!("number"==typeof e&&e>=0)){if(o._webAudio){var d=o.playing(t)?n.ctx.currentTime-i._playStart:0,_=i._rateSeek?i._rateSeek-i._seek:0;return i._seek+(_+d*Math.abs(i._rate))}return i._node.currentTime}var s=o.playing(t);if(s&&o.pause(t,!0),i._seek=e,i._ended=!1,o._clearTimer(t),s&&o.play(t,!0),!o._webAudio&&i._node&&(i._node.currentTime=e),s&&!o._webAudio){var l=function(){o._playLock?setTimeout(l,0):o._emit("seek",t)};setTimeout(l,0)}else o._emit("seek",t)}return o},playing:function(e){var n=this;if("number"==typeof e){var t=n._soundById(e);return!!t&&!t._paused}for(var o=0;o=0&&n._howls.splice(a,1)}var u=!0;for(o=0;o=0;a--)r[a].id&&r[a].id!==n&&"load"!==e||(setTimeout(function(e){e.call(this,n,t)}.bind(o,r[a].fn),0),r[a].once&&o.off(e,r[a].fn,r[a].id));return o._loadQueue(e),o},_loadQueue:function(e){var n=this;if(n._queue.length>0){var t=n._queue[0];t.event===e&&(n._queue.shift(),n._loadQueue()),e||t.action()}return n},_ended:function(e){var t=this,o=e._sprite;if(!t._webAudio&&e._node&&!e._node.paused&&!e._node.ended&&e._node.currentTime=0;o--){if(t<=n)return;e._sounds[o]._ended&&(e._webAudio&&e._sounds[o]._node&&e._sounds[o]._node.disconnect(0),e._sounds.splice(o,1),t--)}}},_getSoundIds:function(e){var n=this;if(void 0===e){for(var t=[],o=0;o0&&(r[t._src]=e,d(t,e))},function(){t._emit("loaderror",null,"Decoding audio data failed.")})},d=function(e,n){n&&!e._duration&&(e._duration=n.duration),0===Object.keys(e._sprite).length&&(e._sprite={__default:[0,1e3*e._duration]}),"loaded"!==e._state&&(e._state="loaded",e._emit("load"),e._loadQueue())},_=function(){try{"undefined"!=typeof AudioContext?n.ctx=new AudioContext:"undefined"!=typeof webkitAudioContext?n.ctx=new webkitAudioContext:n.usingWebAudio=!1}catch(e){n.usingWebAudio=!1}var e=/iP(hone|od|ad)/.test(n._navigator&&n._navigator.platform),t=n._navigator&&n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),o=t?parseInt(t[1],10):null;if(e&&o&&o<9){var r=/safari/.test(n._navigator&&n._navigator.userAgent.toLowerCase());(n._navigator&&n._navigator.standalone&&!r||n._navigator&&!n._navigator.standalone&&!r)&&(n.usingWebAudio=!1)}n.usingWebAudio&&(n.masterGain=void 0===n.ctx.createGain?n.ctx.createGainNode():n.ctx.createGain(),n.masterGain.gain.setValueAtTime(n._muted?0:1,n.ctx.currentTime),n.masterGain.connect(n.ctx.destination)),n._setup()};"function"==typeof define&&define.amd&&define([],function(){return{Howler:n,Howl:t}}),"undefined"!=typeof exports&&(exports.Howler=n,exports.Howl=t),"undefined"!=typeof window?(window.HowlerGlobal=e,window.Howler=n,window.Howl=t,window.Sound=o):"undefined"!=typeof global&&(global.HowlerGlobal=e,global.Howler=n,global.Howl=t,global.Sound=o)}(); /*! Spatial Plugin */ -!function(){"use strict";HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(n){var e=this;if(!e.ctx||!e.ctx.listener)return e;for(var t=e._howls.length-1;t>=0;t--)e._howls[t].stereo(n);return e},HowlerGlobal.prototype.pos=function(n,e,t){var o=this;return o.ctx&&o.ctx.listener?(e="number"!=typeof e?o._pos[1]:e,t="number"!=typeof t?o._pos[2]:t,"number"!=typeof n?o._pos:(o._pos=[n,e,t],o.ctx.listener.setPosition(o._pos[0],o._pos[1],o._pos[2]),o)):o},HowlerGlobal.prototype.orientation=function(n,e,t,o,r,a){var i=this;if(!i.ctx||!i.ctx.listener)return i;var p=i._orientation;return e="number"!=typeof e?p[1]:e,t="number"!=typeof t?p[2]:t,o="number"!=typeof o?p[3]:o,r="number"!=typeof r?p[4]:r,a="number"!=typeof a?p[5]:a,"number"!=typeof n?p:(i._orientation=[n,e,t,o,r,a],i.ctx.listener.setOrientation(n,e,t,o,r,a),i)},Howl.prototype.init=function(n){return function(e){var t=this;return t._orientation=e.orientation||[1,0,0],t._stereo=e.stereo||null,t._pos=e.pos||null,t._pannerAttr={coneInnerAngle:void 0!==e.coneInnerAngle?e.coneInnerAngle:360,coneOuterAngle:void 0!==e.coneOuterAngle?e.coneOuterAngle:360,coneOuterGain:void 0!==e.coneOuterGain?e.coneOuterGain:0,distanceModel:void 0!==e.distanceModel?e.distanceModel:"inverse",maxDistance:void 0!==e.maxDistance?e.maxDistance:1e4,panningModel:void 0!==e.panningModel?e.panningModel:"HRTF",refDistance:void 0!==e.refDistance?e.refDistance:1,rolloffFactor:void 0!==e.rolloffFactor?e.rolloffFactor:1},t._onstereo=e.onstereo?[{fn:e.onstereo}]:[],t._onpos=e.onpos?[{fn:e.onpos}]:[],t._onorientation=e.onorientation?[{fn:e.onorientation}]:[],n.call(this,e)}}(Howl.prototype.init),Howl.prototype.stereo=function(e,t){var o=this;if(!o._webAudio)return o;if("loaded"!==o._state)return o._queue.push({event:"stereo",action:function(){o.stereo(e,t)}}),o;var r=void 0===Howler.ctx.createStereoPanner?"spatial":"stereo";if(void 0===t){if("number"!=typeof e)return o._stereo;o._stereo=e,o._pos=[e,0,0]}for(var a=o._getSoundIds(t),i=0;i=0;t--)n._howls[t].stereo(e);return n},HowlerGlobal.prototype.pos=function(e,n,t){var r=this;return r.ctx&&r.ctx.listener?(n="number"!=typeof n?r._pos[1]:n,t="number"!=typeof t?r._pos[2]:t,"number"!=typeof e?r._pos:(r._pos=[e,n,t],void 0!==r.ctx.listener.positionX?(r.ctx.listener.positionX.setTargetAtTime(r._pos[0],Howler.ctx.currentTime,.1),r.ctx.listener.positionY.setTargetAtTime(r._pos[1],Howler.ctx.currentTime,.1),r.ctx.listener.positionZ.setTargetAtTime(r._pos[2],Howler.ctx.currentTime,.1)):r.ctx.listener.setPosition(r._pos[0],r._pos[1],r._pos[2]),r)):r},HowlerGlobal.prototype.orientation=function(e,n,t,r,o,i){var a=this;if(!a.ctx||!a.ctx.listener)return a;var p=a._orientation;return n="number"!=typeof n?p[1]:n,t="number"!=typeof t?p[2]:t,r="number"!=typeof r?p[3]:r,o="number"!=typeof o?p[4]:o,i="number"!=typeof i?p[5]:i,"number"!=typeof e?p:(a._orientation=[e,n,t,r,o,i],void 0!==a.ctx.listener.forwardX?(a.ctx.listener.forwardX.setTargetAtTime(e,Howler.ctx.currentTime,.1),a.ctx.listener.forwardY.setTargetAtTime(n,Howler.ctx.currentTime,.1),a.ctx.listener.forwardZ.setTargetAtTime(t,Howler.ctx.currentTime,.1),a.ctx.listener.upX.setTargetAtTime(e,Howler.ctx.currentTime,.1),a.ctx.listener.upY.setTargetAtTime(n,Howler.ctx.currentTime,.1),a.ctx.listener.upZ.setTargetAtTime(t,Howler.ctx.currentTime,.1)):a.ctx.listener.setOrientation(e,n,t,r,o,i),a)},Howl.prototype.init=function(e){return function(n){var t=this;return t._orientation=n.orientation||[1,0,0],t._stereo=n.stereo||null,t._pos=n.pos||null,t._pannerAttr={coneInnerAngle:void 0!==n.coneInnerAngle?n.coneInnerAngle:360,coneOuterAngle:void 0!==n.coneOuterAngle?n.coneOuterAngle:360,coneOuterGain:void 0!==n.coneOuterGain?n.coneOuterGain:0,distanceModel:void 0!==n.distanceModel?n.distanceModel:"inverse",maxDistance:void 0!==n.maxDistance?n.maxDistance:1e4,panningModel:void 0!==n.panningModel?n.panningModel:"HRTF",refDistance:void 0!==n.refDistance?n.refDistance:1,rolloffFactor:void 0!==n.rolloffFactor?n.rolloffFactor:1},t._onstereo=n.onstereo?[{fn:n.onstereo}]:[],t._onpos=n.onpos?[{fn:n.onpos}]:[],t._onorientation=n.onorientation?[{fn:n.onorientation}]:[],e.call(this,n)}}(Howl.prototype.init),Howl.prototype.stereo=function(n,t){var r=this;if(!r._webAudio)return r;if("loaded"!==r._state)return r._queue.push({event:"stereo",action:function(){r.stereo(n,t)}}),r;var o=void 0===Howler.ctx.createStereoPanner?"spatial":"stereo";if(void 0===t){if("number"!=typeof n)return r._stereo;r._stereo=n,r._pos=[n,0,0]}for(var i=r._getSoundIds(t),a=0;a=1920?10:screenWidth>=1440?8:6,enableScrollX()&&(options.Limit=20));var promise;return"MusicArtist"===section.types?promise=ApiClient.getArtists(userId,options):(options.IncludeItemTypes=section.types,promise=ApiClient.getItems(userId,options)),promise.then(function(result){var html="";if(result.Items.length){if(html+='
',!layoutManager.tv&&options.Limit&&result.Items.length>=options.Limit){html+='',html+='

',html+=globalize.translate(section.name),html+="

",html+='',html+="
"}else html+='

'+globalize.translate(section.name)+"

";if(html+="
",enableScrollX()){var scrollXClass="scrollX hiddenScrollX";layoutManager.tv&&(scrollXClass+=" smoothScrollX"),html+='
'}else html+='
';var supportsImageAnalysis=appHost.supports("imageanalysis"),cardLayout=(appHost.preferVisualCards||supportsImageAnalysis)&§ion.autoCardLayout&§ion.showTitle;cardLayout=!1,html+=cardBuilder.getCardsHtml(result.Items,{preferThumb:section.preferThumb,shape:section.shape,centerText:section.centerText&&!cardLayout,overlayText:!1!==section.overlayText,showTitle:section.showTitle,showParentTitle:section.showParentTitle,scalable:!0,coverImage:section.coverImage,overlayPlayButton:section.overlayPlayButton,overlayMoreButton:section.overlayMoreButton&&!cardLayout,action:section.action,allowBottomPadding:!enableScrollX(),cardLayout:cardLayout,vibrant:supportsImageAnalysis&&cardLayout}),html+="
"}elem.innerHTML=html,imageLoader.lazyChildren(elem)})}function loadSections(page,userId,topParentId,types){loading.show();var sections=getSections(),sectionid=getParameterByName("sectionid");sectionid&&(sections=sections.filter(function(s){return s.id===sectionid})),types&&(sections=sections.filter(function(s){return-1!==types.indexOf(s.id)}));var i,length,elem=page.querySelector(".favoriteSections");if(!elem.innerHTML){var html="";for(i=0,length=sections.length;i
';elem.innerHTML=html}var promises=[];for(i=0,length=sections.length;i=1920?10:screenWidth>=1440?8:6,enableScrollX()&&(options.Limit=20));var promise;return"MusicArtist"===section.types?promise=ApiClient.getArtists(userId,options):(options.IncludeItemTypes=section.types,promise=ApiClient.getItems(userId,options)),promise.then(function(result){var html="";if(result.Items.length){if(html+='
',!layoutManager.tv&&options.Limit&&result.Items.length>=options.Limit){html+='',html+='

',html+=globalize.translate(section.name),html+="

",html+='',html+="
"}else html+='

'+globalize.translate(section.name)+"

";if(html+="
",enableScrollX()){var scrollXClass="scrollX hiddenScrollX";layoutManager.tv&&(scrollXClass+=" smoothScrollX"),html+='
'}else html+='
';var supportsImageAnalysis=appHost.supports("imageanalysis"),cardLayout=(appHost.preferVisualCards||supportsImageAnalysis)&§ion.autoCardLayout&§ion.showTitle;cardLayout=!1,html+=cardBuilder.getCardsHtml(result.Items,{preferThumb:section.preferThumb,shape:section.shape,centerText:section.centerText&&!cardLayout,overlayText:!1!==section.overlayText,showTitle:section.showTitle,showParentTitle:section.showParentTitle,scalable:!0,coverImage:section.coverImage,overlayPlayButton:section.overlayPlayButton,overlayMoreButton:section.overlayMoreButton&&!cardLayout,action:section.action,allowBottomPadding:!enableScrollX(),cardLayout:cardLayout,vibrant:supportsImageAnalysis&&cardLayout}),html+="
"}elem.innerHTML=html,imageLoader.lazyChildren(elem)})}function loadSections(page,userId,topParentId,types){loading.show();var sections=getSections(),sectionid=getParameterByName("sectionid");sectionid&&(sections=sections.filter(function(s){return s.id===sectionid})),types&&(sections=sections.filter(function(s){return-1!==types.indexOf(s.id)}));var i,length,elem=page.querySelector(".favoriteSections");if(!elem.innerHTML){var html="";for(i=0,length=sections.length;i
';elem.innerHTML=html}var promises=[];for(i=0,length=sections.length;i"+culture.DisplayName+""}select.innerHTML=html}function populateLanguagesIntoList(element,languages){for(var html="",i=0,length=languages.length;i'+culture.DisplayName+""}element.innerHTML=html}function populateCountries(select){return ApiClient.getCountries().then(function(allCountries){var html="";html+="";for(var i=0,length=allCountries.length;i"+culture.DisplayName+""}select.innerHTML=html})}function populateRefreshInterval(select){var html="";html+="",html+=[30,60,90].map(function(val){return""}).join(""),select.innerHTML=html}function renderMetadataReaders(page,plugins){var html="",elem=page.querySelector(".metadataReaders");if(plugins.length<1)return elem.innerHTML="",elem.classList.add("hide"),!1;html+='

'+globalize.translate("LabelMetadataReaders")+"

",html+='
';for(var i=0,length=plugins.length;i',html+='live_tv',html+='
',html+='

',html+=plugin.Name,html+="

",html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}return html+="
",html+='
'+globalize.translate("LabelMetadataReadersHelp")+"
",plugins.length<2?elem.classList.add("hide"):elem.classList.remove("hide"),elem.innerHTML=html,!0}function renderMetadataSavers(page,metadataSavers){var html="",elem=page.querySelector(".metadataSavers");if(!metadataSavers.length)return elem.innerHTML="",elem.classList.add("hide"),!1;html+='

'+globalize.translate("LabelMetadataSavers")+"

",html+='
';for(var i=0,length=metadataSavers.length;i"+plugin.Name+""}return html+="
",html+='
'+globalize.translate("LabelMetadataSaversHelp")+"
",elem.innerHTML=html,elem.classList.remove("hide"),!0}function getMetadataFetchersForTypeHtml(availableTypeOptions,libraryOptionsForType){var html="",plugins=availableTypeOptions.MetadataFetchers;if(plugins=getOrderedPlugins(plugins,libraryOptionsForType.MetadataFetcherOrder||[]),!plugins.length)return html;html+='
',html+='

'+globalize.translate("LabelTypeMetadataDownloaders",availableTypeOptions.Type)+"

",html+='
';for(var i=0,length=plugins.length;i';var isChecked=libraryOptionsForType.MetadataFetchers?-1!==libraryOptionsForType.MetadataFetchers.indexOf(plugin.Name):plugin.DefaultEnabled,checkedHtml=isChecked?' checked="checked"':"";html+='",html+='
',html+='

',html+=plugin.Name,html+="

",html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}return html+="
",html+='
'+globalize.translate("LabelMetadataDownloadersHelp")+"
",html+="
"}function getTypeOptions(allOptions,type){for(var allTypeOptions=allOptions.TypeOptions||[],i=0,length=allTypeOptions.length;i",html+='
';for(var i=0,length=plugins.length;i';var isChecked=libraryOptions.DisabledSubtitleFetchers?-1===libraryOptions.DisabledSubtitleFetchers.indexOf(plugin.Name):plugin.DefaultEnabled,checkedHtml=isChecked?' checked="checked"':"";html+='",html+='
',html+='

',html+=plugin.Name,html+="

","Open Subtitles"===plugin.Name&&(html+='
',html+=globalize.translate("OpenSubtitleInstructions"),html+="
"),html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}html+="
",html+='
'+globalize.translate("SubtitleDownloadersHelp")+"
",elem.innerHTML=html}catch(err){alert(err)}}function getImageFetchersForTypeHtml(availableTypeOptions,libraryOptionsForType){var html="",plugins=availableTypeOptions.ImageFetchers;if(plugins=getOrderedPlugins(plugins,libraryOptionsForType.ImageFetcherOrder||[]),!plugins.length)return html;html+='
',html+='
',html+='

'+globalize.translate("HeaderTypeImageFetchers",availableTypeOptions.Type)+"

";var supportedImageTypes=availableTypeOptions.SupportedImageTypes||[];(supportedImageTypes.length>1||1===supportedImageTypes.length&&"Primary"!==supportedImageTypes[0])&&(html+=''),html+="
",html+='
';for(var i=0,length=plugins.length;i';var isChecked=libraryOptionsForType.ImageFetchers?-1!==libraryOptionsForType.ImageFetchers.indexOf(plugin.Name):plugin.DefaultEnabled,checkedHtml=isChecked?' checked="checked"':"";html+='",html+='
',html+='

',html+=plugin.Name,html+="

",html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}return html+="
",html+='
'+globalize.translate("LabelImageFetchersHelp")+"
",html+="
"}function renderImageFetchers(page,availableOptions,libraryOptions){for(var html="",elem=page.querySelector(".imageFetchers"),i=0,length=availableOptions.TypeOptions.length;ib?1:0}),plugins}function setLibraryOptions(parent,options){currentLibraryOptions=options,currentAvailableOptions=parent.availableOptions,parent.querySelector("#selectLanguage").value=options.PreferredMetadataLanguage||"",parent.querySelector("#selectCountry").value=options.MetadataCountryCode||"",parent.querySelector("#selectAutoRefreshInterval").value=options.AutomaticRefreshIntervalDays||"0",parent.querySelector("#txtSeasonZeroName").value=options.SeasonZeroDisplayName||"Specials",parent.querySelector(".chkEnablePhotos").checked=options.EnablePhotos,parent.querySelector(".chkEnableRealtimeMonitor").checked=options.EnableRealtimeMonitor,parent.querySelector(".chkExtractChaptersDuringLibraryScan").checked=options.ExtractChapterImagesDuringLibraryScan,parent.querySelector(".chkExtractChapterImages").checked=options.EnableChapterImageExtraction,parent.querySelector("#chkDownloadImagesInAdvance").checked=options.DownloadImagesInAdvance,parent.querySelector("#chkSaveLocal").checked=options.SaveLocalMetadata,parent.querySelector("#chkImportMissingEpisodes").checked=options.ImportMissingEpisodes,parent.querySelector(".chkAutomaticallyGroupSeries").checked=options.EnableAutomaticSeriesGrouping,parent.querySelector("#chkEnableEmbeddedTitles").checked=options.EnableEmbeddedTitles,parent.querySelector("#chkSkipIfGraphicalSubsPresent").checked=options.SkipSubtitlesIfEmbeddedSubtitlesPresent,parent.querySelector("#chkSaveSubtitlesLocally").checked=options.SaveSubtitlesWithMedia,parent.querySelector("#chkSkipIfAudioTrackPresent").checked=options.SkipSubtitlesIfAudioTrackMatches,parent.querySelector("#chkRequirePerfectMatch").checked=options.RequirePerfectSubtitleMatch,Array.prototype.forEach.call(parent.querySelectorAll(".chkMetadataSaver"),function(elem){elem.checked=options.MetadataSavers?-1!==options.MetadataSavers.indexOf(elem.getAttribute("data-pluginname")):"true"===elem.getAttribute("data-defaultenabled")}),Array.prototype.forEach.call(parent.querySelectorAll(".chkSubtitleLanguage"),function(elem){elem.checked=!!options.SubtitleDownloadLanguages&&-1!==options.SubtitleDownloadLanguages.indexOf(elem.getAttribute("data-lang"))}),renderMetadataReaders(parent,getOrderedPlugins(parent.availableOptions.MetadataReaders,options.LocalMetadataReaderOrder||[])),renderMetadataFetchers(parent,parent.availableOptions,options),renderImageFetchers(parent,parent.availableOptions,options),renderSubtitleFetchers(parent,parent.availableOptions,options)}var currentLibraryOptions,currentAvailableOptions;return{embed:embed,setContentType:setContentType,getLibraryOptions:getLibraryOptions,setLibraryOptions:setLibraryOptions,setAdvancedVisible:setAdvancedVisible}}); \ No newline at end of file +define(["globalize","dom","emby-checkbox","emby-select","emby-input"],function(globalize,dom){"use strict";function populateLanguages(parent){return ApiClient.getCultures().then(function(languages){populateLanguagesIntoSelect(parent.querySelector("#selectLanguage"),languages),populateLanguagesIntoList(parent.querySelector(".subtitleDownloadLanguages"),languages)})}function populateLanguagesIntoSelect(select,languages){var html="";html+="";for(var i=0,length=languages.length;i"+culture.DisplayName+""}select.innerHTML=html}function populateLanguagesIntoList(element,languages){for(var html="",i=0,length=languages.length;i'+culture.DisplayName+""}element.innerHTML=html}function populateCountries(select){return ApiClient.getCountries().then(function(allCountries){var html="";html+="";for(var i=0,length=allCountries.length;i"+culture.DisplayName+""}select.innerHTML=html})}function populateRefreshInterval(select){var html="";html+="",html+=[30,60,90].map(function(val){return""}).join(""),select.innerHTML=html}function renderMetadataReaders(page,plugins){var html="",elem=page.querySelector(".metadataReaders");if(plugins.length<1)return elem.innerHTML="",elem.classList.add("hide"),!1;html+='

'+globalize.translate("LabelMetadataReaders")+"

",html+='
';for(var i=0,length=plugins.length;i',html+='live_tv',html+='
',html+='

',html+=plugin.Name,html+="

",html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}return html+="
",html+='
'+globalize.translate("LabelMetadataReadersHelp")+"
",plugins.length<2?elem.classList.add("hide"):elem.classList.remove("hide"),elem.innerHTML=html,!0}function renderMetadataSavers(page,metadataSavers){var html="",elem=page.querySelector(".metadataSavers");if(!metadataSavers.length)return elem.innerHTML="",elem.classList.add("hide"),!1;html+='

'+globalize.translate("LabelMetadataSavers")+"

",html+='
';for(var i=0,length=metadataSavers.length;i"+plugin.Name+""}return html+="
",html+='
'+globalize.translate("LabelMetadataSaversHelp")+"
",elem.innerHTML=html,elem.classList.remove("hide"),!0}function getMetadataFetchersForTypeHtml(availableTypeOptions,libraryOptionsForType){var html="",plugins=availableTypeOptions.MetadataFetchers;if(plugins=getOrderedPlugins(plugins,libraryOptionsForType.MetadataFetcherOrder||[]),!plugins.length)return html;html+='
',html+='

'+globalize.translate("LabelTypeMetadataDownloaders",availableTypeOptions.Type)+"

",html+='
';for(var i=0,length=plugins.length;i';var isChecked=libraryOptionsForType.MetadataFetchers?-1!==libraryOptionsForType.MetadataFetchers.indexOf(plugin.Name):plugin.DefaultEnabled,checkedHtml=isChecked?' checked="checked"':"";html+='",html+='
',html+='

',html+=plugin.Name,html+="

",html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}return html+="
",html+='
'+globalize.translate("LabelMetadataDownloadersHelp")+"
",html+="
"}function getTypeOptions(allOptions,type){for(var allTypeOptions=allOptions.TypeOptions||[],i=0,length=allTypeOptions.length;i",html+='
';for(var i=0,length=plugins.length;i';var isChecked=libraryOptions.DisabledSubtitleFetchers?-1===libraryOptions.DisabledSubtitleFetchers.indexOf(plugin.Name):plugin.DefaultEnabled,checkedHtml=isChecked?' checked="checked"':"";html+='",html+='
',html+='

',html+=plugin.Name,html+="

","Open Subtitles"===plugin.Name&&(html+='
',html+=globalize.translate("OpenSubtitleInstructions"),html+="
"),html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}html+="
",html+='
'+globalize.translate("SubtitleDownloadersHelp")+"
",elem.innerHTML=html}catch(err){alert(err)}}function getImageFetchersForTypeHtml(availableTypeOptions,libraryOptionsForType){var html="",plugins=availableTypeOptions.ImageFetchers;if(plugins=getOrderedPlugins(plugins,libraryOptionsForType.ImageFetcherOrder||[]),!plugins.length)return html;html+='
',html+='
',html+='

'+globalize.translate("HeaderTypeImageFetchers",availableTypeOptions.Type)+"

";var supportedImageTypes=availableTypeOptions.SupportedImageTypes||[];(supportedImageTypes.length>1||1===supportedImageTypes.length&&"Primary"!==supportedImageTypes[0])&&(html+='"),html+="
",html+='
';for(var i=0,length=plugins.length;i';var isChecked=libraryOptionsForType.ImageFetchers?-1!==libraryOptionsForType.ImageFetchers.indexOf(plugin.Name):plugin.DefaultEnabled,checkedHtml=isChecked?' checked="checked"':"";html+='",html+='
',html+='

',html+=plugin.Name,html+="

",html+="
",i>0?html+='':plugins.length>1&&(html+=''),html+="
"}return html+="
",html+='
'+globalize.translate("LabelImageFetchersHelp")+"
",html+=""}function renderImageFetchers(page,availableOptions,libraryOptions){for(var html="",elem=page.querySelector(".imageFetchers"),i=0,length=availableOptions.TypeOptions.length;ib?1:0}),plugins}function setLibraryOptions(parent,options){currentLibraryOptions=options,currentAvailableOptions=parent.availableOptions,parent.querySelector("#selectLanguage").value=options.PreferredMetadataLanguage||"",parent.querySelector("#selectCountry").value=options.MetadataCountryCode||"",parent.querySelector("#selectAutoRefreshInterval").value=options.AutomaticRefreshIntervalDays||"0",parent.querySelector("#txtSeasonZeroName").value=options.SeasonZeroDisplayName||"Specials",parent.querySelector(".chkEnablePhotos").checked=options.EnablePhotos,parent.querySelector(".chkEnableRealtimeMonitor").checked=options.EnableRealtimeMonitor,parent.querySelector(".chkExtractChaptersDuringLibraryScan").checked=options.ExtractChapterImagesDuringLibraryScan,parent.querySelector(".chkExtractChapterImages").checked=options.EnableChapterImageExtraction,parent.querySelector("#chkDownloadImagesInAdvance").checked=options.DownloadImagesInAdvance,parent.querySelector("#chkSaveLocal").checked=options.SaveLocalMetadata,parent.querySelector("#chkImportMissingEpisodes").checked=options.ImportMissingEpisodes,parent.querySelector(".chkAutomaticallyGroupSeries").checked=options.EnableAutomaticSeriesGrouping,parent.querySelector("#chkEnableEmbeddedTitles").checked=options.EnableEmbeddedTitles,parent.querySelector("#chkSkipIfGraphicalSubsPresent").checked=options.SkipSubtitlesIfEmbeddedSubtitlesPresent,parent.querySelector("#chkSaveSubtitlesLocally").checked=options.SaveSubtitlesWithMedia,parent.querySelector("#chkSkipIfAudioTrackPresent").checked=options.SkipSubtitlesIfAudioTrackMatches,parent.querySelector("#chkRequirePerfectMatch").checked=options.RequirePerfectSubtitleMatch,Array.prototype.forEach.call(parent.querySelectorAll(".chkMetadataSaver"),function(elem){elem.checked=options.MetadataSavers?-1!==options.MetadataSavers.indexOf(elem.getAttribute("data-pluginname")):"true"===elem.getAttribute("data-defaultenabled")}),Array.prototype.forEach.call(parent.querySelectorAll(".chkSubtitleLanguage"),function(elem){elem.checked=!!options.SubtitleDownloadLanguages&&-1!==options.SubtitleDownloadLanguages.indexOf(elem.getAttribute("data-lang"))}),renderMetadataReaders(parent,getOrderedPlugins(parent.availableOptions.MetadataReaders,options.LocalMetadataReaderOrder||[])),renderMetadataFetchers(parent,parent.availableOptions,options),renderImageFetchers(parent,parent.availableOptions,options),renderSubtitleFetchers(parent,parent.availableOptions,options)}var currentLibraryOptions,currentAvailableOptions;return{embed:embed,setContentType:setContentType,getLibraryOptions:getLibraryOptions,setLibraryOptions:setLibraryOptions,setAdvancedVisible:setAdvancedVisible}}); \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/schedulesdirect.template.html b/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/schedulesdirect.template.html index 6d5d8f43d1..d4f4e22ad7 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/schedulesdirect.template.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/schedulesdirect.template.html @@ -1,5 +1,5 @@ 
-
+

Schedules Direct

${Help}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/xmltv.template.html b/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/xmltv.template.html index e782fdb5dd..b75c748113 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/xmltv.template.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/components/tvproviders/xmltv.template.html @@ -1,5 +1,5 @@ 
-
+

Xml TV

${Help}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/css/dashboard.css b/MediaBrowser.WebDashboard/dashboard-ui/css/dashboard.css index dcd0573f1f..302af2fea5 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/css/dashboard.css +++ b/MediaBrowser.WebDashboard/dashboard-ui/css/dashboard.css @@ -1 +1 @@ -.dashboardColumn,.dashboardSections{-webkit-box-orient:vertical;-webkit-box-direction:normal}.dashboardFooter{margin-top:3.5em;text-align:center}.dashboardFooter a{margin:0 .7em}progress{appearance:none;-moz-appearance:none;-webkit-appearance:none;border:2px solid #ccc;-webkit-border-radius:.3em;border-radius:.3em;margin:0;background:#ccc!important}progress[role]:after{background-image:none}progress::-webkit-progress-bar{background:#ccc}progress::-moz-progress-bar{border-radius:.4em;background-image:-moz-linear-gradient(center bottom,#2bc253 37%,#54f054 69%)}progress::-webkit-progress-value{-webkit-border-radius:.4em;border-radius:.4em;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#2bc253),color-stop(1,#54f054));background-image:-webkit-linear-gradient(center bottom,#2bc253 37%,#54f054 69%)}progress[aria-valuenow]:before{-webkit-border-radius:.4em;border-radius:.4em;background-image:-o-linear-gradient(center bottom,#2bc253 37%,#54f054 69%)}.localnav{margin-bottom:2.2em!important}@media all and (min-width:50em){.type-interior>.ui-panel-content-wrap>div[data-role=content],.type-interior>div[data-role=content]{padding-right:0;padding-left:0;padding-top:0;overflow:hidden}}.dashboardDocument{font-size:96.8%}.dashboardDocument .dashboardEntryHeaderButton,.dashboardDocument .lnkManageServer{display:none!important}.adminDrawerLogo{padding:1.5em 1em 1.2em;border-bottom:1px solid #e0e0e0;margin-bottom:1em;display:block}.adminDrawerLogo img{height:2.2em}div[data-role=controlgroup] a[data-role=button]{display:inline-block!important;margin:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-border-radius:0;border-radius:0}div[data-role=controlgroup] a[data-role=button]:first-child{-webkit-border-bottom-left-radius:.3125em;border-bottom-left-radius:.3125em;-webkit-border-top-left-radius:.3125em;border-top-left-radius:.3125em}div[data-role=controlgroup] a[data-role=button]:last-child{-webkit-border-bottom-right-radius:.3125em;border-bottom-right-radius:.3125em;-webkit-border-top-right-radius:.3125em;border-top-right-radius:.3125em}div[data-role=controlgroup] a[data-role=button]+a[data-role=button]{border-left-width:0!important;margin:0 0 0 -.4em!important}div[data-role=controlgroup] a.ui-btn-active{background:#38c!important;color:#fff!important}.header .imageLink{display:inline-block}.header .imageLink img{height:2.1em;vertical-align:middle}.content-primary{padding-top:6em;padding-right:1em;padding-left:1em}.withTabs .content-primary{padding-top:9em!important}@media all and (min-width:40em){.content-primary{padding-top:7em}.withTabs .content-primary{padding-top:10em!important}}@media all and (min-width:84em){.withTabs .content-primary{padding-top:7em!important}}.content-primary ul:first-child{margin-top:0}.dashboardSections{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column}.dashboardColumn{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-flex-shrink:0;flex-shrink:0;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1}.activeSession:not(.playingSession) .sessionNowPlayingContent,.supporterMembershipDisabled .tabSupporterMembership{display:none}.dashboardSection{-webkit-flex-shrink:0;flex-shrink:0;margin:0 0 2em}.dashboardSection h3{margin-top:.5em;margin-bottom:.5em}.activeRecordingItems>.card{width:50%}@media all and (min-width:70em){.dashboardSections{-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row}.dashboardColumn-2-60{width:46%}.dashboardColumn-2-40{width:27%}.dashboardSection{padding:0 1.5em}.activeRecordingItems>.card{width:25%}}@media all and (min-width:94em){.dashboardColumn-3-46{width:46%}.dashboardColumn-3-27{width:27%}.activeRecordingItems>.card{width:50%}}.premiumBanner img{position:absolute;text-align:right;top:0;right:0;width:4.4em;height:4.4em}.wizardContent{max-width:62em;padding:.5em 2em 1em;margin:0 auto;background:#fff}.wizardNavigation{text-align:right}.wizardContent form{max-width:100%}.wizardContent h2 img{height:2.5em;vertical-align:middle;margin-right:.5em;position:relative;top:-.3em}.scheduledTaskPaperIconItem{outline:0!important}.activeSession{width:100%!important}@media all and (min-width:40em){.activeSession{width:100%!important}}@media all and (min-width:50em){.activeSession{width:50%!important}}.sessionCardFooter{padding-top:.5em!important;padding-bottom:1em!important;border-top:1px solid #eee;text-align:center;position:relative}.sessionAppInfo,.sessionNowPlayingInfo{padding:.5em;overflow:hidden}.sessionCardButtons{min-height:2.7em}.sessionCardButton{margin:0}.sessionNowPlayingContent{-webkit-background-size:cover;background-size:cover;background-repeat:no-repeat;background-position:center center;position:absolute;top:0;left:0;right:0;bottom:0}.sessionNowPlayingInnerContent{position:absolute;top:0;left:0;right:0;bottom:0;font-weight:400}.sessionNowPlayingContent-withbackground+.sessionNowPlayingInnerContent{color:#fff!important;background:rgba(0,0,0,.7)}.sessionAppName{vertical-align:top;max-width:200px}.sessionNowPlayingInfo{position:absolute;left:0;bottom:11px;max-width:50%;-o-text-overflow:ellipsis;text-overflow:ellipsis}.sessionAppInfo img{max-width:32px;max-height:32px;margin-right:5px}.activeSession .playbackProgress{position:absolute;right:0;bottom:0;left:0;height:7px;width:100%;opacity:.95}.activeSession:not(.playingSession) .sessionNowPlayingInfo{bottom:0}.sessionNowPlayingTime{position:absolute;right:10px;bottom:19px}.sessionNowPlayingStreamInfo{white-space:nowrap}.activeSession .transcodingProgress{right:0;bottom:0;left:0;height:5px;width:100%;opacity:.9;position:absolute}.playbackProgress,.transcodingProgress{appearance:none;-moz-appearance:none;-webkit-appearance:none;margin:0 5px 0 0;height:14px;border:0 solid #222;-webkit-border-radius:0;border-radius:0;width:50px;background:#000!important}.playbackProgress::-webkit-progress-bar,.transcodingProgress::-webkit-progress-bar{background:#000}.transcodingSession .playbackProgress{bottom:5px}.transcodingProgress::-moz-progress-bar{border-radius:0;background-image:-moz-linear-gradient(center bottom,#dd4919 37%,#dd4919 69%)!important}.transcodingProgress::-webkit-progress-value{-webkit-border-radius:0;border-radius:0;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#dd4919),color-stop(1,#dd4919))!important;background-image:-webkit-linear-gradient(center bottom,#dd4919 37%,#dd4919 69%)!important}.transcodingProgress[aria-valuenow]:before{-webkit-border-radius:0;border-radius:0;background-image:-o-linear-gradient(center bottom,#dd4919 37%,#dd4919 69%)!important}.playbackProgress::-moz-progress-bar{border-radius:0;background-image:none;background-color:#52B54B}.playbackProgress::-webkit-progress-value{-webkit-border-radius:0;border-radius:0;background-image:none;background-color:#52B54B}.playbackProgress[aria-valuenow]:before{-webkit-border-radius:0;border-radius:0;background-image:none;background-color:#52B54B}@media all and (max-width:34.375em){.sessionAppName{max-width:160px}}@media all and (max-width:31.25em){.sessionAppName{max-width:150px}}.disabledUser{-webkit-filter:grayscale(100%);filter:grayscale(100%)}.disabledUserBanner{margin:0 0 2em}.appLinks a{text-decoration:none!important}.appLinks a+a{margin-left:5px}.appLinks img{height:36px}a[data-role=button]{-webkit-font-smoothing:antialiased;-webkit-user-select:none;-webkit-background-clip:padding-box;-webkit-border-radius:.3125em;border-radius:.3125em;border:1px solid #ddd!important;color:#333!important;cursor:pointer!important;font-family:inherit!important;font-weight:500!important;margin:0 .25em!important;display:inline-block;padding:.8em 1em;text-align:center;text-decoration:none!important;background:#f6f6f6!important}@-webkit-keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.rotatingCircle{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.pluginPreviewImg{-webkit-box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37)} \ No newline at end of file +.dashboardColumn,.dashboardSections{-webkit-box-orient:vertical;-webkit-box-direction:normal}.dashboardFooter{margin-top:3.5em;text-align:center}.dashboardFooter a{margin:0 .7em}progress{appearance:none;-moz-appearance:none;-webkit-appearance:none;border:2px solid #ccc;-webkit-border-radius:.3em;border-radius:.3em;margin:0;background:#ccc!important}progress[role]:after{background-image:none}progress::-webkit-progress-bar{background:#ccc}progress::-moz-progress-bar{border-radius:.4em;background-image:-moz-linear-gradient(center bottom,#2bc253 37%,#54f054 69%)}progress::-webkit-progress-value{-webkit-border-radius:.4em;border-radius:.4em;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#2bc253),color-stop(1,#54f054));background-image:-webkit-linear-gradient(center bottom,#2bc253 37%,#54f054 69%)}progress[aria-valuenow]:before{-webkit-border-radius:.4em;border-radius:.4em;background-image:-o-linear-gradient(center bottom,#2bc253 37%,#54f054 69%)}.localnav{margin-bottom:2.2em!important}@media all and (min-width:50em){.type-interior>.ui-panel-content-wrap>div[data-role=content],.type-interior>div[data-role=content]{padding-right:0;padding-left:0;padding-top:0;overflow:hidden}}.dashboardDocument{font-size:94.1%}.dashboardDocument .dashboardEntryHeaderButton,.dashboardDocument .lnkManageServer{display:none!important}.adminDrawerLogo{padding:1.5em 1em 1.2em;border-bottom:1px solid #e0e0e0;margin-bottom:1em;display:block}.adminDrawerLogo img{height:2.2em}div[data-role=controlgroup] a[data-role=button]{display:inline-block!important;margin:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-border-radius:0;border-radius:0}div[data-role=controlgroup] a[data-role=button]:first-child{-webkit-border-bottom-left-radius:.3125em;border-bottom-left-radius:.3125em;-webkit-border-top-left-radius:.3125em;border-top-left-radius:.3125em}div[data-role=controlgroup] a[data-role=button]:last-child{-webkit-border-bottom-right-radius:.3125em;border-bottom-right-radius:.3125em;-webkit-border-top-right-radius:.3125em;border-top-right-radius:.3125em}div[data-role=controlgroup] a[data-role=button]+a[data-role=button]{border-left-width:0!important;margin:0 0 0 -.4em!important}div[data-role=controlgroup] a.ui-btn-active{background:#38c!important;color:#fff!important}.header .imageLink{display:inline-block}.header .imageLink img{height:2.1em;vertical-align:middle}.content-primary{padding-top:6em;padding-right:1em;padding-left:1em}.withTabs .content-primary{padding-top:9em!important}@media all and (min-width:40em){.content-primary{padding-top:7em}.withTabs .content-primary{padding-top:10em!important}}@media all and (min-width:84em){.withTabs .content-primary{padding-top:7em!important}}.content-primary ul:first-child{margin-top:0}.dashboardSections{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column}.dashboardColumn{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-flex-shrink:0;flex-shrink:0;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1}.activeSession:not(.playingSession) .sessionNowPlayingContent,.supporterMembershipDisabled .tabSupporterMembership{display:none}.dashboardSection{-webkit-flex-shrink:0;flex-shrink:0;margin:0 0 2em}.dashboardSection h3{margin-top:.5em;margin-bottom:.5em}.activeRecordingItems>.card{width:50%}@media all and (min-width:70em){.dashboardSections{-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row}.dashboardColumn-2-60{width:46%}.dashboardColumn-2-40{width:27%}.dashboardSection{padding:0 1.5em}.activeRecordingItems>.card{width:25%}}@media all and (min-width:94em){.dashboardColumn-3-46{width:46%}.dashboardColumn-3-27{width:27%}.activeRecordingItems>.card{width:50%}}.premiumBanner img{position:absolute;text-align:right;top:0;right:0;width:4.4em;height:4.4em}.wizardContent{max-width:62em;padding:.5em 2em 1em;margin:0 auto;background:#fff}.wizardNavigation{text-align:right}.wizardContent form{max-width:100%}.wizardContent h2 img{height:2.5em;vertical-align:middle;margin-right:.5em;position:relative;top:-.3em}.scheduledTaskPaperIconItem{outline:0!important}.activeSession{width:100%!important}@media all and (min-width:40em){.activeSession{width:100%!important}}@media all and (min-width:50em){.activeSession{width:50%!important}}.sessionCardFooter{padding-top:.5em!important;padding-bottom:1em!important;border-top:1px solid #eee;text-align:center;position:relative}.sessionAppInfo,.sessionNowPlayingInfo{padding:.5em;overflow:hidden}.sessionCardButtons{min-height:2.7em}.sessionCardButton{margin:0}.sessionNowPlayingContent{-webkit-background-size:cover;background-size:cover;background-repeat:no-repeat;background-position:center center;position:absolute;top:0;left:0;right:0;bottom:0}.sessionNowPlayingInnerContent{position:absolute;top:0;left:0;right:0;bottom:0;font-weight:400}.sessionNowPlayingContent-withbackground+.sessionNowPlayingInnerContent{color:#fff!important;background:rgba(0,0,0,.7)}.sessionAppName{vertical-align:top;max-width:200px}.sessionNowPlayingInfo{position:absolute;left:0;bottom:11px;max-width:50%;-o-text-overflow:ellipsis;text-overflow:ellipsis}.sessionAppInfo img{max-width:32px;max-height:32px;margin-right:5px}.activeSession .playbackProgress{position:absolute;right:0;bottom:0;left:0;height:7px;width:100%;opacity:.95}.activeSession:not(.playingSession) .sessionNowPlayingInfo{bottom:0}.sessionNowPlayingTime{position:absolute;right:10px;bottom:19px}.sessionNowPlayingStreamInfo{white-space:nowrap}.activeSession .transcodingProgress{right:0;bottom:0;left:0;height:5px;width:100%;opacity:.9;position:absolute}.playbackProgress,.transcodingProgress{appearance:none;-moz-appearance:none;-webkit-appearance:none;margin:0 5px 0 0;height:14px;border:0 solid #222;-webkit-border-radius:0;border-radius:0;width:50px;background:#000!important}.playbackProgress::-webkit-progress-bar,.transcodingProgress::-webkit-progress-bar{background:#000}.transcodingSession .playbackProgress{bottom:5px}.transcodingProgress::-moz-progress-bar{border-radius:0;background-image:-moz-linear-gradient(center bottom,#dd4919 37%,#dd4919 69%)!important}.transcodingProgress::-webkit-progress-value{-webkit-border-radius:0;border-radius:0;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#dd4919),color-stop(1,#dd4919))!important;background-image:-webkit-linear-gradient(center bottom,#dd4919 37%,#dd4919 69%)!important}.transcodingProgress[aria-valuenow]:before{-webkit-border-radius:0;border-radius:0;background-image:-o-linear-gradient(center bottom,#dd4919 37%,#dd4919 69%)!important}.playbackProgress::-moz-progress-bar{border-radius:0;background-image:none;background-color:#52B54B}.playbackProgress::-webkit-progress-value{-webkit-border-radius:0;border-radius:0;background-image:none;background-color:#52B54B}.playbackProgress[aria-valuenow]:before{-webkit-border-radius:0;border-radius:0;background-image:none;background-color:#52B54B}@media all and (max-width:34.375em){.sessionAppName{max-width:160px}}@media all and (max-width:31.25em){.sessionAppName{max-width:150px}}.disabledUser{-webkit-filter:grayscale(100%);filter:grayscale(100%)}.disabledUserBanner{margin:0 0 2em}.appLinks a{text-decoration:none!important}.appLinks a+a{margin-left:5px}.appLinks img{height:36px}a[data-role=button]{-webkit-font-smoothing:antialiased;-webkit-user-select:none;-webkit-background-clip:padding-box;-webkit-border-radius:.3125em;border-radius:.3125em;border:1px solid #ddd!important;color:#333!important;cursor:pointer!important;font-family:inherit!important;font-weight:500!important;margin:0 .25em!important;display:inline-block;padding:.8em 1em;text-align:center;text-decoration:none!important;background:#f6f6f6!important}@-webkit-keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.rotatingCircle{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.pluginPreviewImg{-webkit-box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37)} \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/css/librarybrowser.css b/MediaBrowser.WebDashboard/dashboard-ui/css/librarybrowser.css index f13a99284c..5ccebd77c0 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/css/librarybrowser.css +++ b/MediaBrowser.WebDashboard/dashboard-ui/css/librarybrowser.css @@ -1 +1 @@ -.headerUserImage,.navMenuOption,.pageTitle{vertical-align:middle}.detailButton-mobile,.itemLinks,.listPaging,.sectionTabs,.viewSettings{text-align:center}.headerSelectedPlayer,.itemMiscInfo{-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden}.libraryPage{padding-top:7.5em!important}.itemDetailPage{padding-top:4em!important}.standalonePage{padding-top:5.5em!important}.wizardPage{padding-top:7em!important}.libraryPage:not(.noSecondaryNavPage){padding-top:9.2em!important}.absolutePageTabContent{position:absolute;left:0;right:0;bottom:0;z-index:1;margin:0!important;top:6.9em!important;-webkit-transition:-webkit-transform .2s ease-out;-o-transition:transform .2s ease-out;transition:transform .2s ease-out}.pageTabContent:not(.is-active){display:none!important}.navMenuDivider{height:1px;margin:.5em 0;display:none}.headerUserImage{-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;background-position:center center;-webkit-border-radius:100em;border-radius:100em;display:inline-block}.headerUserButtonRound img{-webkit-border-radius:100em;border-radius:100em}.headerButton{-webkit-flex-shrink:0;flex-shrink:0}.hideMainDrawer .mainDrawerButton{display:none}.noHeaderRight .headerRight,.noHomeButtonHeader .headerHomeButton{display:none!important}.pageTitle{display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;margin:0 0 0 .5em;height:1.7em;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-flex-shrink:1;flex-shrink:1}.detailButton-mobile,.skinHeader{-webkit-flex-direction:column;-webkit-box-orient:vertical;-webkit-box-direction:normal}.pageTitleWithLogo{background-position:left center;-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;width:13.2em}.pageTitleWithDefaultLogo{height:1.22em}.skinHeader{position:fixed;right:0;left:0;z-index:999;top:0;border:0;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;background-color:#121212;color:#ccc;contain:layout style paint}.mainAnimatedPages,.pageTabContent{contain:layout style}.hiddenViewMenuBar .skinHeader{display:none}.headerLeft,.headerRight{display:-webkit-box;display:-webkit-flex;-webkit-box-align:center}.headerTop{padding:.865em 0}.headerLeft{display:flex;-webkit-align-items:center;align-items:center;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;overflow:hidden}.sectionTabs{width:100%}.headerRight{display:flex;-webkit-align-items:center;align-items:center;-webkit-box-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}.selectedMediaFolder{background-color:#f2f2f2!important}.navMenuOption{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;text-decoration:none;color:inherit;padding:.9em 0 .9em 2.4em;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1}.layout-desktop .searchTabButton,.layout-mobile .searchTabButton,.layout-tv .headerSearchButton,html:not(.dashboardDocument) .btnNotifications{display:none!important}.navMenuOptionIcon{margin-right:1em;-webkit-flex-shrink:0;flex-shrink:0}.sidebarHeader{padding-left:1.2em;margin:1em 0 .5em}.dashboardDocument .skinBody{-webkit-transition:left ease-in-out .3s,padding ease-in-out .3s;-o-transition:left ease-in-out .3s,padding ease-in-out .3s;transition:left ease-in-out .3s,padding ease-in-out .3s;position:absolute;top:0;right:0;bottom:0;left:0}.mainDrawer-scrollContainer{padding-bottom:10vh}@media all and (min-width:40em){.dashboardDocument .adminDrawerLogo,.dashboardDocument .mainDrawerButton{display:none!important}.dashboardDocument .mainDrawer{z-index:inherit!important;left:0!important;top:0!important;-webkit-transform:none!important;transform:none!important;-webkit-box-shadow:none!important;box-shadow:none!important;width:19.23em!important;font-size:96%}.dashboardDocument .mainDrawer-scrollContainer{margin-top:5em!important}.dashboardDocument withSectionTabs .mainDrawer-scrollContainer{margin-top:8.7em!important}.dashboardDocument .skinBody{left:20em}}@media all and (min-width:40em) and (max-width:84em){.dashboardDocument.withSectionTabs .mainDrawer-scrollContainer{margin-top:8.4em!important}}@media all and (max-width:60em){.libraryDocument .mainDrawerButton{display:none}}@media all and (max-width:84em){.withSectionTabs .headerTop{padding-bottom:.2em}.sectionTabs{font-size:83.5%}}@media all and (min-width:84em){.headerTop{padding:1.489em 0}.headerTabs{-webkit-align-self:center;align-self:center;width:auto;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;margin-top:-3.34em;position:relative;top:-1.05em}.libraryPage:not(.noSecondaryNavPage){padding-top:6.3em!important}.pageWithAbsoluteTabs:not(.noSecondaryNavPage){padding-top:8.4em!important}.absolutePageTabContent{top:5.7em!important}.dashboardDocument.withSectionTabs .mainDrawer-scrollContainer{margin-top:6.1em!important}.dashboardDocument .mainDrawer-scrollContainer{margin-top:6.3em!important}}.headerSelectedPlayer{max-width:10em;white-space:nowrap}@media all and (max-width:37.5em){.headerSelectedPlayer{display:none}}.hidingAnimatedTab{visibility:hidden}.headerArrowImage{height:20px;margin-left:.5em}.backdropContainer{position:fixed;top:0;left:0;right:0;bottom:0;z-index:-1}.libraryPage .header{padding-bottom:0}.flexPageTabContent.is-active{display:-webkit-box!important;display:-webkit-flex!important;display:flex!important}.viewSettings{margin:0 0 .25em}.viewControls+.listTopPaging{margin-left:.5em!important}.criticReview{margin:1.5em 0;background:#222;padding:.8em .8em .8em 3em;-webkit-border-radius:.3em;border-radius:.3em;position:relative}.detailLogo,.itemBackdrop{background-repeat:no-repeat;background-position:center center}.criticReview:first-child{margin-top:.5em}.criticReview img{width:2.4em}.criticRatingScore{margin-bottom:.5em}.itemTag{display:inline-block;margin-right:1em}.itemOverview{white-space:pre-wrap}.itemLinks{padding:0}.itemLinks p{margin:.5em 0}.reviewLink,.reviewerName{margin-top:.5em}.reviewerName{color:#ccc}.reviewDate{margin-left:1em}.reviewScore{position:absolute;left:.8em}.itemBackdrop{-webkit-background-size:cover;background-size:cover;height:50vh;position:relative}.itemBackdropProgressBar{position:absolute!important;bottom:0;left:0;right:0}.itemBackdropFader{position:absolute;bottom:-1px;left:0;right:0;height:15vh}.desktopMiscInfoContainer{position:absolute;bottom:.75em}.detailImageContainer{margin-right:2em;width:280px;-webkit-flex-shrink:0;flex-shrink:0}.detailPagePrimaryContent{position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1}.detailLogo{width:21.3em;height:5em;position:absolute;top:13.5%;right:19.5%;-webkit-background-size:contain;background-size:contain}@media all and (max-width:87.5em){.detailLogo{right:5%}}@media all and (max-width:75em){.detailLogo{right:2%}}@media all and (max-width:68.75em){.detailLogo{width:14.91em;height:3.5em;right:5%;bottom:5%;top:auto;background-position:center right;display:none}}.itemDetailImage{width:100%}.thumbDetailImageContainer{width:400px}.itemDetailImage.loaded{-webkit-box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37)}@media all and (max-width:62.5em){.detailPageContent{position:relative}.detailImageContainer{position:absolute;top:-90px;left:5%;width:auto}.itemDetailImage{height:120px;width:auto!important}.btnPlaySimple{display:none!important}}@media all and (min-width:62.5em){.itemBackdrop{display:none}.detailPagePrimaryContainer{display:-webkit-box;display:-webkit-flex;display:flex;margin-bottom:3.6em}}@media all and (max-width:75em){.lnkSibling{display:none!important}}.parentName{display:block;margin-bottom:.5em}.emby-button.detailFloatingButton{position:absolute;background-color:rgba(0,0,0,.5)!important;z-index:1;top:50%;left:50%;margin:-2.2em 0 0 -2.2em;border:2.7px solid rgba(255,255,255,.6);padding:.38em!important;color:rgba(255,255,255,.76)}.emby-button.detailFloatingButton i{font-size:3.5em}@media all and (max-width:62.5em){.parentName{margin-bottom:1em}.itemDetailPage{padding-top:0!important}.detailimg-hidemobile{display:none}}@media all and (min-width:31.25em){.mobileDetails{display:none}}@media all and (max-width:31.25em){.desktopDetails{display:none!important}}.detailButton-mobile,.mainDetailButtons{display:-webkit-box;display:-webkit-flex}.itemName{margin:.5em 0}.empty{margin:0}.detailCollapsibleSection:not(.hide)+.detailCollapsibleSection{margin-top:-2em}.detailPageCollabsible{margin-top:0}.mainDetailButtons{display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-flex-wrap:wrap;flex-wrap:wrap;margin:1em 0}.recordingFields button{margin-left:0;margin-right:.5em;-webkit-flex-shrink:0;flex-shrink:0}.mainDetailButtons.hide+.recordingFields{margin-top:1.5em!important}.mainDetailButtons>.raised{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.detailButton-mobile{display:flex;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;align-items:center;margin:0!important;padding:.5em .7em!important}@media all and (min-width:29em){.detailButton-mobile{padding-left:.75em!important;padding-right:.75em!important}}@media all and (min-width:32em){.detailButton-mobile{padding-left:.8em!important;padding-right:.8em!important}}@media all and (min-width:35em){.detailButton-mobile{padding-left:.85em!important;padding-right:.85em!important}}.detailButton-mobile-content{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.detailButton-mobile-icon{font-size:1.6em!important;width:1em;height:1em}.detailImageProgressContainer{position:absolute;bottom:4px;right:1px;left:1px;text-align:center}@media all and (max-width:62.5em){.detailButton-mobile-text{margin-top:.7em;font-size:80%;font-weight:400}.mainDetailButtons{margin-left:-.5em}}@media all and (min-width:62.5em){.detailButton-mobile-icon:not(.always),.detailButton-mobile-text.texthide{display:none!important}.detailButton-mobile{padding-top:0!important;padding-bottom:0!important;height:3em;margin-right:.3em!important}.mainDetailButtons{font-size:108%;margin:1.25em 0}.detailButton-mobile-icon:not(.notext){margin-right:.25em}.detailButton-mobile-icon.playstatebutton-icon-unplayed{opacity:.2}.detailButton-mobile-content{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row}}.listTopPaging,.viewControls{display:inline-block}@media all and (max-width:50em){.editorMenuLink{display:none}}.itemMiscInfo{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-webkit-align-items:center;align-items:center}@media all and (max-width:31.25em){.mobileDetails .itemMiscInfo{text-align:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.itemMiscInfo .endsAt{display:none}}.layout-tv .detailVerticalSection{margin-bottom:3.4em!important}.detailPageContent{border-spacing:0;border-collapse:collapse;padding-top:3em}@media all and (max-width:62.5em){.detailPageContent-nodetailimg{padding-top:0;margin-top:-3em}}@media all and (min-width:75em){.itemDetailPage .padded-left{padding-left:4%!important}.itemDetailPage .padded-right{padding-right:4%!important}}.mediaInfoStream{margin:0 3em 0 0;display:inline-block;vertical-align:top}.mediaInfoStreamType{display:block;margin:1em 0}.mediaInfoAttribute,.mediaInfoLabel{display:inline-block}.mediaInfoLabel{margin-right:1em;font-weight:600}.recordingProgressBar::-moz-progress-bar{background-color:#c33}.recordingProgressBar::-webkit-progress-value{background-color:#c33}.recordingProgressBar[aria-valuenow]:before{background-color:#c33}.timelineHeader{margin-bottom:.25em;line-height:1.25em;line-height:initial}.itemsContainer{margin:0 auto}@media all and (max-height:31.25em){.itemBackdrop{height:52vh}}@media all and (max-width:75em){.listViewUserDataButtons{display:none!important}}@media all and (max-width:62.5em){.detailsHiddenOnMobile{display:none}}.btnSyncComplete{background:#673AB7!important}.btnSyncComplete i{-webkit-border-radius:1000px;border-radius:1000px}.bulletSeparator{margin:0 .35em}.mediaInfoIcons{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;margin:1em 0;-webkit-flex-wrap:wrap;flex-wrap:wrap}.verticalSection{margin-bottom:1.7em}@media all and (max-width:500px),(max-height:720px){.verticalSection{margin-bottom:1em}}.verticalSection-extrabottompadding{margin-bottom:2.7em}.sectionTitleContainer{margin-bottom:.4em}.formSectionTitleContainer{margin:1.5em 0}.sectionTitleButton,.sectionTitleIconButton{margin-right:0!important;display:inline-block;vertical-align:middle}.sectionTitle{margin-bottom:1em}.sectionTitle-cards{margin-left:.4em;margin-bottom:.1em;margin-top:0}@media all and (max-width:50em){.sectionTitle-cards{margin-left:.2em}}.sectionTitleContainer>.sectionTitle{margin-top:0;margin-bottom:0;display:inline-block;vertical-align:middle}.sectionTitleButton{margin-left:1.5em!important;-webkit-flex-shrink:0;flex-shrink:0}.sectionTitleButton+.sectionTitleButton{margin-left:.5em!important}.sectionTitleIconButton{margin-left:1.5em!important;-webkit-flex-shrink:0;flex-shrink:0;color:#aaa!important;font-size:84%!important;padding:.5em!important}.horizontalItemsContainer{display:-webkit-box;display:-webkit-flex;display:flex}.sectionTitleTextButton{margin:0!important;display:-webkit-inline-box!important;display:-webkit-inline-flex!important;display:inline-flex!important;color:inherit!important}.sectionTitleTextButton:not(.padded-left){padding:0!important}.sectionTitleTextButton.padded-left{padding-bottom:0!important;padding-right:0!important;padding-top:0!important}.sectionTitleTextButton>.sectionTitle{margin-bottom:0}.padded-left{padding-left:2%}.padded-right{padding-right:2%}.padded-top{padding-top:1em}.padded-bottom{padding-bottom:1em}.layout-tv .padded-top-focusscale{padding-top:1.6em;margin-top:-1.6em}.layout-tv .padded-bottom-focusscale{padding-bottom:1.6em;margin-bottom:-1.6em}@media all and (min-height:500px){.padded-left-withalphapicker{padding-left:7.5%}.padded-right-withalphapicker{padding-right:7.5%}}@media all and (min-width:500px){.padded-left{padding-left:6%}.padded-right{padding-right:6%}}@media all and (min-width:600px){.padded-left{padding-left:4%}.padded-right{padding-right:4%}}@media all and (min-width:800px){.padded-left{padding-left:3.2%}.padded-right{padding-right:3.2%}}@media all and (min-width:1280px){.padded-left{padding-left:3.3%}.padded-right{padding-right:3.3%}}@media all and (min-width:800px){.layout-tv .padded-left-withalphapicker{padding-left:4.5%}.layout-tv .padded-right-withalphapicker{padding-right:4.5%}}.searchfields-icon{color:#aaa}.button-accent-flat{color:#52B54B!important}.clearLink{text-decoration:none;font-weight:inherit!important;vertical-align:middle;color:inherit!important}.itemsViewSettingsContainer{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}@media all and (min-width:40em){.listIconButton-autohide{display:none!important}}@media all and (max-width:40em){.listTextButton-autohide{display:none!important}}.layout-tv .itemsViewSettingsContainer{-webkit-box-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;font-size:92%;padding:0 .75em 2em 0}.viewSettingsButtonIcon{font-size:1.113em!important} \ No newline at end of file +.headerUserImage,.navMenuOption,.pageTitle{vertical-align:middle}.detailButton-mobile,.itemLinks,.listPaging,.sectionTabs,.viewSettings{text-align:center}.headerSelectedPlayer,.itemMiscInfo{-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden}.libraryPage{padding-top:7em!important}.itemDetailPage{padding-top:4em!important}.standalonePage{padding-top:4.5em!important}.wizardPage{padding-top:7em!important}.libraryPage:not(.noSecondaryNavPage){padding-top:7.5em!important}.absolutePageTabContent{position:absolute;left:0;right:0;bottom:0;z-index:1;margin:0!important;top:6.9em!important;-webkit-transition:-webkit-transform .2s ease-out;-o-transition:transform .2s ease-out;transition:transform .2s ease-out}.pageTabContent:not(.is-active){display:none!important}.navMenuDivider{height:1px;margin:.5em 0;display:none}.headerUserImage{-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;background-position:center center;-webkit-border-radius:100em;border-radius:100em;display:inline-block}.headerUserButtonRound img{-webkit-border-radius:100em;border-radius:100em}.headerButton{-webkit-flex-shrink:0;flex-shrink:0}.hideMainDrawer .mainDrawerButton{display:none}.noHeaderRight .headerRight,.noHomeButtonHeader .headerHomeButton{display:none!important}.pageTitle{display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;margin:0 0 0 .5em;height:1.7em;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-flex-shrink:1;flex-shrink:1}.detailButton-mobile,.skinHeader{-webkit-flex-direction:column;-webkit-box-orient:vertical;-webkit-box-direction:normal}.pageTitleWithLogo{background-position:left center;-webkit-background-size:contain;background-size:contain;background-repeat:no-repeat;width:13.2em}.pageTitleWithDefaultLogo{height:1.22em}.skinHeader{position:fixed;right:0;left:0;z-index:999;top:0;border:0;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;background-color:#121212;color:#ccc;contain:layout style paint}.mainAnimatedPages,.pageTabContent{contain:layout style}.hiddenViewMenuBar .skinHeader{display:none}.headerLeft,.headerRight{display:-webkit-box;display:-webkit-flex;-webkit-box-align:center}.headerTop{padding:.865em 0}.headerLeft{display:flex;-webkit-align-items:center;align-items:center;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;overflow:hidden}.sectionTabs{width:100%}.headerRight{display:flex;-webkit-align-items:center;align-items:center;-webkit-box-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}.selectedMediaFolder{background-color:#f2f2f2!important}.navMenuOption{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;text-decoration:none;color:inherit;padding:.9em 0 .9em 2.4em;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1}.layout-desktop .searchTabButton,.layout-mobile .searchTabButton,.layout-tv .headerSearchButton,body:not(.dashboardDocument) .btnNotifications{display:none!important}.navMenuOptionIcon{margin-right:1em;-webkit-flex-shrink:0;flex-shrink:0}.sidebarHeader{padding-left:1.2em;margin:1em 0 .5em}.dashboardDocument .skinBody{-webkit-transition:left ease-in-out .3s,padding ease-in-out .3s;-o-transition:left ease-in-out .3s,padding ease-in-out .3s;transition:left ease-in-out .3s,padding ease-in-out .3s;position:absolute;top:0;right:0;bottom:0;left:0}.mainDrawer-scrollContainer{padding-bottom:10vh}@media all and (min-width:40em){.dashboardDocument .adminDrawerLogo,.dashboardDocument .mainDrawerButton{display:none!important}.dashboardDocument .mainDrawer{z-index:inherit!important;left:0!important;top:0!important;-webkit-transform:none!important;transform:none!important;-webkit-box-shadow:none!important;box-shadow:none!important;width:20.205em!important;font-size:94%}.dashboardDocument .mainDrawer-scrollContainer{margin-top:5em!important}.dashboardDocument withSectionTabs .mainDrawer-scrollContainer{margin-top:8.7em!important}.dashboardDocument .skinBody{left:20em}}@media all and (min-width:40em) and (max-width:84em){.dashboardDocument.withSectionTabs .mainDrawer-scrollContainer{margin-top:8.4em!important}}@media all and (max-width:60em){.libraryDocument .mainDrawerButton{display:none}}@media all and (max-width:84em){.withSectionTabs .headerTop{padding-bottom:.2em}.sectionTabs{font-size:83.5%}}@media all and (min-width:84em){.headerTop{padding:1.489em 0}.headerTabs{-webkit-align-self:center;align-self:center;width:auto;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;margin-top:-3.34em;position:relative;top:-1.05em}.libraryPage:not(.noSecondaryNavPage){padding-top:4.6em!important}.pageWithAbsoluteTabs:not(.noSecondaryNavPage){padding-top:6.7em!important}.absolutePageTabContent{top:5.7em!important}.dashboardDocument.withSectionTabs .mainDrawer-scrollContainer{margin-top:6.1em!important}.dashboardDocument .mainDrawer-scrollContainer{margin-top:6.3em!important}}.headerSelectedPlayer{max-width:10em;white-space:nowrap}@media all and (max-width:37.5em){.headerSelectedPlayer{display:none}}.hidingAnimatedTab{visibility:hidden}.headerArrowImage{height:20px;margin-left:.5em}.backdropContainer{position:fixed;top:0;left:0;right:0;bottom:0;z-index:-1}.libraryPage .header{padding-bottom:0}.flexPageTabContent.is-active{display:-webkit-box!important;display:-webkit-flex!important;display:flex!important}.viewSettings{margin:0 0 .25em}.viewControls+.listTopPaging{margin-left:.5em!important}.criticReview{margin:1.5em 0;background:#222;padding:.8em .8em .8em 3em;-webkit-border-radius:.3em;border-radius:.3em;position:relative}.detailLogo,.itemBackdrop{background-repeat:no-repeat;background-position:center center}.criticReview:first-child{margin-top:.5em}.criticReview img{width:2.4em}.criticRatingScore{margin-bottom:.5em}.itemTag{display:inline-block;margin-right:1em}.itemOverview{white-space:pre-wrap}.itemLinks{padding:0}.itemLinks p{margin:.5em 0}.reviewLink,.reviewerName{margin-top:.5em}.reviewerName{color:#ccc}.reviewDate{margin-left:1em}.reviewScore{position:absolute;left:.8em}.itemBackdrop{-webkit-background-size:cover;background-size:cover;height:50vh;position:relative}.itemBackdropProgressBar{position:absolute!important;bottom:0;left:0;right:0}.itemBackdropFader{position:absolute;bottom:-1px;left:0;right:0;height:15vh}.desktopMiscInfoContainer{position:absolute;bottom:.75em}.detailImageContainer{margin-right:2em;width:280px;-webkit-flex-shrink:0;flex-shrink:0}.detailPagePrimaryContent{position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1}.detailLogo{width:21.3em;height:5em;position:absolute;top:13.5%;right:19.5%;-webkit-background-size:contain;background-size:contain}@media all and (max-width:87.5em){.detailLogo{right:5%}}@media all and (max-width:75em){.detailLogo{right:2%}}@media all and (max-width:68.75em){.detailLogo{width:14.91em;height:3.5em;right:5%;bottom:5%;top:auto;background-position:center right;display:none}}.itemDetailImage{width:100%}.thumbDetailImageContainer{width:400px}.itemDetailImage.loaded{-webkit-box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37);box-shadow:0 .0725em .29em 0 rgba(0,0,0,.37)}@media all and (max-width:62.5em){.detailPageContent{position:relative}.detailImageContainer{position:absolute;top:-90px;left:5%;width:auto}.itemDetailImage{height:120px;width:auto!important}.btnPlaySimple{display:none!important}}@media all and (min-width:62.5em){.itemBackdrop{display:none}.detailPagePrimaryContainer{display:-webkit-box;display:-webkit-flex;display:flex;margin-bottom:3.6em}}@media all and (max-width:75em){.lnkSibling{display:none!important}}.parentName{display:block;margin-bottom:.5em}.emby-button.detailFloatingButton{position:absolute;background-color:rgba(0,0,0,.5)!important;z-index:1;top:50%;left:50%;margin:-2.2em 0 0 -2.2em;border:2.7px solid rgba(255,255,255,.6);padding:.38em!important;color:rgba(255,255,255,.76)}.emby-button.detailFloatingButton i{font-size:3.5em}@media all and (max-width:62.5em){.parentName{margin-bottom:1em}.itemDetailPage{padding-top:0!important}.detailimg-hidemobile{display:none}}@media all and (min-width:31.25em){.mobileDetails{display:none}}@media all and (max-width:31.25em){.desktopDetails{display:none!important}}.detailButton-mobile,.mainDetailButtons{display:-webkit-box;display:-webkit-flex}.itemName{margin:.5em 0}.empty{margin:0}.detailCollapsibleSection:not(.hide)+.detailCollapsibleSection{margin-top:-2em}.detailPageCollabsible{margin-top:0}.mainDetailButtons{display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-flex-wrap:wrap;flex-wrap:wrap;margin:1em 0}.recordingFields button{margin-left:0;margin-right:.5em;-webkit-flex-shrink:0;flex-shrink:0}.mainDetailButtons.hide+.recordingFields{margin-top:1.5em!important}.mainDetailButtons>.raised{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.detailButton-mobile{display:flex;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;align-items:center;margin:0!important;padding:.5em .7em!important}@media all and (min-width:29em){.detailButton-mobile{padding-left:.75em!important;padding-right:.75em!important}}@media all and (min-width:32em){.detailButton-mobile{padding-left:.8em!important;padding-right:.8em!important}}@media all and (min-width:35em){.detailButton-mobile{padding-left:.85em!important;padding-right:.85em!important}}.detailButton-mobile-content{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.detailButton-mobile-icon{font-size:1.6em!important;width:1em;height:1em}.detailImageProgressContainer{position:absolute;bottom:4px;right:1px;left:1px;text-align:center}@media all and (max-width:62.5em){.detailButton-mobile-text{margin-top:.7em;font-size:80%;font-weight:400}.mainDetailButtons{margin-left:-.5em}}@media all and (min-width:62.5em){.detailButton-mobile-icon:not(.always),.detailButton-mobile-text.texthide{display:none!important}.detailButton-mobile{padding-top:0!important;padding-bottom:0!important;height:3em;margin-right:.3em!important}.mainDetailButtons{font-size:108%;margin:1.25em 0}.detailButton-mobile-icon:not(.notext){margin-right:.25em}.detailButton-mobile-icon.playstatebutton-icon-unplayed{opacity:.2}.detailButton-mobile-content{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row}}.listTopPaging,.viewControls{display:inline-block}@media all and (max-width:50em){.editorMenuLink{display:none}}.itemMiscInfo{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-webkit-align-items:center;align-items:center}@media all and (max-width:31.25em){.mobileDetails .itemMiscInfo{text-align:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.itemMiscInfo .endsAt{display:none}}.layout-tv .detailVerticalSection{margin-bottom:3.4em!important}.detailPageContent{border-spacing:0;border-collapse:collapse;padding-top:3em}@media all and (max-width:62.5em){.detailPageContent-nodetailimg{padding-top:0;margin-top:-3em}}@media all and (min-width:75em){.itemDetailPage .padded-left{padding-left:4%!important}.itemDetailPage .padded-right{padding-right:4%!important}}.mediaInfoStream{margin:0 3em 0 0;display:inline-block;vertical-align:top}.mediaInfoStreamType{display:block;margin:1em 0}.mediaInfoAttribute,.mediaInfoLabel{display:inline-block}.mediaInfoLabel{margin-right:1em;font-weight:600}.recordingProgressBar::-moz-progress-bar{background-color:#c33}.recordingProgressBar::-webkit-progress-value{background-color:#c33}.recordingProgressBar[aria-valuenow]:before{background-color:#c33}.timelineHeader{margin-bottom:.25em;line-height:1.25em;line-height:initial}.itemsContainer{margin:0 auto}@media all and (max-height:31.25em){.itemBackdrop{height:52vh}}@media all and (max-width:75em){.listViewUserDataButtons{display:none!important}}@media all and (max-width:62.5em){.detailsHiddenOnMobile{display:none}}.btnSyncComplete{background:#673AB7!important}.btnSyncComplete i{-webkit-border-radius:1000px;border-radius:1000px}.bulletSeparator{margin:0 .35em}.mediaInfoIcons{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;margin:1em 0;-webkit-flex-wrap:wrap;flex-wrap:wrap}.verticalSection{margin-bottom:1.5em}@media all and (max-width:500px),(max-height:720px){.verticalSection{margin-bottom:1em}}.verticalSection-extrabottompadding{margin-bottom:2.7em}.sectionTitleContainer{margin:1.5em 0}.sectionTitleButton,.sectionTitleIconButton{margin-right:0!important;display:inline-block;vertical-align:middle}.sectionTitleContainer-cards{margin-bottom:.5em}.sectionTitle{margin-bottom:1em}.sectionTitle-cards{margin-left:.4em;margin-bottom:.1em}@media all and (max-width:50em){.sectionTitle-cards{margin-left:.28em}}.sectionTitleContainer>.sectionTitle{margin-top:0;margin-bottom:0;display:inline-block;vertical-align:middle}.sectionTitleButton{margin-left:1.5em!important;-webkit-flex-shrink:0;flex-shrink:0}.sectionTitleButton+.sectionTitleButton{margin-left:.5em!important}.sectionTitleIconButton{margin-left:1.5em!important;-webkit-flex-shrink:0;flex-shrink:0;color:#aaa!important;font-size:84%!important;padding:.5em!important}.horizontalItemsContainer{display:-webkit-box;display:-webkit-flex;display:flex}.sectionTitleTextButton{margin:0!important;display:-webkit-inline-box!important;display:-webkit-inline-flex!important;display:inline-flex!important;color:inherit!important}.sectionTitleTextButton:not(.padded-left){padding:0!important}.sectionTitleTextButton.padded-left{padding-bottom:0!important;padding-right:0!important;padding-top:0!important}.sectionTitleTextButton>.sectionTitle{margin-bottom:0;margin-top:0}.padded-left{padding-left:2%}.padded-right{padding-right:2%}.padded-top{padding-top:1em}.padded-bottom{padding-bottom:1em}.layout-tv .padded-top-focusscale{padding-top:1.6em;margin-top:-1.6em}.layout-tv .padded-bottom-focusscale{padding-bottom:1.6em;margin-bottom:-1.6em}@media all and (min-height:500px){.padded-left-withalphapicker{padding-left:7.5%}.padded-right-withalphapicker{padding-right:7.5%}}@media all and (min-width:500px){.padded-left{padding-left:6%}.padded-right{padding-right:6%}}@media all and (min-width:600px){.padded-left{padding-left:4%}.padded-right{padding-right:4%}}@media all and (min-width:800px){.padded-left{padding-left:3.2%}.padded-right{padding-right:3.2%}}@media all and (min-width:1280px){.padded-left{padding-left:3.3%}.padded-right{padding-right:3.3%}}@media all and (min-width:800px){.layout-tv .padded-left-withalphapicker{padding-left:4.5%}.layout-tv .padded-right-withalphapicker{padding-right:4.5%}}.searchfields-icon{color:#aaa}.button-accent-flat{color:#52B54B!important}.clearLink{text-decoration:none;font-weight:inherit!important;vertical-align:middle;color:inherit!important}.itemsViewSettingsContainer{-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}@media all and (min-width:40em){.listIconButton-autohide{display:none!important}}@media all and (max-width:40em){.listTextButton-autohide{display:none!important}}.layout-tv .itemsViewSettingsContainer{-webkit-box-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;font-size:92%;padding:0 .75em 2em 0}.viewSettingsButtonIcon{font-size:1.113em!important} \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/css/site.css b/MediaBrowser.WebDashboard/dashboard-ui/css/site.css index 2104b68729..f77bde4753 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/css/site.css +++ b/MediaBrowser.WebDashboard/dashboard-ui/css/site.css @@ -1 +1 @@ -body,html{margin:0;padding:0;height:100%}.backgroundContainer{position:fixed;top:0;left:0;right:0;bottom:0;contain:strict}html{background-color:#242424;line-height:1.35}.layout-mobile,.layout-tv{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.iosBody{font-size:88%!important}body{overflow-y:scroll!important;overflow-x:hidden;background-color:transparent!important;-webkit-font-smoothing:antialiased}body.autoScrollY{overflow-y:auto!important}.mainAnimatedPage{contain:style size!important}.pageContainer{overflow-x:visible!important}.bodyWithPopupOpen{overflow-y:hidden!important}div[data-role=page]{outline:0}.pageTitle{margin-top:0;font-family:inherit}.fieldDescription{padding-left:.15em;font-weight:400;white-space:normal!important}.fieldDescription+.fieldDescription{margin-top:.3em}.content-primary,.padded-bottom-page,.page,.pageWithAbsoluteTabs .pageTabContent{padding-bottom:14em!important}.supporterPromotionContainer{margin:0 0 2em}@media all and (min-width:80em){.supporterPromotionContainer{position:fixed;top:120px;right:0}}.fullWidthContent .supporterPromotionContainer{position:static!important}@media all and (min-width:50em){.readOnlyContent,form{max-width:54em}.supporterPromotionContainer{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;flex-direction:row-reverse}.supporterPromotion{text-align:center;padding:0 2em}.supporterPromotion button{padding-left:2em;padding-right:2em}}.imageDropZone{border:.2em dashed currentcolor;-webkit-border-radius:.25em;border-radius:.25em;text-align:center;position:relative;height:12em;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.squareImageDropZone{height:12em;width:12em}.headerHelpButton{margin-left:1.25em!important;padding-bottom:.4em!important;padding-top:.4em!important} \ No newline at end of file +body,html{margin:0;padding:0;height:100%}.backgroundContainer{position:fixed;top:0;left:0;right:0;bottom:0;contain:strict}html{background-color:#242424;line-height:1.35}.layout-mobile,.layout-tv{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body{overflow-y:scroll!important;overflow-x:hidden;background-color:transparent!important;-webkit-font-smoothing:antialiased}body.autoScrollY{overflow-y:auto!important}.mainAnimatedPage{contain:style size!important}.pageContainer{overflow-x:visible!important}.bodyWithPopupOpen{overflow-y:hidden!important}div[data-role=page]{outline:0}.pageTitle{margin-top:0;font-family:inherit}.fieldDescription{padding-left:.15em;font-weight:400;white-space:normal!important}.fieldDescription+.fieldDescription{margin-top:.3em}.content-primary,.padded-bottom-page,.page,.pageWithAbsoluteTabs .pageTabContent{padding-bottom:14em!important}.supporterPromotionContainer{margin:0 0 2em}@media all and (min-width:80em){.supporterPromotionContainer{position:fixed;top:120px;right:0}}.fullWidthContent .supporterPromotionContainer{position:static!important}@media all and (min-width:50em){.readOnlyContent,form{max-width:54em}.supporterPromotionContainer{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;flex-direction:row-reverse}.supporterPromotion{text-align:center;padding:0 2em}.supporterPromotion button{padding-left:2em;padding-right:2em}}.imageDropZone{border:.2em dashed currentcolor;-webkit-border-radius:.25em;border-radius:.25em;text-align:center;position:relative;height:12em;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.squareImageDropZone{height:12em;width:12em}.headerHelpButton{margin-left:1.25em!important;padding-bottom:.4em!important;padding-top:.4em!important} \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/dashboardgeneral.html b/MediaBrowser.WebDashboard/dashboard-ui/dashboardgeneral.html index 74901457e3..bdf67e7fd8 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/dashboardgeneral.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/dashboardgeneral.html @@ -5,12 +5,14 @@
-
-
+
+

${TabSettings}

${Help}
+
+
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/dashboardhosting.html b/MediaBrowser.WebDashboard/dashboard-ui/dashboardhosting.html index 964447a639..cd8cd23b58 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/dashboardhosting.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/dashboardhosting.html @@ -6,7 +6,7 @@
-
+

${TabHosting}

${Help}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/device.html b/MediaBrowser.WebDashboard/dashboard-ui/device.html index 1255b21d65..3623b8597d 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/device.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/device.html @@ -7,7 +7,7 @@
-
+ diff --git a/MediaBrowser.WebDashboard/dashboard-ui/devices.html b/MediaBrowser.WebDashboard/dashboard-ui/devices.html index 8507ece54c..cc143e5f43 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/devices.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/devices.html @@ -3,7 +3,7 @@
-
+

${TabDevices}

${Help} diff --git a/MediaBrowser.WebDashboard/dashboard-ui/devices/ios/ios.css b/MediaBrowser.WebDashboard/dashboard-ui/devices/ios/ios.css index 59f6182325..29a54288b8 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/devices/ios/ios.css +++ b/MediaBrowser.WebDashboard/dashboard-ui/devices/ios/ios.css @@ -1 +1 @@ -html{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.backdropContainer{background-attachment:initial}.dialog{background:rgba(28,28,28,.84);-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.formDialogFooter{position:static!important;margin:0 -1em!important} \ No newline at end of file +html{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:86%!important}.backdropContainer{background-attachment:initial}.dialog{background:rgba(28,28,28,.84);-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.formDialogFooter{position:static!important;margin:0 -1em!important} \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/dashboard-ui/devicesupload.html b/MediaBrowser.WebDashboard/dashboard-ui/devicesupload.html index 1c132851f3..216d42d079 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/devicesupload.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/devicesupload.html @@ -6,7 +6,7 @@
-
+

${TabCameraUpload}

${Help}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofile.html b/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofile.html index b749df8648..c6fc9bac63 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofile.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofile.html @@ -6,7 +6,7 @@
-
+

${HeaderProfileInformation}

${Help}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofiles.html b/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofiles.html index c24171ed6a..dbfc865e7b 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofiles.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/dlnaprofiles.html @@ -1,27 +1,32 @@ -
+
-
-

${HeaderCustomDlnaProfiles}

- - - +
+
+

${HeaderCustomDlnaProfiles}

+ + + + ${Help} +
+ +

${CustomDlnaProfilesHelp}

+
-

${CustomDlnaProfilesHelp}

-
+
+
+

${HeaderSystemDlnaProfiles}

+
-
-

${HeaderSystemDlnaProfiles}

- -

${SystemDlnaProfilesHelp}

- -
+

${SystemDlnaProfilesHelp}

+
+
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/dlnasettings.html b/MediaBrowser.WebDashboard/dashboard-ui/dlnasettings.html index fc4d259539..35173131a8 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/dlnasettings.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/dlnasettings.html @@ -1,10 +1,22 @@ -
+
+
+
+

${TabSettings}

+ ${Help} +
+ +
+ +
${LabelRemoteClientBitrateLimitHelp}
+
+
+
- +
${LabelEnableDlnaClientDiscoveryIntervalHelp}
@@ -43,7 +55,7 @@
- +
${LabelBlastMessageIntervalHelp}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/encodingsettings.html b/MediaBrowser.WebDashboard/dashboard-ui/encodingsettings.html index b5342899e0..f544e9f0f2 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/encodingsettings.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/encodingsettings.html @@ -6,7 +6,7 @@
-
+

${TabTranscoding}

${Help}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/home/favorites.js b/MediaBrowser.WebDashboard/dashboard-ui/home/favorites.js index 56c73ce170..d4a564cefe 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/home/favorites.js +++ b/MediaBrowser.WebDashboard/dashboard-ui/home/favorites.js @@ -1 +1 @@ -define(["appRouter","cardBuilder","dom","globalize","connectionManager","apphost","layoutManager","focusManager","emby-itemscontainer","emby-scroller"],function(appRouter,cardBuilder,dom,globalize,connectionManager,appHost,layoutManager,focusManager){"use strict";function enableScrollX(){return!0}function getThumbShape(){return enableScrollX()?"overflowBackdrop":"backdrop"}function getPosterShape(){return enableScrollX()?"overflowPortrait":"portrait"}function getSquareShape(){return enableScrollX()?"overflowSquare":"square"}function getSections(){return[{name:"sharedcomponents#HeaderFavoriteMovies",types:"Movie",shape:getPosterShape(),showTitle:!0,showYear:!0,overlayPlayButton:!0,overlayText:!1,centerText:!0},{name:"sharedcomponents#HeaderFavoriteShows",types:"Series",shape:getPosterShape(),showTitle:!0,showYear:!0,overlayPlayButton:!0,overlayText:!1,centerText:!0},{name:"sharedcomponents#HeaderFavoriteEpisodes",types:"Episode",shape:getThumbShape(),preferThumb:!1,showTitle:!0,showParentTitle:!0,overlayPlayButton:!0,overlayText:!1,centerText:!0},{name:"sharedcomponents#HeaderFavoriteVideos",types:"Video",shape:getThumbShape(),preferThumb:!0,showTitle:!0,overlayPlayButton:!0,overlayText:!1,centerText:!0},{name:"sharedcomponents#HeaderFavoriteCollections",types:"BoxSet",shape:getPosterShape(),showTitle:!0,overlayPlayButton:!0,overlayText:!1,centerText:!0},{name:"sharedcomponents#HeaderFavoritePlaylists",types:"Playlist",shape:getSquareShape(),preferThumb:!1,showTitle:!0,overlayText:!1,showParentTitle:!1,centerText:!0,overlayPlayButton:!0,coverImage:!0},{name:"sharedcomponents#HeaderFavoriteArtists",types:"MusicArtist",shape:getSquareShape(),preferThumb:!1,showTitle:!0,overlayText:!1,showParentTitle:!1,centerText:!0,overlayPlayButton:!0,coverImage:!0},{name:"sharedcomponents#HeaderFavoriteAlbums",types:"MusicAlbum",shape:getSquareShape(),preferThumb:!1,showTitle:!0,overlayText:!1,showParentTitle:!0,centerText:!0,overlayPlayButton:!0,coverImage:!0},{name:"sharedcomponents#HeaderFavoriteSongs",types:"Audio",shape:getSquareShape(),preferThumb:!1,showTitle:!0,overlayText:!1,showParentTitle:!0,centerText:!0,overlayMoreButton:!0,action:"instantmix",coverImage:!0},{name:"sharedcomponents#HeaderFavoriteGames",types:"Game",shape:getSquareShape(),preferThumb:!1,showTitle:!0}]}function getFetchDataFn(section){return function(){var apiClient=this.apiClient,options={SortBy:"SortName",SortOrder:"Ascending",Filters:"IsFavorite",Recursive:!0,Fields:"PrimaryImageAspectRatio,BasicSyncInfo",CollapseBoxSetItems:!1,ExcludeLocationTypes:"Virtual",EnableTotalRecordCount:!1};options.Limit=20;var userId=apiClient.getCurrentUserId();return"MusicArtist"===section.types?apiClient.getArtists(userId,options):(options.IncludeItemTypes=section.types,apiClient.getItems(userId,options))}}function getRouteUrl(section,serverId){return appRouter.getRouteUrl("list",{serverId:serverId,itemTypes:section.types,isFavorite:!0})}function getItemsHtmlFn(section){return function(items){var supportsImageAnalysis=appHost.supports("imageanalysis"),cardLayout=(appHost.preferVisualCards||supportsImageAnalysis)&§ion.autoCardLayout&§ion.showTitle;cardLayout=!1;var serverId=this.apiClient.serverId(),leadingButtons=layoutManager.tv?[{name:globalize.translate("sharedcomponents#All"),id:"more",icon:"",routeUrl:getRouteUrl(section,serverId)}]:null,lines=0;return section.showTitle&&lines++,section.showYear&&lines++,section.showParentTitle&&lines++,cardBuilder.getCardsHtml({items:items,preferThumb:section.preferThumb,shape:section.shape,centerText:section.centerText&&!cardLayout,overlayText:!1!==section.overlayText,showTitle:section.showTitle,showYear:section.showYear,showParentTitle:section.showParentTitle,scalable:!0,coverImage:section.coverImage,overlayPlayButton:section.overlayPlayButton,overlayMoreButton:section.overlayMoreButton&&!cardLayout,action:section.action,allowBottomPadding:!enableScrollX(),cardLayout:cardLayout,vibrant:supportsImageAnalysis&&cardLayout,leadingButtons:leadingButtons,lines:lines})}}function FavoritesTab(view,params){this.view=view,this.params=params,this.apiClient=connectionManager.currentApiClient(),this.sectionsContainer=view.querySelector(".sections"),createSections(this,this.sectionsContainer,this.apiClient)}function createSections(instance,elem,apiClient){var i,length,sections=getSections(),html="";for(i=0,length=sections.length;i',html+='
',layoutManager.tv?html+='

'+globalize.translate(section.name)+"

":(html+='',html+='

',html+=globalize.translate(section.name),html+="

",html+='',html+="
"),html+="
",html+='
',html+="
"}elem.innerHTML=html;var elems=elem.querySelectorAll(".itemsContainer");for(i=0,length=elems.length;i',html+='
',layoutManager.tv?html+='

'+globalize.translate(section.name)+"

":(html+='',html+='

',html+=globalize.translate(section.name),html+="

",html+='',html+="
"),html+="
",html+='
',html+="
"}elem.innerHTML=html;var elems=elem.querySelectorAll(".itemsContainer");for(i=0,length=elems.length;i
-
-
-
-
-
-
+
-
+
@@ -76,7 +76,7 @@

-
+
-
+

${HeaderAllRecordings}

-
-
-

${HeaderRecordingGroups}

-
-
-
@@ -110,7 +104,7 @@

${HeaderActiveRecordings

-
+
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/livetvsettings.html b/MediaBrowser.WebDashboard/dashboard-ui/livetvsettings.html index 7a4e026f4e..e513f2cea3 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/livetvsettings.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/livetvsettings.html @@ -1,4 +1,4 @@ -
+
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/livetvstatus.html b/MediaBrowser.WebDashboard/dashboard-ui/livetvstatus.html index 2e75155070..82e41ed70c 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/livetvstatus.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/livetvstatus.html @@ -4,10 +4,10 @@
-
+
-
-

${HeaderTunerDevices}

+
+

${HeaderTunerDevices}

diff --git a/MediaBrowser.WebDashboard/dashboard-ui/livetvtuner.html b/MediaBrowser.WebDashboard/dashboard-ui/livetvtuner.html index 083d566e49..0356109b9a 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/livetvtuner.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/livetvtuner.html @@ -5,7 +5,7 @@
-
+

${HeaderLiveTvTunerSetup}

${Help}
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/movies.html b/MediaBrowser.WebDashboard/dashboard-ui/movies.html index b71cd60651..0ad802ef5e 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/movies.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/movies.html @@ -1,7 +1,7 @@ 
-
+
@@ -13,13 +13,13 @@
-
+
-
+

${HeaderContinueWatching}

@@ -28,7 +28,7 @@

${HeaderContinueWatching

-
+

${HeaderLatestMovies}

-
+
@@ -58,24 +58,24 @@

${HeaderLatestMovies}

-
+
-
+
-
+
-
+
@@ -84,7 +84,7 @@

${HeaderLatestMovies}

-
+
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/music.html b/MediaBrowser.WebDashboard/dashboard-ui/music.html index 2ffa4d102f..58f2602753 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/music.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/music.html @@ -35,7 +35,7 @@

${HeaderFrequentlyPlayed

-
+
@@ -49,12 +49,12 @@

${HeaderFrequentlyPlayed
-
+
-
+
@@ -65,12 +65,12 @@

${HeaderFrequentlyPlayed
-
+
-
+
@@ -81,29 +81,29 @@

${HeaderFrequentlyPlayed
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/notificationsetting.html b/MediaBrowser.WebDashboard/dashboard-ui/notificationsetting.html index a263a67dc2..5938672304 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/notificationsetting.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/notificationsetting.html @@ -6,7 +6,7 @@
-
+ diff --git a/MediaBrowser.WebDashboard/dashboard-ui/notificationsettings.html b/MediaBrowser.WebDashboard/dashboard-ui/notificationsettings.html index e7808775b8..148069acd5 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/notificationsettings.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/notificationsettings.html @@ -1,4 +1,4 @@ -
+
diff --git a/MediaBrowser.WebDashboard/dashboard-ui/plugincatalog.html b/MediaBrowser.WebDashboard/dashboard-ui/plugincatalog.html index 8647ceae14..9f66fefc77 100644 --- a/MediaBrowser.WebDashboard/dashboard-ui/plugincatalog.html +++ b/MediaBrowser.WebDashboard/dashboard-ui/plugincatalog.html @@ -3,7 +3,7 @@
-
+