diff options
34 files changed, 563 insertions, 126 deletions
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index b3191cd4b..39fcc50d8 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -8,8 +8,11 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; using ServiceStack; +using ServiceStack.Text.Controller; +using ServiceStack.Web; using System; using System.Collections.Generic; +using System.IO; using System.Linq; namespace MediaBrowser.Api @@ -23,6 +26,13 @@ namespace MediaBrowser.Api } + [Route("/System/Configuration/{Key}", "GET", Summary = "Gets a named configuration")] + public class GetNamedConfiguration + { + [ApiMember(Name = "Key", Description = "Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Key { get; set; } + } + /// <summary> /// Class UpdateConfiguration /// </summary> @@ -31,6 +41,15 @@ namespace MediaBrowser.Api { } + [Route("/System/Configuration/{Key}", "POST", Summary = "Updates named configuration")] + public class UpdateNamedConfiguration : IReturnVoid, IRequiresRequestStream + { + [ApiMember(Name = "Key", Description = "Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Key { get; set; } + + public Stream RequestStream { get; set; } + } + [Route("/System/Configuration/MetadataOptions/Default", "GET", Summary = "Gets a default MetadataOptions object")] public class GetDefaultMetadataOptions : IReturn<MetadataOptions> { @@ -88,6 +107,13 @@ namespace MediaBrowser.Api return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => _configurationManager.Configuration); } + public object Get(GetNamedConfiguration request) + { + var result = _configurationManager.GetConfiguration(request.Key); + + return ToOptimizedResult(result); + } + /// <summary> /// Posts the specified configuraiton. /// </summary> @@ -95,7 +121,6 @@ namespace MediaBrowser.Api public void Post(UpdateConfiguration request) { // Silly, but we need to serialize and deserialize or the XmlSerializer will write the xml with an element name of UpdateConfiguration - var json = _jsonSerializer.SerializeToString(request); var config = _jsonSerializer.DeserializeFromString<ServerConfiguration>(json); @@ -103,6 +128,17 @@ namespace MediaBrowser.Api _configurationManager.ReplaceConfiguration(config); } + public void Post(UpdateNamedConfiguration request) + { + var pathInfo = PathInfo.Parse(Request.PathInfo); + var key = pathInfo.GetArgumentValue<string>(2); + + var configurationType = _configurationManager.GetConfigurationType(key); + var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, configurationType); + + _configurationManager.SaveConfiguration(key, configuration); + } + public object Get(GetDefaultMetadataOptions request) { return ToOptimizedSerializedResultUsingCache(new MetadataOptions()); diff --git a/MediaBrowser.Api/Dlna/DlnaServerService.cs b/MediaBrowser.Api/Dlna/DlnaServerService.cs index 28de8ee17..82bd394f0 100644 --- a/MediaBrowser.Api/Dlna/DlnaServerService.cs +++ b/MediaBrowser.Api/Dlna/DlnaServerService.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Dlna; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Dlna; +using MediaBrowser.Model.Configuration; using ServiceStack; using ServiceStack.Text.Controller; using ServiceStack.Web; @@ -76,11 +78,14 @@ namespace MediaBrowser.Api.Dlna private readonly IContentDirectory _contentDirectory; private readonly IConnectionManager _connectionManager; - public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager) + private readonly IConfigurationManager _config; + + public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IConfigurationManager config) { _dlnaManager = dlnaManager; _contentDirectory = contentDirectory; _connectionManager = connectionManager; + _config = config; } public object Get(GetDescriptionXml request) diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 1e9ff9199..3f1d9fe67 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -101,6 +101,7 @@ <Compile Include="NotificationsService.cs" /> <Compile Include="PackageReviewService.cs" /> <Compile Include="PackageService.cs" /> + <Compile Include="Playback\BifService.cs" /> <Compile Include="Playback\EndlessStreamCopy.cs" /> <Compile Include="Playback\Hls\BaseHlsService.cs" /> <Compile Include="Playback\Hls\DynamicHlsService.cs" /> diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index 7bd0ca748..ebd6c6b59 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -342,6 +342,7 @@ namespace MediaBrowser.Common.Implementations /// </summary> protected virtual void FindParts() { + ConfigurationManager.AddParts(GetExports<IConfigurationFactory>()); Plugins = GetExports<IPlugin>(); } diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs index 8c4840ea7..60abc14f1 100644 --- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs +++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs @@ -1,10 +1,13 @@ -using System.IO; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Threading; namespace MediaBrowser.Common.Implementations.Configuration @@ -26,6 +29,11 @@ namespace MediaBrowser.Common.Implementations.Configuration public event EventHandler<EventArgs> ConfigurationUpdated; /// <summary> + /// Occurs when [named configuration updated]. + /// </summary> + public event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdated; + + /// <summary> /// Gets the logger. /// </summary> /// <value>The logger.</value> @@ -74,6 +82,9 @@ namespace MediaBrowser.Common.Implementations.Configuration } } + private ConfigurationStore[] _configurationStores = {}; + private IConfigurationFactory[] _configurationFactories; + /// <summary> /// Initializes a new instance of the <see cref="BaseConfigurationManager" /> class. /// </summary> @@ -89,10 +100,14 @@ namespace MediaBrowser.Common.Implementations.Configuration UpdateCachePath(); } - /// <summary> - /// The _save lock - /// </summary> - private readonly object _configurationSaveLock = new object(); + public void AddParts(IEnumerable<IConfigurationFactory> factories) + { + _configurationFactories = factories.ToArray(); + + _configurationStores = _configurationFactories + .SelectMany(i => i.GetConfigurations()) + .ToArray(); + } /// <summary> /// Saves the configuration. @@ -103,7 +118,7 @@ namespace MediaBrowser.Common.Implementations.Configuration Directory.CreateDirectory(Path.GetDirectoryName(path)); - lock (_configurationSaveLock) + lock (_configurationSyncLock) { XmlSerializer.SerializeToFile(CommonConfiguration, path); } @@ -144,8 +159,8 @@ namespace MediaBrowser.Common.Implementations.Configuration /// </summary> private void UpdateCachePath() { - ((BaseApplicationPaths)CommonApplicationPaths).CachePath = string.IsNullOrEmpty(CommonConfiguration.CachePath) ? - null : + ((BaseApplicationPaths)CommonApplicationPaths).CachePath = string.IsNullOrEmpty(CommonConfiguration.CachePath) ? + null : CommonConfiguration.CachePath; } @@ -168,5 +183,63 @@ namespace MediaBrowser.Common.Implementations.Configuration } } } + + private readonly ConcurrentDictionary<string, object> _configurations = new ConcurrentDictionary<string, object>(); + + private string GetConfigurationFile(string key) + { + return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLower() + ".xml"); + } + + public object GetConfiguration(string key) + { + return _configurations.GetOrAdd(key, k => + { + var file = GetConfigurationFile(key); + + var configurationType = _configurationStores + .First(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase)) + .ConfigurationType; + + lock (_configurationSyncLock) + { + return ConfigurationHelper.GetXmlConfiguration(configurationType, file, XmlSerializer); + } + }); + } + + public void SaveConfiguration(string key, object configuration) + { + var configurationType = GetConfigurationType(key); + + if (configuration.GetType() != configurationType) + { + throw new ArgumentException("Expected configuration type is " + configurationType.Name); + } + + _configurations.AddOrUpdate(key, configuration, (k, v) => configuration); + + var path = GetConfigurationFile(key); + Directory.CreateDirectory(Path.GetDirectoryName(path)); + + lock (_configurationSyncLock) + { + XmlSerializer.SerializeToFile(configuration, path); + } + + EventHelper.FireEventIfNotNull(NamedConfigurationUpdated, this, new ConfigurationUpdateEventArgs + { + Key = key, + NewConfiguration = configuration + + }, Logger); + } + + public Type GetConfigurationType(string key) + { + return _configurationStores + .First(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase)) + .ConfigurationType; + } } } diff --git a/MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs b/MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs new file mode 100644 index 000000000..310e2aa63 --- /dev/null +++ b/MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs @@ -0,0 +1,18 @@ +using System; + +namespace MediaBrowser.Common.Configuration +{ + public class ConfigurationUpdateEventArgs : EventArgs + { + /// <summary> + /// Gets or sets the key. + /// </summary> + /// <value>The key.</value> + public string Key { get; set; } + /// <summary> + /// Gets or sets the new configuration. + /// </summary> + /// <value>The new configuration.</value> + public object NewConfiguration { get; set; } + } +} diff --git a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs new file mode 100644 index 000000000..d418d0a42 --- /dev/null +++ b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Common.Configuration +{ + public interface IConfigurationFactory + { + IEnumerable<ConfigurationStore> GetConfigurations(); + } + + public class ConfigurationStore + { + public string Key { get; set; } + + public Type ConfigurationType { get; set; } + } +} diff --git a/MediaBrowser.Common/Configuration/IConfigurationManager.cs b/MediaBrowser.Common/Configuration/IConfigurationManager.cs index 0d0759b66..25698d972 100644 --- a/MediaBrowser.Common/Configuration/IConfigurationManager.cs +++ b/MediaBrowser.Common/Configuration/IConfigurationManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Model.Configuration; using System; +using System.Collections.Generic; namespace MediaBrowser.Common.Configuration { @@ -9,7 +10,12 @@ namespace MediaBrowser.Common.Configuration /// Occurs when [configuration updated]. /// </summary> event EventHandler<EventArgs> ConfigurationUpdated; - + + /// <summary> + /// Occurs when [named configuration updated]. + /// </summary> + event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdated; + /// <summary> /// Gets or sets the application paths. /// </summary> @@ -32,5 +38,40 @@ namespace MediaBrowser.Common.Configuration /// </summary> /// <param name="newConfiguration">The new configuration.</param> void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration); + + /// <summary> + /// Gets the configuration. + /// </summary> + /// <param name="key">The key.</param> + /// <returns>System.Object.</returns> + object GetConfiguration(string key); + + /// <summary> + /// Gets the type of the configuration. + /// </summary> + /// <param name="key">The key.</param> + /// <returns>Type.</returns> + Type GetConfigurationType(string key); + + /// <summary> + /// Saves the configuration. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="configuration">The configuration.</param> + void SaveConfiguration(string key, object configuration); + + /// <summary> + /// Adds the parts. + /// </summary> + /// <param name="factories">The factories.</param> + void AddParts(IEnumerable<IConfigurationFactory> factories); + } + + public static class ConfigurationManagerExtensions + { + public static T GetConfiguration<T>(this IConfigurationManager manager, string key) + { + return (T)manager.GetConfiguration(key); + } } } diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 2e7db5c35..9d5984317 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -55,7 +55,9 @@ <Link>Properties\SharedVersion.cs</Link> </Compile> <Compile Include="Configuration\ConfigurationHelper.cs" /> + <Compile Include="Configuration\ConfigurationUpdateEventArgs.cs" /> <Compile Include="Configuration\IConfigurationManager.cs" /> + <Compile Include="Configuration\IConfigurationFactory.cs" /> <Compile Include="Constants\Constants.cs" /> <Compile Include="Events\EventHelper.cs" /> <Compile Include="Extensions\BaseExtensions.cs" /> diff --git a/MediaBrowser.Common/Net/MimeTypes.cs b/MediaBrowser.Common/Net/MimeTypes.cs index d85a2fd1e..0cc4fc6b4 100644 --- a/MediaBrowser.Common/Net/MimeTypes.cs +++ b/MediaBrowser.Common/Net/MimeTypes.cs @@ -228,6 +228,11 @@ namespace MediaBrowser.Common.Net return "text/vtt"; } + if (ext.Equals(".bif", StringComparison.OrdinalIgnoreCase)) + { + return "application/octet-stream"; + } + throw new ArgumentException("Argument not supported: " + path); } } diff --git a/MediaBrowser.Controller/Chapters/IChapterManager.cs b/MediaBrowser.Controller/Chapters/IChapterManager.cs index b8f29d1ce..676ef9c56 100644 --- a/MediaBrowser.Controller/Chapters/IChapterManager.cs +++ b/MediaBrowser.Controller/Chapters/IChapterManager.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Chapters; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Chapters @@ -70,5 +71,11 @@ namespace MediaBrowser.Controller.Chapters /// </summary> /// <returns>IEnumerable{ChapterProviderInfo}.</returns> IEnumerable<ChapterProviderInfo> GetProviders(); + + /// <summary> + /// Gets the configuration. + /// </summary> + /// <returns>ChapterOptions.</returns> + ChapterOptions GetConfiguration(); } } diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 9468fd987..38c2c83c4 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -44,6 +44,27 @@ namespace MediaBrowser.Controller.MediaEncoding Task<Stream> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); /// <summary> + /// Extracts the video images on interval. + /// </summary> + /// <param name="inputFiles">The input files.</param> + /// <param name="protocol">The protocol.</param> + /// <param name="threedFormat">The threed format.</param> + /// <param name="interval">The interval.</param> + /// <param name="targetDirectory">The target directory.</param> + /// <param name="filenamePrefix">The filename prefix.</param> + /// <param name="maxWidth">The maximum width.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task ExtractVideoImagesOnInterval(string[] inputFiles, + MediaProtocol protocol, + Video3DFormat? threedFormat, + TimeSpan interval, + string targetDirectory, + string filenamePrefix, + int? maxWidth, + CancellationToken cancellationToken); + + /// <summary> /// Gets the media info. /// </summary> /// <param name="inputFiles">The input files.</param> diff --git a/MediaBrowser.Dlna/ConfigurationExtension.cs b/MediaBrowser.Dlna/ConfigurationExtension.cs new file mode 100644 index 000000000..821e21ccf --- /dev/null +++ b/MediaBrowser.Dlna/ConfigurationExtension.cs @@ -0,0 +1,29 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Configuration; +using System.Collections.Generic; + +namespace MediaBrowser.Dlna +{ + public static class ConfigurationExtension + { + public static DlnaOptions GetDlnaConfiguration(this IConfigurationManager manager) + { + return manager.GetConfiguration<DlnaOptions>("dlna"); + } + } + + public class DlnaConfigurationFactory : IConfigurationFactory + { + public IEnumerable<ConfigurationStore> GetConfigurations() + { + return new List<ConfigurationStore> + { + new ConfigurationStore + { + Key = "dlna", + ConfigurationType = typeof (DlnaOptions) + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs index bb65f422c..f594b4471 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs @@ -89,9 +89,11 @@ namespace MediaBrowser.Dlna.ContentDirectory } } - if (!string.IsNullOrEmpty(_config.Configuration.DlnaOptions.DefaultUserId)) + var userId = _config.GetDlnaConfiguration().DefaultUserId; + + if (!string.IsNullOrEmpty(userId)) { - var user = _userManager.GetUserById(new Guid(_config.Configuration.DlnaOptions.DefaultUserId)); + var user = _userManager.GetUserById(new Guid(userId)); if (user != null) { diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 048525588..5f2c1c49a 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; @@ -58,34 +59,39 @@ namespace MediaBrowser.Dlna.Main StartSsdpHandler(); ReloadComponents(); - _config.ConfigurationUpdated += ConfigurationUpdated; + _config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated; } - void ConfigurationUpdated(object sender, EventArgs e) + void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) { - ReloadComponents(); + if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase)) + { + ReloadComponents(); + } } private void ReloadComponents() { var isServerStarted = _dlnaServerStarted; - if (_config.Configuration.DlnaOptions.EnableServer && !isServerStarted) + var options = _config.GetDlnaConfiguration(); + + if (options.EnableServer && !isServerStarted) { StartDlnaServer(); } - else if (!_config.Configuration.DlnaOptions.EnableServer && isServerStarted) + else if (!options.EnableServer && isServerStarted) { DisposeDlnaServer(); } var isPlayToStarted = _manager != null; - if (_config.Configuration.DlnaOptions.EnablePlayTo && !isPlayToStarted) + if (options.EnablePlayTo && !isPlayToStarted) { StartPlayToManager(); } - else if (!_config.Configuration.DlnaOptions.EnablePlayTo && isPlayToStarted) + else if (!options.EnablePlayTo && isPlayToStarted) { DisposePlayToManager(); } diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 10da21e52..1d51fc60f 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -51,6 +51,7 @@ <Compile Include="..\SharedVersion.cs"> <Link>Properties\SharedVersion.cs</Link> </Compile> + <Compile Include="ConfigurationExtension.cs" /> <Compile Include="ConnectionManager\ConnectionManager.cs" /> <Compile Include="ConnectionManager\ConnectionManagerXmlBuilder.cs" /> <Compile Include="ConnectionManager\ControlHandler.cs" /> diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 095c6a893..1f8c33ee7 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -181,7 +181,7 @@ namespace MediaBrowser.Dlna.PlayTo return; } - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)); var headerText = string.Join(",", headerTexts.ToArray()); @@ -220,7 +220,7 @@ namespace MediaBrowser.Dlna.PlayTo { _ssdpHandler.SendRendererSearchMessage(new IPEndPoint(localIp, 1900)); - var delay = _config.Configuration.DlnaOptions.ClientDiscoveryIntervalSeconds * 1000; + var delay = _config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds * 1000; await Task.Delay(delay, _tokenSource.Token).ConfigureAwait(false); } @@ -250,7 +250,7 @@ namespace MediaBrowser.Dlna.PlayTo { socket.SendTo(request, new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900)); - var delay = _config.Configuration.DlnaOptions.ClientDiscoveryIntervalSeconds * 1000; + var delay = _config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds * 1000; await Task.Delay(delay).ConfigureAwait(false); } diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs index 22d4797a3..ccc7d46e6 100644 --- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs +++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url, UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging, + LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging, LogErrorResponseBody = true }; @@ -76,7 +76,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url, UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging, + LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging, LogErrorResponseBody = true }; @@ -103,7 +103,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url, UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging, + LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging, LogErrorResponseBody = true }; diff --git a/MediaBrowser.Dlna/Service/BaseControlHandler.cs b/MediaBrowser.Dlna/Service/BaseControlHandler.cs index 9f7e87088..c2af1f5a1 100644 --- a/MediaBrowser.Dlna/Service/BaseControlHandler.cs +++ b/MediaBrowser.Dlna/Service/BaseControlHandler.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Dlna.Service { try { - if (Config.Configuration.DlnaOptions.EnableDebugLogging) + if (Config.GetDlnaConfiguration().EnableDebugLogging) { LogRequest(request); } diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 0fc7c579b..0455dd674 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -1,4 +1,4 @@ -using System.Text; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Controller.Configuration; using MediaBrowser.Dlna.Server; @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; +using System.Text; using System.Threading; namespace MediaBrowser.Dlna.Ssdp @@ -42,12 +43,15 @@ namespace MediaBrowser.Dlna.Ssdp _config = config; _serverSignature = serverSignature; - _config.ConfigurationUpdated += _config_ConfigurationUpdated; + _config.NamedConfigurationUpdated += _config_ConfigurationUpdated; } - void _config_ConfigurationUpdated(object sender, EventArgs e) + void _config_ConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) { - ReloadAliveNotifier(); + if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase)) + { + ReloadAliveNotifier(); + } } public event EventHandler<SsdpMessageEventArgs> MessageReceived; @@ -142,7 +146,7 @@ namespace MediaBrowser.Dlna.Ssdp private void RespondToSearch(IPEndPoint endpoint, string deviceType) { - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("RespondToSearch"); } @@ -166,7 +170,7 @@ namespace MediaBrowser.Dlna.Ssdp SendDatagram(header, values, endpoint, null); - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("{1} - Responded to a {0} request to {2}", d.Type, endpoint, d.Address.ToString()); } @@ -255,14 +259,14 @@ namespace MediaBrowser.Dlna.Ssdp var received = (byte[])result.AsyncState; - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug(Encoding.ASCII.GetString(received)); } var args = SsdpHelper.ParseSsdpResponse(received, (IPEndPoint)endpoint); - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)); var headerText = string.Join(",", headerTexts.ToArray()); @@ -285,7 +289,7 @@ namespace MediaBrowser.Dlna.Ssdp public void Dispose() { - _config.ConfigurationUpdated -= _config_ConfigurationUpdated; + _config.NamedConfigurationUpdated -= _config_ConfigurationUpdated; _isDisposed = true; while (_messageQueue.Count != 0) @@ -337,7 +341,7 @@ namespace MediaBrowser.Dlna.Ssdp private void NotifyAll() { - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("Sending alive notifications"); } @@ -362,7 +366,7 @@ namespace MediaBrowser.Dlna.Ssdp values["NT"] = dev.Type; values["USN"] = dev.USN; - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("{0} said {1}", dev.USN, type); } @@ -406,13 +410,13 @@ namespace MediaBrowser.Dlna.Ssdp private int _aliveNotifierIntervalMs; private void ReloadAliveNotifier() { - if (!_config.Configuration.DlnaOptions.BlastAliveMessages) + if (!_config.GetDlnaConfiguration().BlastAliveMessages) { DisposeNotificationTimer(); return; } - var intervalMs = _config.Configuration.DlnaOptions.BlastAliveMessageIntervalSeconds * 1000; + var intervalMs = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds * 1000; if (_notificationTimer == null || _aliveNotifierIntervalMs != intervalMs) { diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 1087c905c..ce761ff9c 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.MediaEncoding.Encoder RedirectStandardError = true, FileName = FFProbePath, Arguments = string.Format(args, - probeSizeArgument, inputPath).Trim(), + probeSizeArgument, inputPath).Trim(), WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false @@ -186,8 +186,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { process.BeginErrorReadLine(); - result = - _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream); + result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream); } catch { @@ -292,7 +291,6 @@ namespace MediaBrowser.MediaEncoding.Encoder // apply some filters to thumbnail extracted below (below) crop any black lines that we made and get the correct ar then scale to width 600. // This filter chain may have adverse effects on recorded tv thumbnails if ar changes during presentation ex. commercials @ diff ar var vf = "scale=600:trunc(600/dar/2)*2"; - //crop=min(iw\,ih*dar):min(ih\,iw/dar):(iw-min(iw\,iw*sar))/2:(ih - min (ih\,ih/sar))/2,scale=600:(600/dar),thumbnail" -f image2 if (threedFormat.HasValue) { @@ -344,7 +342,8 @@ namespace MediaBrowser.MediaEncoding.Encoder WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, RedirectStandardOutput = true, - RedirectStandardError = true + RedirectStandardError = true, + RedirectStandardInput = true } }; @@ -370,7 +369,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { _logger.Info("Killing ffmpeg process"); - process.Kill(); + process.StandardInput.WriteLine("q"); process.WaitForExit(1000); } @@ -437,5 +436,93 @@ namespace MediaBrowser.MediaEncoding.Encoder { return time.ToString(@"hh\:mm\:ss\.fff", UsCulture); } + + public async Task ExtractVideoImagesOnInterval(string[] inputFiles, + MediaProtocol protocol, + Video3DFormat? threedFormat, + TimeSpan interval, + string targetDirectory, + string filenamePrefix, + int? maxWidth, + CancellationToken cancellationToken) + { + var resourcePool = _videoImageResourcePool; + + var inputArgument = GetInputArgument(inputFiles, protocol); + + var vf = "fps=fps=1/" + interval.TotalSeconds.ToString(UsCulture); + + if (maxWidth.HasValue) + { + var maxWidthParam = maxWidth.Value.ToString(UsCulture); + + vf += string.Format(",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam); + } + + Directory.CreateDirectory(targetDirectory); + var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg"); + + var args = string.Format("-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf); + + var probeSize = GetProbeSizeArgument(new[] { inputArgument }, protocol); + + if (!string.IsNullOrEmpty(probeSize)) + { + args = probeSize + " " + args; + } + + var process = new Process + { + StartInfo = new ProcessStartInfo + { + CreateNoWindow = true, + UseShellExecute = false, + FileName = FFMpegPath, + Arguments = args, + WindowStyle = ProcessWindowStyle.Hidden, + ErrorDialog = false, + RedirectStandardInput = true + } + }; + + _logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments); + + await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + process.Start(); + + var ranToCompletion = process.WaitForExit(120000); + + if (!ranToCompletion) + { + try + { + _logger.Info("Killing ffmpeg process"); + + process.StandardInput.WriteLine("q"); + + process.WaitForExit(1000); + } + catch (Exception ex) + { + _logger.ErrorException("Error killing process", ex); + } + } + + resourcePool.Release(); + + var exitCode = ranToCompletion ? process.ExitCode : -1; + + process.Dispose(); + + if (exitCode == -1) + { + var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument); + + _logger.Error(msg); + + throw new ApplicationException(msg); + } + } } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 154541316..ab9cd546a 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -342,12 +342,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles { RedirectStandardOutput = false, RedirectStandardError = true, + RedirectStandardInput = true, CreateNoWindow = true, UseShellExecute = false, FileName = _mediaEncoder.EncoderPath, - Arguments = - string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath), + Arguments = string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath), WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false @@ -385,8 +385,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { _logger.Info("Killing ffmpeg subtitle conversion process"); - process.Kill(); - + process.StandardInput.WriteLine("q"); process.WaitForExit(1000); await logTask.ConfigureAwait(false); @@ -520,6 +519,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles RedirectStandardOutput = false, RedirectStandardError = true, + RedirectStandardInput = true, FileName = _mediaEncoder.EncoderPath, Arguments = processArgs, @@ -559,8 +559,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { _logger.Info("Killing ffmpeg subtitle extraction process"); - process.Kill(); - + process.StandardInput.WriteLine("q"); process.WaitForExit(1000); } catch (Exception ex) diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index ee6f05cc1..3c34652c3 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -104,6 +104,12 @@ <Compile Include="..\MediaBrowser.Model\Configuration\BaseApplicationConfiguration.cs"> <Link>Configuration\BaseApplicationConfiguration.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\Configuration\ChannelOptions.cs"> + <Link>Configuration\ChannelOptions.cs</Link> + </Compile> + <Compile Include="..\MediaBrowser.Model\Configuration\ChapterOptions.cs"> + <Link>Configuration\ChapterOptions.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\Configuration\DlnaOptions.cs"> <Link>Configuration\DlnaOptions.cs</Link> </Compile> @@ -152,6 +158,9 @@ <Compile Include="..\MediaBrowser.Model\Configuration\SubtitleOptions.cs"> <Link>Configuration\SubtitleOptions.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs"> + <Link>Configuration\SubtitlePlaybackMode.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\Configuration\TvFileOrganizationOptions.cs"> <Link>Configuration\TvFileOrganizationOptions.cs</Link> </Compile> diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index a2fa1aa94..9e3df382e 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -91,6 +91,12 @@ <Compile Include="..\MediaBrowser.Model\Configuration\BaseApplicationConfiguration.cs"> <Link>Configuration\BaseApplicationConfiguration.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\Configuration\ChannelOptions.cs"> + <Link>Configuration\ChannelOptions.cs</Link> + </Compile> + <Compile Include="..\MediaBrowser.Model\Configuration\ChapterOptions.cs"> + <Link>Configuration\ChapterOptions.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\Configuration\DlnaOptions.cs"> <Link>Configuration\DlnaOptions.cs</Link> </Compile> @@ -139,6 +145,9 @@ <Compile Include="..\MediaBrowser.Model\Configuration\SubtitleOptions.cs"> <Link>Configuration\SubtitleOptions.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs"> + <Link>Configuration\SubtitlePlaybackMode.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\Configuration\TvFileOrganizationOptions.cs"> <Link>Configuration\TvFileOrganizationOptions.cs</Link> </Compile> diff --git a/MediaBrowser.Model/Configuration/ChannelOptions.cs b/MediaBrowser.Model/Configuration/ChannelOptions.cs new file mode 100644 index 000000000..f0fc4d47c --- /dev/null +++ b/MediaBrowser.Model/Configuration/ChannelOptions.cs @@ -0,0 +1,18 @@ +namespace MediaBrowser.Model.Configuration +{ + public class ChannelOptions + { + public int? PreferredStreamingWidth { get; set; } + + public string DownloadPath { get; set; } + public int? MaxDownloadAge { get; set; } + + public string[] DownloadingChannels { get; set; } + + public ChannelOptions() + { + DownloadingChannels = new string[] { }; + MaxDownloadAge = 30; + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/ChapterOptions.cs b/MediaBrowser.Model/Configuration/ChapterOptions.cs new file mode 100644 index 000000000..8a059a0a4 --- /dev/null +++ b/MediaBrowser.Model/Configuration/ChapterOptions.cs @@ -0,0 +1,27 @@ +namespace MediaBrowser.Model.Configuration +{ + public class ChapterOptions + { + public bool EnableMovieChapterImageExtraction { get; set; } + public bool EnableEpisodeChapterImageExtraction { get; set; } + public bool EnableOtherVideoChapterImageExtraction { get; set; } + + public bool DownloadMovieChapters { get; set; } + public bool DownloadEpisodeChapters { get; set; } + + public string[] FetcherOrder { get; set; } + public string[] DisabledFetchers { get; set; } + + public ChapterOptions() + { + EnableMovieChapterImageExtraction = true; + EnableEpisodeChapterImageExtraction = false; + EnableOtherVideoChapterImageExtraction = false; + + DownloadMovieChapters = true; + + DisabledFetchers = new string[] { }; + FetcherOrder = new string[] { }; + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 0d728ec75..3d5e0a9c9 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -211,6 +211,7 @@ namespace MediaBrowser.Model.Configuration public string UICulture { get; set; } + [Obsolete] public DlnaOptions DlnaOptions { get; set; } public double DownMixAudioBoost { get; set; } @@ -223,6 +224,8 @@ namespace MediaBrowser.Model.Configuration public string[] ManualLoginClients { get; set; } public ChannelOptions ChannelOptions { get; set; } + + [Obsolete] public ChapterOptions ChapterOptions { get; set; } /// <summary> @@ -268,73 +271,27 @@ namespace MediaBrowser.Model.Configuration SeasonZeroDisplayName = "Specials"; - LiveTvOptions = new LiveTvOptions(); - - TvFileOrganizationOptions = new TvFileOrganizationOptions(); - EnableRealtimeMonitor = true; - List<MetadataOptions> options = new List<MetadataOptions> + UICulture = "en-us"; + + MetadataOptions = new List<MetadataOptions> { new MetadataOptions(1, 1280) {ItemType = "Book"}, new MetadataOptions(1, 1280) {ItemType = "MusicAlbum"}, new MetadataOptions(1, 1280) {ItemType = "MusicArtist"}, new MetadataOptions(0, 1280) {ItemType = "Season"} - }; - - MetadataOptions = options.ToArray(); - DlnaOptions = new DlnaOptions(); - - UICulture = "en-us"; + }.ToArray(); NotificationOptions = new NotificationOptions(); SubtitleOptions = new SubtitleOptions(); ChannelOptions = new ChannelOptions(); - ChapterOptions = new ChapterOptions(); - } - } - - public class ChannelOptions - { - public int? PreferredStreamingWidth { get; set; } - public string DownloadPath { get; set; } - public int? MaxDownloadAge { get; set; } - - public string[] DownloadingChannels { get; set; } - - public ChannelOptions() - { - DownloadingChannels = new string[] { }; - MaxDownloadAge = 30; - } - } - - public class ChapterOptions - { - public bool EnableMovieChapterImageExtraction { get; set; } - public bool EnableEpisodeChapterImageExtraction { get; set; } - public bool EnableOtherVideoChapterImageExtraction { get; set; } - - public bool DownloadMovieChapters { get; set; } - public bool DownloadEpisodeChapters { get; set; } - - public string[] FetcherOrder { get; set; } - public string[] DisabledFetchers { get; set; } - - public ChapterOptions() - { - EnableMovieChapterImageExtraction = true; - EnableEpisodeChapterImageExtraction = false; - EnableOtherVideoChapterImageExtraction = false; - - DownloadMovieChapters = true; - - DisabledFetchers = new string[] { }; - FetcherOrder = new string[] { }; + LiveTvOptions = new LiveTvOptions(); + TvFileOrganizationOptions = new TvFileOrganizationOptions(); } } } diff --git a/MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs b/MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs new file mode 100644 index 000000000..e6a3c3091 --- /dev/null +++ b/MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs @@ -0,0 +1,10 @@ +namespace MediaBrowser.Model.Configuration +{ + public enum SubtitlePlaybackMode + { + Default = 0, + Always = 1, + OnlyForced = 2, + None = 3 + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 885172bed..94a41bdda 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -91,12 +91,4 @@ namespace MediaBrowser.Model.Configuration ExcludeFoldersFromGrouping = new string[] { }; } } - - public enum SubtitlePlaybackMode - { - Default = 0, - Always = 1, - OnlyForced = 2, - None = 3 - } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 9efa63283..5d753f9c2 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -73,6 +73,9 @@ <Compile Include="Channels\ChannelQuery.cs" /> <Compile Include="Chapters\RemoteChapterInfo.cs" /> <Compile Include="Chapters\RemoteChapterResult.cs" /> + <Compile Include="Configuration\ChannelOptions.cs" /> + <Compile Include="Configuration\ChapterOptions.cs" /> + <Compile Include="Configuration\SubtitlePlaybackMode.cs" /> <Compile Include="Configuration\TvFileOrganizationOptions.cs" /> <Compile Include="Configuration\BaseApplicationConfiguration.cs" /> <Compile Include="Configuration\DlnaOptions.cs" /> diff --git a/MediaBrowser.Providers/Chapters/ChapterManager.cs b/MediaBrowser.Providers/Chapters/ChapterManager.cs index 5f8664bec..6e2cd77eb 100644 --- a/MediaBrowser.Providers/Chapters/ChapterManager.cs +++ b/MediaBrowser.Providers/Chapters/ChapterManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -8,6 +9,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Chapters; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; @@ -192,8 +194,10 @@ namespace MediaBrowser.Providers.Chapters if (!includeDisabledProviders) { + var options = GetConfiguration(); + providers = providers - .Where(i => !_config.Configuration.ChapterOptions.DisabledFetchers.Contains(i.Name)) + .Where(i => !options.DisabledFetchers.Contains(i.Name)) .ToArray(); } @@ -224,8 +228,10 @@ namespace MediaBrowser.Providers.Chapters private int GetConfiguredOrder(IChapterProvider provider) { + var options = GetConfiguration(); + // See if there's a user-defined order - var index = Array.IndexOf(_config.Configuration.ChapterOptions.FetcherOrder, provider.Name); + var index = Array.IndexOf(options.FetcherOrder, provider.Name); if (index != -1) { @@ -257,5 +263,25 @@ namespace MediaBrowser.Providers.Chapters { return _itemRepo.SaveChapters(new Guid(itemId), chapters, cancellationToken); } + + public ChapterOptions GetConfiguration() + { + return _config.GetConfiguration<ChapterOptions>("chapters"); + } + } + + public class ChapterConfigurationStore : IConfigurationFactory + { + public IEnumerable<ConfigurationStore> GetConfigurations() + { + return new List<ConfigurationStore> + { + new ConfigurationStore + { + Key = "chapters", + ConfigurationType = typeof (ChapterOptions) + } + }; + } } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 65faae327..92b4616e7 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -492,9 +492,11 @@ namespace MediaBrowser.Providers.MediaInfo private async Task<List<ChapterInfo>> DownloadChapters(Video video, List<ChapterInfo> currentChapters, CancellationToken cancellationToken) { - if ((_config.Configuration.ChapterOptions.DownloadEpisodeChapters && + var options = _chapterManager.GetConfiguration(); + + if ((options.DownloadEpisodeChapters && video is Episode) || - (_config.Configuration.ChapterOptions.DownloadMovieChapters && + (options.DownloadMovieChapters && video is Movie)) { var results = await _chapterManager.Search(video, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs index 056a526f6..d35282e55 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -1,12 +1,15 @@ -using MediaBrowser.Common.IO; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; using System.Globalization; @@ -14,7 +17,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Server.Implementations.MediaEncoder { @@ -61,23 +63,25 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder return false; } + var options = _chapterManager.GetConfiguration(); + if (video is Movie) { - if (!_config.Configuration.ChapterOptions.EnableMovieChapterImageExtraction) + if (!options.EnableMovieChapterImageExtraction) { return false; } } else if (video is Episode) { - if (!_config.Configuration.ChapterOptions.EnableEpisodeChapterImageExtraction) + if (!options.EnableEpisodeChapterImageExtraction) { return false; } } else { - if (!_config.Configuration.ChapterOptions.EnableOtherVideoChapterImageExtraction) + if (!options.EnableOtherVideoChapterImageExtraction) { return false; } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index d03c5fe3d..8007e0506 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -41,6 +41,7 @@ using MediaBrowser.Dlna.Main; using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.MediaEncoding.Encoder; using MediaBrowser.MediaEncoding.Subtitles; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.System; @@ -273,11 +274,35 @@ namespace MediaBrowser.ServerApplication public override Task Init(IProgress<double> progress) { - DeleteDeprecatedModules(); + PerformVersionMigration(); return base.Init(progress); } + private void PerformVersionMigration() + { + DeleteDeprecatedModules(); + + MigrateModularConfigurations(); + } + + private void MigrateModularConfigurations() + { + if (ServerConfigurationManager.Configuration.DlnaOptions != null) + { + ServerConfigurationManager.SaveConfiguration("dlna", ServerConfigurationManager.Configuration.DlnaOptions); + ServerConfigurationManager.Configuration.DlnaOptions = null; + ServerConfigurationManager.SaveConfiguration(); + } + + if (ServerConfigurationManager.Configuration.ChapterOptions != null) + { + ServerConfigurationManager.SaveConfiguration("chapters", ServerConfigurationManager.Configuration.ChapterOptions); + ServerConfigurationManager.Configuration.ChapterOptions = null; + ServerConfigurationManager.SaveConfiguration(); + } + } + private void DeleteDeprecatedModules() { try |
