mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-15 09:59:06 -07:00
added modular configuration
This commit is contained in:
parent
6904919794
commit
933443c2b9
@ -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());
|
||||
|
@ -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)
|
||||
|
@ -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" />
|
||||
|
@ -342,6 +342,7 @@ namespace MediaBrowser.Common.Implementations
|
||||
/// </summary>
|
||||
protected virtual void FindParts()
|
||||
{
|
||||
ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
|
||||
Plugins = GetExports<IPlugin>();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -25,6 +28,11 @@ namespace MediaBrowser.Common.Implementations.Configuration
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> ConfigurationUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [named configuration updated].
|
||||
/// </summary>
|
||||
public event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger.
|
||||
/// </summary>
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
17
MediaBrowser.Common/Configuration/IConfigurationFactory.cs
Normal file
17
MediaBrowser.Common/Configuration/IConfigurationFactory.cs
Normal file
@ -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; }
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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" />
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,27 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
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>
|
||||
|
29
MediaBrowser.Dlna/ConfigurationExtension.cs
Normal file
29
MediaBrowser.Dlna/ConfigurationExtension.cs
Normal file
@ -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)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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" />
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace MediaBrowser.Dlna.Service
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Config.Configuration.DlnaOptions.EnableDebugLogging)
|
||||
if (Config.GetDlnaConfiguration().EnableDebugLogging)
|
||||
{
|
||||
LogRequest(request);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
18
MediaBrowser.Model/Configuration/ChannelOptions.cs
Normal file
18
MediaBrowser.Model/Configuration/ChannelOptions.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
27
MediaBrowser.Model/Configuration/ChapterOptions.cs
Normal file
27
MediaBrowser.Model/Configuration/ChapterOptions.cs
Normal file
@ -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[] { };
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs
Normal file
10
MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
public enum SubtitlePlaybackMode
|
||||
{
|
||||
Default = 0,
|
||||
Always = 1,
|
||||
OnlyForced = 2,
|
||||
None = 3
|
||||
}
|
||||
}
|
@ -91,12 +91,4 @@ namespace MediaBrowser.Model.Configuration
|
||||
ExcludeFoldersFromGrouping = new string[] { };
|
||||
}
|
||||
}
|
||||
|
||||
public enum SubtitlePlaybackMode
|
||||
{
|
||||
Default = 0,
|
||||
Always = 1,
|
||||
OnlyForced = 2,
|
||||
None = 3
|
||||
}
|
||||
}
|
||||
|
@ -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" />
|
||||
|
@ -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)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user