Merge branch 'master' into usings

This commit is contained in:
Bond-009
2020-04-01 22:42:43 +02:00
committed by GitHub
67 changed files with 538 additions and 317 deletions

View File

@@ -5,7 +5,7 @@ using MediaBrowser.Common.Configuration;
namespace Emby.Server.Implementations.AppBase
{
/// <summary>
/// Provides a base class to hold common application paths used by both the Ui and Server.
/// Provides a base class to hold common application paths used by both the UI and Server.
/// This can be subclassed to add application-specific paths.
/// </summary>
public abstract class BaseApplicationPaths : IApplicationPaths
@@ -37,10 +37,7 @@ namespace Emby.Server.Implementations.AppBase
/// <value>The program data path.</value>
public string ProgramDataPath { get; }
/// <summary>
/// Gets the path to the web UI resources folder.
/// </summary>
/// <value>The web UI resources path.</value>
/// <inheritdoc/>
public string WebPath { get; }
/// <summary>

View File

@@ -235,11 +235,6 @@ namespace Emby.Server.Implementations
/// </summary>
public int HttpsPort { get; private set; }
/// <summary>
/// Gets the content root for the webhost.
/// </summary>
public string ContentRoot { get; private set; }
/// <summary>
/// Gets the server configuration manager.
/// </summary>
@@ -612,13 +607,7 @@ namespace Emby.Server.Implementations
DiscoverTypes();
await RegisterResources(serviceCollection, startupConfig).ConfigureAwait(false);
ContentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath;
if (string.IsNullOrEmpty(ContentRoot))
{
ContentRoot = ServerConfigurationManager.ApplicationPaths.WebPath;
}
await RegisterServices(serviceCollection, startupConfig).ConfigureAwait(false);
}
public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
@@ -649,9 +638,9 @@ namespace Emby.Server.Implementations
}
/// <summary>
/// Registers resources that classes will depend on
/// Registers services/resources with the service collection that will be available via DI.
/// </summary>
protected async Task RegisterResources(IServiceCollection serviceCollection, IConfiguration startupConfig)
protected async Task RegisterServices(IServiceCollection serviceCollection, IConfiguration startupConfig)
{
serviceCollection.AddMemoryCache();
@@ -769,20 +758,8 @@ namespace Emby.Server.Implementations
CertificateInfo = GetCertificateInfo(true);
Certificate = GetCertificate(CertificateInfo);
HttpServer = new HttpListenerHost(
this,
LoggerFactory.CreateLogger<HttpListenerHost>(),
ServerConfigurationManager,
startupConfig,
NetworkManager,
JsonSerializer,
XmlSerializer,
CreateHttpListener())
{
GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading")
};
serviceCollection.AddSingleton(HttpServer);
serviceCollection.AddSingleton<IHttpListener, WebSocketSharpListener>();
serviceCollection.AddSingleton<IHttpServer, HttpListenerHost>();
ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger<ImageProcessor>(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => LibraryManager, () => MediaEncoder);
serviceCollection.AddSingleton(ImageProcessor);
@@ -844,10 +821,15 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IDeviceDiscovery>(new DeviceDiscovery(ServerConfigurationManager));
ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository);
ChapterManager = new ChapterManager(ItemRepository);
serviceCollection.AddSingleton(ChapterManager);
EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
EncodingManager = new MediaEncoder.EncodingManager(
LoggerFactory.CreateLogger<MediaEncoder.EncodingManager>(),
FileSystemManager,
MediaEncoder,
ChapterManager,
LibraryManager);
serviceCollection.AddSingleton(EncodingManager);
var activityLogRepo = GetActivityLogRepository();
@@ -890,6 +872,14 @@ namespace Emby.Server.Implementations
((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
}
/// <summary>
/// Create services registered with the service container that need to be initialized at application startup.
/// </summary>
public void InitializeServices()
{
HttpServer = Resolve<IHttpServer>();
}
public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths)
{
// Distinct these to prevent users from reporting problems that aren't actually problems
@@ -1167,7 +1157,7 @@ namespace Emby.Server.Implementations
{
exportedTypes = ass.GetExportedTypes();
}
catch (TypeLoadException ex)
catch (FileNotFoundException ex)
{
Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName);
continue;
@@ -1207,8 +1197,6 @@ namespace Emby.Server.Implementations
});
}
protected IHttpListener CreateHttpListener() => new WebSocketSharpListener(LoggerFactory.CreateLogger<WebSocketSharpListener>());
private CertificateInfo GetCertificateInfo(bool generateCertificate)
{
// Custom cert

View File

@@ -1,51 +1,48 @@
using System;
using MediaBrowser.Controller;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Browser
{
/// <summary>
/// Class BrowserLauncher.
/// Assists in opening application URLs in an external browser.
/// </summary>
public static class BrowserLauncher
{
/// <summary>
/// Opens the dashboard page.
/// </summary>
/// <param name="page">The page.</param>
/// <param name="appHost">The app host.</param>
private static void OpenDashboardPage(string page, IServerApplicationHost appHost)
{
var url = appHost.GetLocalApiUrl("localhost") + "/web/" + page;
OpenUrl(appHost, url);
}
/// <summary>
/// Opens the web client.
/// Opens the home page of the web client.
/// </summary>
/// <param name="appHost">The app host.</param>
public static void OpenWebApp(IServerApplicationHost appHost)
{
OpenDashboardPage("index.html", appHost);
TryOpenUrl(appHost, "/web/index.html");
}
/// <summary>
/// Opens the URL.
/// Opens the swagger API page.
/// </summary>
/// <param name="appHost">The application host instance.</param>
/// <param name="appHost">The app host.</param>
public static void OpenSwaggerPage(IServerApplicationHost appHost)
{
TryOpenUrl(appHost, "/swagger/index.html");
}
/// <summary>
/// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored.
/// </summary>
/// <param name="appHost">The application host.</param>
/// <param name="url">The URL.</param>
private static void OpenUrl(IServerApplicationHost appHost, string url)
private static void TryOpenUrl(IServerApplicationHost appHost, string url)
{
try
{
appHost.LaunchUrl(url);
string baseUrl = appHost.GetLocalApiUrl("localhost");
appHost.LaunchUrl(baseUrl + url);
}
catch (NotSupportedException)
{
}
catch (Exception)
catch (Exception ex)
{
var logger = appHost.Resolve<ILogger>();
logger?.LogError(ex, "Failed to open browser window with URL {URL}", url);
}
}
}

View File

@@ -1,13 +1,22 @@
using System.Collections.Generic;
using Emby.Server.Implementations.HttpServer;
using MediaBrowser.Providers.Music;
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
namespace Emby.Server.Implementations
{
/// <summary>
/// Static class containing the default configuration options for the web server.
/// </summary>
public static class ConfigurationOptions
{
public static Dictionary<string, string> Configuration => new Dictionary<string, string>
/// <summary>
/// Gets a new copy of the default configuration options.
/// </summary>
public static Dictionary<string, string> DefaultConfiguration => new Dictionary<string, string>
{
{ "HttpListenerHost:DefaultRedirectPath", "web/index.html" },
{ HostWebClientKey, bool.TrueString },
{ HttpListenerHost.DefaultRedirectKey, "web/index.html" },
{ FfmpegProbeSizeKey, "1G" },
{ FfmpegAnalyzeDurationKey, "200M" },
{ PlaylistsAllowDuplicatesKey, bool.TrueString }

View File

@@ -2006,7 +2006,7 @@ namespace Emby.Server.Implementations.Data
/// <summary>
/// Saves the chapters.
/// </summary>
public void SaveChapters(Guid id, List<ChapterInfo> chapters)
public void SaveChapters(Guid id, IReadOnlyList<ChapterInfo> chapters)
{
CheckDisposed();
@@ -2035,22 +2035,24 @@ namespace Emby.Server.Implementations.Data
}
}
private void InsertChapters(byte[] idBlob, List<ChapterInfo> chapters, IDatabaseConnection db)
private void InsertChapters(byte[] idBlob, IReadOnlyList<ChapterInfo> chapters, IDatabaseConnection db)
{
var startIndex = 0;
var limit = 100;
var chapterIndex = 0;
const string StartInsertText = "insert into " + ChaptersTableName + " (ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath, ImageDateModified) values ";
var insertText = new StringBuilder(StartInsertText, 256);
while (startIndex < chapters.Count)
{
var insertText = new StringBuilder("insert into " + ChaptersTableName + " (ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath, ImageDateModified) values ");
var endIndex = Math.Min(chapters.Count, startIndex + limit);
for (var i = startIndex; i < endIndex; i++)
{
insertText.AppendFormat("(@ItemId, @ChapterIndex{0}, @StartPositionTicks{0}, @Name{0}, @ImagePath{0}, @ImageDateModified{0}),", i.ToString(CultureInfo.InvariantCulture));
}
insertText.Length -= 1; // Remove last ,
using (var statement = PrepareStatement(db, insertText.ToString()))
@@ -2077,6 +2079,7 @@ namespace Emby.Server.Implementations.Data
}
startIndex += limit;
insertText.Length = StartInsertText.Length;
}
}

View File

@@ -2,7 +2,9 @@ using System.Threading.Tasks;
using Emby.Server.Implementations.Browser;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Controller.Plugins;
using Microsoft.Extensions.Configuration;
namespace Emby.Server.Implementations.EntryPoints
{
@@ -11,10 +13,8 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
public sealed class StartupWizard : IServerEntryPoint
{
/// <summary>
/// The app host.
/// </summary>
private readonly IServerApplicationHost _appHost;
private readonly IConfiguration _appConfig;
private readonly IServerConfigurationManager _config;
/// <summary>
@@ -22,9 +22,10 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
/// <param name="appHost">The application host.</param>
/// <param name="config">The configuration manager.</param>
public StartupWizard(IServerApplicationHost appHost, IServerConfigurationManager config)
public StartupWizard(IServerApplicationHost appHost, IConfiguration appConfig, IServerConfigurationManager config)
{
_appHost = appHost;
_appConfig = appConfig;
_config = config;
}
@@ -36,7 +37,11 @@ namespace Emby.Server.Implementations.EntryPoints
return Task.CompletedTask;
}
if (!_config.Configuration.IsStartupWizardCompleted)
if (!_appConfig.HostWebClient())
{
BrowserLauncher.OpenSwaggerPage(_appHost);
}
else if (!_config.Configuration.IsStartupWizardCompleted)
{
BrowserLauncher.OpenWebApp(_appHost);
}

View File

@@ -17,6 +17,7 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
@@ -29,6 +30,12 @@ namespace Emby.Server.Implementations.HttpServer
{
public class HttpListenerHost : IHttpServer, IDisposable
{
/// <summary>
/// The key for a setting that specifies the default redirect path
/// to use for requests where the URL base prefix is invalid or missing.
/// </summary>
public const string DefaultRedirectKey = "HttpListenerHost:DefaultRedirectPath";
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
@@ -52,12 +59,13 @@ namespace Emby.Server.Implementations.HttpServer
INetworkManager networkManager,
IJsonSerializer jsonSerializer,
IXmlSerializer xmlSerializer,
IHttpListener socketListener)
IHttpListener socketListener,
ILocalizationManager localizationManager)
{
_appHost = applicationHost;
_logger = logger;
_config = config;
_defaultRedirectPath = configuration["HttpListenerHost:DefaultRedirectPath"];
_defaultRedirectPath = configuration[DefaultRedirectKey];
_baseUrlPrefix = _config.Configuration.BaseUrl;
_networkManager = networkManager;
_jsonSerializer = jsonSerializer;
@@ -69,6 +77,7 @@ namespace Emby.Server.Implementations.HttpServer
Instance = this;
ResponseFilters = Array.Empty<Action<IRequest, HttpResponse, object>>();
GlobalResponse = localizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
}
public event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.IO;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Threading.Tasks;
using MediaBrowser.Controller.Plugins;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Threading;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Globalization;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using MediaBrowser.Controller.LiveTv;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Concurrent;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Concurrent;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic;
using MediaBrowser.Common.Configuration;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Globalization;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Concurrent;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Buffers;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System;
using System.Collections.Generic;

View File

@@ -1,8 +1,8 @@
{
"Albums": "Албуми",
"AppDeviceValues": "Програма: {0}, устройство: {1}",
"AppDeviceValues": "Програма: {0}, Устройство: {1}",
"Application": "Програма",
"Artists": "Изпълнители",
"Artists": "Артисти",
"AuthenticationSucceededWithUserName": "{0} се удостовери успешно",
"Books": "Книги",
"CameraImageUploadedFrom": "Нова снимка от камера беше качена от {0}",
@@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} спря {1}",
"ValueHasBeenAddedToLibrary": "{0} беше добавен във Вашата библиотека",
"ValueSpecialEpisodeName": "Специални - {0}",
"VersionNumber": "Версия {0}"
"VersionNumber": "Версия {0}",
"TaskDownloadMissingSubtitlesDescription": "Търси Интернет за липсващи поднадписи, на база конфигурацията за мета-данни.",
"TaskDownloadMissingSubtitles": "Изтегляне на липсващи поднадписи",
"TaskRefreshChannelsDescription": "Обновява информацията за интернет канала.",
"TaskRefreshChannels": "Обновяване на Канали",
"TaskCleanTranscodeDescription": "Изтрива прекодирани файлове по-стари от един ден.",
"TaskCleanTranscode": "Изчиства директорията за прекодиране",
"TaskUpdatePluginsDescription": "Изтегля и инсталира актуализации за добавките, които са настроени за автоматична актуализация.",
"TaskUpdatePlugins": "Актуализира добавките",
"TaskRefreshPeopleDescription": "Актуализира мета-данните за артистите и режисьорите за Вашата медийна библиотека.",
"TaskRefreshPeople": "Обновяване на участниците",
"TaskCleanLogsDescription": "Изтрива лог файлове по-стари от {0} дни.",
"TaskCleanLogs": "Изчисти директорията с логове",
"TaskRefreshLibraryDescription": "Сканира Вашата библиотека с медия за нови файлове и обновява мета-данните.",
"TaskRefreshLibrary": "Сканиране на библиотеката с медия",
"TaskRefreshChapterImagesDescription": "Създава иконки за видеа, които имат епизоди.",
"TaskRefreshChapterImages": "Извличане на изображения за епизода",
"TaskCleanCacheDescription": "Изтриване на ненужните от системата файлове.",
"TaskCleanCache": "Изчистване на Кеш-директорията",
"TasksChannelsCategory": "Интернет Канали",
"TasksApplicationCategory": "Приложение",
"TasksLibraryCategory": "Библиотека",
"TasksMaintenanceCategory": "Поддръжка"
}

View File

@@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} vient d'arrêter la lecture de {1} sur {2}",
"ValueHasBeenAddedToLibrary": "{0} a été ajouté à votre médiathèque",
"ValueSpecialEpisodeName": "Spécial - {0}",
"VersionNumber": "Version {0}"
"VersionNumber": "Version {0}",
"TasksChannelsCategory": "Chaines en ligne",
"TaskDownloadMissingSubtitlesDescription": "Cherche les sous-titres manquant sur internet en se basant sur la configuration des métadonnées.",
"TaskDownloadMissingSubtitles": "Télécharge les sous-titres manquant",
"TaskRefreshChannelsDescription": "Rafraîchit les informations des chaines en ligne.",
"TaskRefreshChannels": "Rafraîchit les chaines",
"TaskCleanTranscodeDescription": "Supprime les fichiers transcodés de plus d'un jour.",
"TaskCleanTranscode": "Nettoie les dossier des transcodages",
"TaskUpdatePluginsDescription": "Télécharge et installe les mises à jours des plugins configurés pour être mis à jour automatiquement.",
"TaskUpdatePlugins": "Mettre à jour les plugins",
"TaskRefreshPeopleDescription": "Met à jour les métadonnées pour les acteurs et directeurs dans votre bibliothèque.",
"TaskRefreshPeople": "Rafraîchit les acteurs",
"TaskCleanLogsDescription": "Supprime les journaux de plus de {0} jours.",
"TaskCleanLogs": "Nettoie le répertoire des journaux",
"TaskRefreshLibraryDescription": "Scanne toute les bibliothèques pour trouver les nouveaux fichiers et rafraîchit les métadonnées.",
"TaskRefreshLibrary": "Scanne toute les Bibliothèques",
"TaskRefreshChapterImagesDescription": "Crée des images de miniature pour les vidéos ayant des chapitres.",
"TaskRefreshChapterImages": "Extrait les images de chapitre",
"TaskCleanCacheDescription": "Supprime les fichiers de cache dont le système n'a plus besoin.",
"TaskCleanCache": "Vider le répertoire cache",
"TasksApplicationCategory": "Application",
"TasksLibraryCategory": "Bibliothèque",
"TasksMaintenanceCategory": "Maintenance"
}

View File

@@ -5,7 +5,7 @@
"Artists": "Artisti",
"AuthenticationSucceededWithUserName": "{0} autenticato con successo",
"Books": "Libri",
"CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera da {0}",
"CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera dal device {0}",
"Channels": "Canali",
"ChapterNameValue": "Capitolo {0}",
"Collections": "Collezioni",
@@ -15,7 +15,7 @@
"Favorites": "Preferiti",
"Folders": "Cartelle",
"Genres": "Generi",
"HeaderAlbumArtists": "Artisti dell' Album",
"HeaderAlbumArtists": "Artisti degli Album",
"HeaderCameraUploads": "Caricamenti Fotocamera",
"HeaderContinueWatching": "Continua a guardare",
"HeaderFavoriteAlbums": "Album Preferiti",
@@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} ha interrotto la riproduzione di {1} su {2}",
"ValueHasBeenAddedToLibrary": "{0} è stato aggiunto alla tua libreria multimediale",
"ValueSpecialEpisodeName": "Speciale - {0}",
"VersionNumber": "Versione {0}"
"VersionNumber": "Versione {0}",
"TaskRefreshChannelsDescription": "Aggiorna le informazioni dei canali Internet.",
"TaskDownloadMissingSubtitlesDescription": "Cerca su internet i sottotitoli mancanti basandosi sulle configurazioni dei metadati.",
"TaskDownloadMissingSubtitles": "Scarica i sottotitoli mancanti",
"TaskRefreshChannels": "Aggiorna i canali",
"TaskCleanTranscodeDescription": "Cancella i file di transcode più vecchi di un giorno.",
"TaskCleanTranscode": "Svuota la cartella del transcoding",
"TaskUpdatePluginsDescription": "Scarica e installa gli aggiornamenti per i plugin che sono stati configurati per essere aggiornati contemporaneamente.",
"TaskUpdatePlugins": "Aggiorna i Plugin",
"TaskRefreshPeopleDescription": "Aggiorna i metadati per gli attori e registi nella tua libreria multimediale.",
"TaskRefreshPeople": "Aggiorna persone",
"TaskCleanLogsDescription": "Rimuovi i file di log più vecchi di {0} giorni.",
"TaskCleanLogs": "Pulisci la cartella dei log",
"TaskRefreshLibraryDescription": "Analizza la tua libreria multimediale per nuovi file e rinnova i metadati.",
"TaskRefreshLibrary": "Analizza la libreria dei contenuti multimediali",
"TaskRefreshChapterImagesDescription": "Crea le thumbnail per i video che hanno capitoli.",
"TaskRefreshChapterImages": "Estrai immagini capitolo",
"TaskCleanCacheDescription": "Cancella i file di cache non più necessari al sistema.",
"TaskCleanCache": "Pulisci la directory della cache",
"TasksChannelsCategory": "Canali su Internet",
"TasksApplicationCategory": "Applicazione",
"TasksLibraryCategory": "Libreria",
"TasksMaintenanceCategory": "Manutenzione"
}

View File

@@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} parou de reproduzir {1} em {2}",
"ValueHasBeenAddedToLibrary": "{0} foi adicionado à sua biblioteca de mídia",
"ValueSpecialEpisodeName": "Especial - {0}",
"VersionNumber": "Versão {0}"
"VersionNumber": "Versão {0}",
"TaskDownloadMissingSubtitlesDescription": "Procurar na internet por legendas faltando baseado na configuração de metadados.",
"TaskDownloadMissingSubtitles": "Baixar legendas que estão faltando",
"TaskRefreshChannelsDescription": "Atualizar informação de canais da internet .",
"TaskRefreshChannels": "Atualizar Canais",
"TaskCleanTranscodeDescription": "Deletar arquivos de transcodificação com mais de um dia de criação.",
"TaskCleanTranscode": "Limpar pasta de transcodificação",
"TaskUpdatePluginsDescription": "Baixa e instala atualizações para plugins que estão configurados para atualizar automaticamente.",
"TaskUpdatePlugins": "Atualizar Plugins",
"TaskRefreshPeopleDescription": "Atualiza metadados para atores e diretores na sua biblioteca de mídia.",
"TaskRefreshPeople": "Atualizar pessoas",
"TaskCleanLogsDescription": "Deletar arquivos temporários com mais de {0} dias.",
"TaskCleanLogs": "Limpar pasta de logs",
"TaskRefreshLibraryDescription": "Escaneie a sua biblioteca de mídia para arquivos novos e atualize os metadados.",
"TaskRefreshLibrary": "Escanear a Biblioteca de Mídia",
"TaskRefreshChapterImagesDescription": "Criar miniaturas para vídeos que tem capítulos.",
"TaskRefreshChapterImages": "Extrair imagens dos capítulos",
"TaskCleanCacheDescription": "Deletar arquivos temporários que não são mais necessários para o sistema.",
"TaskCleanCache": "Limpar Arquivos Temporários",
"TasksChannelsCategory": "Canais da Internet",
"TasksApplicationCategory": "Aplicativo",
"TasksLibraryCategory": "Biblioteca",
"TasksMaintenanceCategory": "Manutenção"
}

View File

@@ -26,14 +26,20 @@ namespace Emby.Server.Implementations.MediaEncoder
private readonly IChapterManager _chapterManager;
private readonly ILibraryManager _libraryManager;
/// <summary>
/// The first chapter ticks.
/// </summary>
private static readonly long _firstChapterTicks = TimeSpan.FromSeconds(15).Ticks;
public EncodingManager(
ILogger<EncodingManager> logger,
IFileSystem fileSystem,
ILoggerFactory loggerFactory,
IMediaEncoder encoder,
IChapterManager chapterManager, ILibraryManager libraryManager)
IChapterManager chapterManager,
ILibraryManager libraryManager)
{
_logger = logger;
_fileSystem = fileSystem;
_logger = loggerFactory.CreateLogger(nameof(EncodingManager));
_encoder = encoder;
_chapterManager = chapterManager;
_libraryManager = libraryManager;
@@ -97,12 +103,7 @@ namespace Emby.Server.Implementations.MediaEncoder
return video.DefaultVideoStreamIndex.HasValue;
}
/// <summary>
/// The first chapter ticks
/// </summary>
private static readonly long FirstChapterTicks = TimeSpan.FromSeconds(15).Ticks;
public async Task<bool> RefreshChapterImages(Video video, IDirectoryService directoryService, List<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken)
public async Task<bool> RefreshChapterImages(Video video, IDirectoryService directoryService, IReadOnlyList<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken)
{
if (!IsEligibleForChapterImageExtraction(video))
{
@@ -135,7 +136,7 @@ namespace Emby.Server.Implementations.MediaEncoder
try
{
// Add some time for the first chapter to make sure we don't end up with a black image
var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks);
var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(_firstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks);
var protocol = MediaProtocol.File;
@@ -152,9 +153,9 @@ namespace Emby.Server.Implementations.MediaEncoder
{
_fileSystem.DeleteFile(tempFile);
}
catch
catch (IOException ex)
{
_logger.LogError(ex, "Error deleting temporary chapter image encoding file {Path}", tempFile);
}
chapter.ImagePath = path;
@@ -184,7 +185,7 @@ namespace Emby.Server.Implementations.MediaEncoder
if (saveChapters && changesMade)
{
_chapterManager.SaveChapters(video.Id.ToString(), chapters);
_chapterManager.SaveChapters(video.Id, chapters);
}
DeleteDeadImages(currentImages, chapters);
@@ -199,22 +200,21 @@ namespace Emby.Server.Implementations.MediaEncoder
return Path.Combine(GetChapterImagesPath(video), filename);
}
private static List<string> GetSavedChapterImages(Video video, IDirectoryService directoryService)
private static IReadOnlyList<string> GetSavedChapterImages(Video video, IDirectoryService directoryService)
{
var path = GetChapterImagesPath(video);
if (!Directory.Exists(path))
{
return new List<string>();
return Array.Empty<string>();
}
try
{
return directoryService.GetFilePaths(path)
.ToList();
return directoryService.GetFilePaths(path);
}
catch (IOException)
{
return new List<string>();
return Array.Empty<string>();
}
}
@@ -227,7 +227,7 @@ namespace Emby.Server.Implementations.MediaEncoder
foreach (var image in deadImages)
{
_logger.LogDebug("Deleting dead chapter image {path}", image);
_logger.LogDebug("Deleting dead chapter image {Path}", image);
try
{
@@ -235,7 +235,7 @@ namespace Emby.Server.Implementations.MediaEncoder
}
catch (IOException ex)
{
_logger.LogError(ex, "Error deleting {path}.", image);
_logger.LogError(ex, "Error deleting {Path}.", image);
}
}
}