mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 13:57:14 -04:00
Merge pull request #3939 from Bond-009/warn24
Make MediaBrowser.MediaEncoding warnings free
This commit is contained in:
commit
ac58d07e0e
@ -30,10 +30,8 @@ using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
|
|||||||
|
|
||||||
namespace Emby.Dlna.Main
|
namespace Emby.Dlna.Main
|
||||||
{
|
{
|
||||||
public class DlnaEntryPoint : IServerEntryPoint, IRunBeforeStartup
|
public sealed class DlnaEntryPoint : IServerEntryPoint, IRunBeforeStartup
|
||||||
{
|
{
|
||||||
public static DlnaEntryPoint Current;
|
|
||||||
|
|
||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly ILogger<DlnaEntryPoint> _logger;
|
private readonly ILogger<DlnaEntryPoint> _logger;
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
@ -123,6 +121,8 @@ namespace Emby.Dlna.Main
|
|||||||
Current = this;
|
Current = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DlnaEntryPoint Current { get; private set; }
|
||||||
|
|
||||||
public IContentDirectory ContentDirectory { get; private set; }
|
public IContentDirectory ContentDirectory { get; private set; }
|
||||||
|
|
||||||
public IConnectionManager ConnectionManager { get; private set; }
|
public IConnectionManager ConnectionManager { get; private set; }
|
||||||
|
@ -56,7 +56,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
throw new ArgumentNullException(nameof(obj));
|
throw new ArgumentNullException(nameof(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Equals(Id, obj.Id, StringComparison.InvariantCulture);
|
return string.Equals(Id, obj.Id, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ using System.Xml.Linq;
|
|||||||
|
|
||||||
namespace Emby.Dlna.PlayTo
|
namespace Emby.Dlna.PlayTo
|
||||||
{
|
{
|
||||||
public class uPnpNamespaces
|
public static class uPnpNamespaces
|
||||||
{
|
{
|
||||||
public static XNamespace dc = "http://purl.org/dc/elements/1.1/";
|
public static XNamespace dc = "http://purl.org/dc/elements/1.1/";
|
||||||
public static XNamespace ns = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/";
|
public static XNamespace ns = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/";
|
||||||
|
@ -4308,7 +4308,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
whereClauses.Add("ProductionYear=@Years");
|
whereClauses.Add("ProductionYear=@Years");
|
||||||
if (statement != null)
|
if (statement != null)
|
||||||
{
|
{
|
||||||
statement.TryBind("@Years", query.Years[0].ToString());
|
statement.TryBind("@Years", query.Years[0].ToString(CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (query.Years.Length > 1)
|
else if (query.Years.Length > 1)
|
||||||
@ -5170,7 +5170,10 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
insertText.Append(',');
|
insertText.Append(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
insertText.AppendFormat("(@ItemId, @AncestorId{0}, @AncestorIdText{0})", i.ToString(CultureInfo.InvariantCulture));
|
insertText.AppendFormat(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"(@ItemId, @AncestorId{0}, @AncestorIdText{0})",
|
||||||
|
i.ToString(CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var statement = PrepareStatement(db, insertText.ToString()))
|
using (var statement = PrepareStatement(db, insertText.ToString()))
|
||||||
|
@ -6,12 +6,11 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Emby.Server.Implementations.Library;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Plugins;
|
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using Emby.Server.Implementations.Library;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.IO
|
namespace Emby.Server.Implementations.IO
|
||||||
@ -38,6 +37,8 @@ namespace Emby.Server.Implementations.IO
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ConcurrentDictionary<string, string> _tempIgnoredPaths = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
private readonly ConcurrentDictionary<string, string> _tempIgnoredPaths = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private bool _disposed = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add the path to our temporary ignore list. Use when writing to a path within our listening scope.
|
/// Add the path to our temporary ignore list. Use when writing to a path within our listening scope.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -492,8 +493,6 @@ namespace Emby.Server.Implementations.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _disposed = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -522,24 +521,4 @@ namespace Emby.Server.Implementations.IO
|
|||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LibraryMonitorStartup : IServerEntryPoint
|
|
||||||
{
|
|
||||||
private readonly ILibraryMonitor _monitor;
|
|
||||||
|
|
||||||
public LibraryMonitorStartup(ILibraryMonitor monitor)
|
|
||||||
{
|
|
||||||
_monitor = monitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task RunAsync()
|
|
||||||
{
|
|
||||||
_monitor.Start();
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
35
Emby.Server.Implementations/IO/LibraryMonitorStartup.cs
Normal file
35
Emby.Server.Implementations/IO/LibraryMonitorStartup.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Controller.Plugins;
|
||||||
|
|
||||||
|
namespace Emby.Server.Implementations.IO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="IServerEntryPoint" /> which is responsible for starting the library monitor.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class LibraryMonitorStartup : IServerEntryPoint
|
||||||
|
{
|
||||||
|
private readonly ILibraryMonitor _monitor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="LibraryMonitorStartup"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="monitor">The library monitor.</param>
|
||||||
|
public LibraryMonitorStartup(ILibraryMonitor monitor)
|
||||||
|
{
|
||||||
|
_monitor = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task RunAsync()
|
||||||
|
{
|
||||||
|
_monitor.Start();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -729,7 +729,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
Directory.CreateDirectory(rootFolderPath);
|
Directory.CreateDirectory(rootFolderPath);
|
||||||
|
|
||||||
var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ??
|
var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ??
|
||||||
((Folder) ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath)))
|
((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath)))
|
||||||
.DeepCopy<Folder, AggregateFolder>();
|
.DeepCopy<Folder, AggregateFolder>();
|
||||||
|
|
||||||
// In case program data folder was moved
|
// In case program data folder was moved
|
||||||
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Plugins;
|
|||||||
|
|
||||||
namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
public class EntryPoint : IServerEntryPoint
|
public sealed class EntryPoint : IServerEntryPoint
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task RunAsync()
|
public Task RunAsync()
|
||||||
|
@ -929,7 +929,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
|
|
||||||
private static string NormalizeName(string value)
|
private static string NormalizeName(string value)
|
||||||
{
|
{
|
||||||
return value.Replace(" ", string.Empty).Replace("-", string.Empty);
|
return value.Replace(" ", string.Empty, StringComparison.Ordinal).Replace("-", string.Empty, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScheduleDirect
|
public class ScheduleDirect
|
||||||
|
@ -10,7 +10,6 @@ using MediaBrowser.Common.Configuration;
|
|||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@ -22,37 +21,53 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ScheduledTaskWorker : IScheduledTaskWorker
|
public class ScheduledTaskWorker : IScheduledTaskWorker
|
||||||
{
|
{
|
||||||
public event EventHandler<GenericEventArgs<double>> TaskProgress;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the scheduled task.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The scheduled task.</value>
|
|
||||||
public IScheduledTask ScheduledTask { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the json serializer.
|
/// Gets or sets the json serializer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The json serializer.</value>
|
/// <value>The json serializer.</value>
|
||||||
private IJsonSerializer JsonSerializer { get; set; }
|
private readonly IJsonSerializer _jsonSerializer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the application paths.
|
/// Gets or sets the application paths.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The application paths.</value>
|
/// <value>The application paths.</value>
|
||||||
private IApplicationPaths ApplicationPaths { get; set; }
|
private readonly IApplicationPaths _applicationPaths;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the logger.
|
/// Gets or sets the logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The logger.</value>
|
/// <value>The logger.</value>
|
||||||
private ILogger Logger { get; set; }
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the task manager.
|
/// Gets or sets the task manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The task manager.</value>
|
/// <value>The task manager.</value>
|
||||||
private ITaskManager TaskManager { get; set; }
|
private readonly ITaskManager _taskManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _last execution result sync lock.
|
||||||
|
/// </summary>
|
||||||
|
private readonly object _lastExecutionResultSyncLock = new object();
|
||||||
|
|
||||||
|
private bool _readFromFile = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _last execution result.
|
||||||
|
/// </summary>
|
||||||
|
private TaskResult _lastExecutionResult;
|
||||||
|
|
||||||
|
private Task _currentTask;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _triggers.
|
||||||
|
/// </summary>
|
||||||
|
private Tuple<TaskTriggerInfo, ITaskTrigger>[] _triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _id.
|
||||||
|
/// </summary>
|
||||||
|
private string _id;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ScheduledTaskWorker" /> class.
|
/// Initializes a new instance of the <see cref="ScheduledTaskWorker" /> class.
|
||||||
@ -71,7 +86,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
/// or
|
/// or
|
||||||
/// jsonSerializer
|
/// jsonSerializer
|
||||||
/// or
|
/// or
|
||||||
/// logger
|
/// logger.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger)
|
public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger)
|
||||||
{
|
{
|
||||||
@ -101,23 +116,22 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
ScheduledTask = scheduledTask;
|
ScheduledTask = scheduledTask;
|
||||||
ApplicationPaths = applicationPaths;
|
_applicationPaths = applicationPaths;
|
||||||
TaskManager = taskManager;
|
_taskManager = taskManager;
|
||||||
JsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
Logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
InitTriggerEvents();
|
InitTriggerEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _readFromFile = false;
|
public event EventHandler<GenericEventArgs<double>> TaskProgress;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _last execution result.
|
/// Gets the scheduled task.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private TaskResult _lastExecutionResult;
|
/// <value>The scheduled task.</value>
|
||||||
/// <summary>
|
public IScheduledTask ScheduledTask { get; private set; }
|
||||||
/// The _last execution result sync lock.
|
|
||||||
/// </summary>
|
|
||||||
private readonly object _lastExecutionResultSyncLock = new object();
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the last execution result.
|
/// Gets the last execution result.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -136,11 +150,11 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_lastExecutionResult = JsonSerializer.DeserializeFromFile<TaskResult>(path);
|
_lastExecutionResult = _jsonSerializer.DeserializeFromFile<TaskResult>(path);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Error deserializing {File}", path);
|
_logger.LogError(ex, "Error deserializing {File}", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +174,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
|
|
||||||
lock (_lastExecutionResultSyncLock)
|
lock (_lastExecutionResultSyncLock)
|
||||||
{
|
{
|
||||||
JsonSerializer.SerializeToFile(value, path);
|
_jsonSerializer.SerializeToFile(value, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,7 +198,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
public string Category => ScheduledTask.Category;
|
public string Category => ScheduledTask.Category;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current cancellation token.
|
/// Gets or sets the current cancellation token.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The current cancellation token source.</value>
|
/// <value>The current cancellation token source.</value>
|
||||||
private CancellationTokenSource CurrentCancellationTokenSource { get; set; }
|
private CancellationTokenSource CurrentCancellationTokenSource { get; set; }
|
||||||
@ -221,12 +235,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
public double? CurrentProgress { get; private set; }
|
public double? CurrentProgress { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _triggers.
|
/// Gets or sets the triggers that define when the task will run.
|
||||||
/// </summary>
|
|
||||||
private Tuple<TaskTriggerInfo, ITaskTrigger>[] _triggers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the triggers that define when the task will run.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The triggers.</value>
|
/// <value>The triggers.</value>
|
||||||
private Tuple<TaskTriggerInfo, ITaskTrigger>[] InternalTriggers
|
private Tuple<TaskTriggerInfo, ITaskTrigger>[] InternalTriggers
|
||||||
@ -255,7 +264,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
/// Gets the triggers that define when the task will run.
|
/// Gets the triggers that define when the task will run.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The triggers.</value>
|
/// <value>The triggers.</value>
|
||||||
/// <exception cref="ArgumentNullException">value</exception>
|
/// <exception cref="ArgumentNullException"><c>value</c> is <c>null</c>.</exception>
|
||||||
public TaskTriggerInfo[] Triggers
|
public TaskTriggerInfo[] Triggers
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -280,11 +289,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The _id.
|
|
||||||
/// </summary>
|
|
||||||
private string _id;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the unique id.
|
/// Gets the unique id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -325,9 +329,9 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
|
|
||||||
trigger.Stop();
|
trigger.Stop();
|
||||||
|
|
||||||
trigger.Triggered -= trigger_Triggered;
|
trigger.Triggered -= OnTriggerTriggered;
|
||||||
trigger.Triggered += trigger_Triggered;
|
trigger.Triggered += OnTriggerTriggered;
|
||||||
trigger.Start(LastExecutionResult, Logger, Name, isApplicationStartup);
|
trigger.Start(LastExecutionResult, _logger, Name, isApplicationStartup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +340,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The source of the event.</param>
|
/// <param name="sender">The source of the event.</param>
|
||||||
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||||
async void trigger_Triggered(object sender, EventArgs e)
|
private async void OnTriggerTriggered(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var trigger = (ITaskTrigger)sender;
|
var trigger = (ITaskTrigger)sender;
|
||||||
|
|
||||||
@ -347,19 +351,17 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.LogInformation("{0} fired for task: {1}", trigger.GetType().Name, Name);
|
_logger.LogInformation("{0} fired for task: {1}", trigger.GetType().Name, Name);
|
||||||
|
|
||||||
trigger.Stop();
|
trigger.Stop();
|
||||||
|
|
||||||
TaskManager.QueueScheduledTask(ScheduledTask, trigger.TaskOptions);
|
_taskManager.QueueScheduledTask(ScheduledTask, trigger.TaskOptions);
|
||||||
|
|
||||||
await Task.Delay(1000).ConfigureAwait(false);
|
await Task.Delay(1000).ConfigureAwait(false);
|
||||||
|
|
||||||
trigger.Start(LastExecutionResult, Logger, Name, false);
|
trigger.Start(LastExecutionResult, _logger, Name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task _currentTask;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the task.
|
/// Executes the task.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -395,9 +397,9 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
|
|
||||||
CurrentCancellationTokenSource = new CancellationTokenSource();
|
CurrentCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
Logger.LogInformation("Executing {0}", Name);
|
_logger.LogInformation("Executing {0}", Name);
|
||||||
|
|
||||||
((TaskManager)TaskManager).OnTaskExecuting(this);
|
((TaskManager)_taskManager).OnTaskExecuting(this);
|
||||||
|
|
||||||
progress.ProgressChanged += OnProgressChanged;
|
progress.ProgressChanged += OnProgressChanged;
|
||||||
|
|
||||||
@ -423,7 +425,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Error");
|
_logger.LogError(ex, "Error");
|
||||||
|
|
||||||
failureException = ex;
|
failureException = ex;
|
||||||
|
|
||||||
@ -476,7 +478,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
{
|
{
|
||||||
if (State == TaskState.Running)
|
if (State == TaskState.Running)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Attempting to cancel Scheduled Task {0}", Name);
|
_logger.LogInformation("Attempting to cancel Scheduled Task {0}", Name);
|
||||||
CurrentCancellationTokenSource.Cancel();
|
CurrentCancellationTokenSource.Cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,7 +489,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
private string GetScheduledTasksConfigurationDirectory()
|
private string GetScheduledTasksConfigurationDirectory()
|
||||||
{
|
{
|
||||||
return Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
|
return Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -496,7 +498,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
private string GetScheduledTasksDataDirectory()
|
private string GetScheduledTasksDataDirectory()
|
||||||
{
|
{
|
||||||
return Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks");
|
return Path.Combine(_applicationPaths.DataPath, "ScheduledTasks");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -535,7 +537,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
TaskTriggerInfo[] list = null;
|
TaskTriggerInfo[] list = null;
|
||||||
if (File.Exists(path))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
list = JsonSerializer.DeserializeFromFile<TaskTriggerInfo[]>(path);
|
list = _jsonSerializer.DeserializeFromFile<TaskTriggerInfo[]>(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return defaults if file doesn't exist.
|
// Return defaults if file doesn't exist.
|
||||||
@ -571,7 +573,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
|
|
||||||
JsonSerializer.SerializeToFile(triggers, path);
|
_jsonSerializer.SerializeToFile(triggers, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -585,7 +587,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
{
|
{
|
||||||
var elapsedTime = endTime - startTime;
|
var elapsedTime = endTime - startTime;
|
||||||
|
|
||||||
Logger.LogInformation("{0} {1} after {2} minute(s) and {3} seconds", Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds);
|
_logger.LogInformation("{0} {1} after {2} minute(s) and {3} seconds", Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds);
|
||||||
|
|
||||||
var result = new TaskResult
|
var result = new TaskResult
|
||||||
{
|
{
|
||||||
@ -606,7 +608,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
|
|
||||||
LastExecutionResult = result;
|
LastExecutionResult = result;
|
||||||
|
|
||||||
((TaskManager)TaskManager).OnTaskCompleted(this, result);
|
((TaskManager)_taskManager).OnTaskCompleted(this, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -615,6 +617,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -635,12 +638,12 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.LogInformation(Name + ": Cancelling");
|
_logger.LogInformation(Name + ": Cancelling");
|
||||||
token.Cancel();
|
token.Cancel();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Error calling CancellationToken.Cancel();");
|
_logger.LogError(ex, "Error calling CancellationToken.Cancel();");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,21 +652,21 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.LogInformation(Name + ": Waiting on Task");
|
_logger.LogInformation(Name + ": Waiting on Task");
|
||||||
var exited = Task.WaitAll(new[] { task }, 2000);
|
var exited = Task.WaitAll(new[] { task }, 2000);
|
||||||
|
|
||||||
if (exited)
|
if (exited)
|
||||||
{
|
{
|
||||||
Logger.LogInformation(Name + ": Task exited");
|
_logger.LogInformation(Name + ": Task exited");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.LogInformation(Name + ": Timed out waiting for task to stop");
|
_logger.LogInformation(Name + ": Timed out waiting for task to stop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Error calling Task.WaitAll();");
|
_logger.LogError(ex, "Error calling Task.WaitAll();");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,12 +674,12 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.LogDebug(Name + ": Disposing CancellationToken");
|
_logger.LogDebug(Name + ": Disposing CancellationToken");
|
||||||
token.Dispose();
|
token.Dispose();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Error calling CancellationToken.Dispose();");
|
_logger.LogError(ex, "Error calling CancellationToken.Dispose();");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,8 +695,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="info">The info.</param>
|
/// <param name="info">The info.</param>
|
||||||
/// <returns>BaseTaskTrigger.</returns>
|
/// <returns>BaseTaskTrigger.</returns>
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// <exception cref="ArgumentException">Invalid trigger type: + info.Type.</exception>
|
||||||
/// <exception cref="ArgumentException">Invalid trigger type: + info.Type</exception>
|
|
||||||
private ITaskTrigger GetTrigger(TaskTriggerInfo info)
|
private ITaskTrigger GetTrigger(TaskTriggerInfo info)
|
||||||
{
|
{
|
||||||
var options = new TaskOptions
|
var options = new TaskOptions
|
||||||
@ -765,7 +767,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
foreach (var triggerInfo in InternalTriggers)
|
foreach (var triggerInfo in InternalTriggers)
|
||||||
{
|
{
|
||||||
var trigger = triggerInfo.Item2;
|
var trigger = triggerInfo.Item2;
|
||||||
trigger.Triggered -= trigger_Triggered;
|
trigger.Triggered -= OnTriggerTriggered;
|
||||||
trigger.Stop();
|
trigger.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,6 +207,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using MediaBrowser.Model.Globalization;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||||
{
|
{
|
||||||
@ -15,12 +16,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask
|
public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask
|
||||||
{
|
{
|
||||||
/// <summary>
|
private readonly IConfigurationManager _configurationManager;
|
||||||
/// Gets or sets the configuration manager.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The configuration manager.</value>
|
|
||||||
private IConfigurationManager ConfigurationManager { get; set; }
|
|
||||||
|
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ILocalizationManager _localization;
|
private readonly ILocalizationManager _localization;
|
||||||
|
|
||||||
@ -32,18 +28,43 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
/// <param name="localization">The localization manager.</param>
|
/// <param name="localization">The localization manager.</param>
|
||||||
public DeleteLogFileTask(IConfigurationManager configurationManager, IFileSystem fileSystem, ILocalizationManager localization)
|
public DeleteLogFileTask(IConfigurationManager configurationManager, IFileSystem fileSystem, ILocalizationManager localization)
|
||||||
{
|
{
|
||||||
ConfigurationManager = configurationManager;
|
_configurationManager = configurationManager;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_localization = localization;
|
_localization = localization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Name => _localization.GetLocalizedString("TaskCleanLogs");
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Description => string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
_localization.GetLocalizedString("TaskCleanLogsDescription"),
|
||||||
|
_configurationManager.CommonConfiguration.LogFileRetentionDays);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Key => "CleanLogFiles";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsHidden => false;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsEnabled => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsLogged => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the triggers that define when the task will run.
|
/// Creates the triggers that define when the task will run.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
{
|
{
|
||||||
return new[] {
|
return new[]
|
||||||
|
{
|
||||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
|
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -57,10 +78,10 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
// Delete log files more than n days old
|
// Delete log files more than n days old
|
||||||
var minDateModified = DateTime.UtcNow.AddDays(-ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
|
var minDateModified = DateTime.UtcNow.AddDays(-_configurationManager.CommonConfiguration.LogFileRetentionDays);
|
||||||
|
|
||||||
// Only delete the .txt log files, the *.log files created by serilog get managed by itself
|
// Only delete the .txt log files, the *.log files created by serilog get managed by itself
|
||||||
var filesToDelete = _fileSystem.GetFiles(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, new[] { ".txt" }, true, true)
|
var filesToDelete = _fileSystem.GetFiles(_configurationManager.CommonApplicationPaths.LogDirectoryPath, new[] { ".txt" }, true, true)
|
||||||
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
|
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@ -83,26 +104,5 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Name => _localization.GetLocalizedString("TaskCleanLogs");
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Description => string.Format(_localization.GetLocalizedString("TaskCleanLogsDescription"), ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Key => "CleanLogFiles";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsHidden => false;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsEnabled => true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsLogged => true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ namespace Emby.Server.Implementations.Services
|
|||||||
|
|
||||||
public static List<string> GetFirstMatchWildCardHashKeys(string[] pathPartsForMatching)
|
public static List<string> GetFirstMatchWildCardHashKeys(string[] pathPartsForMatching)
|
||||||
{
|
{
|
||||||
const string hashPrefix = WildCard + PathSeperator;
|
const string HashPrefix = WildCard + PathSeperator;
|
||||||
return GetPotentialMatchesWithPrefix(hashPrefix, pathPartsForMatching);
|
return GetPotentialMatchesWithPrefix(HashPrefix, pathPartsForMatching);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<string> GetPotentialMatchesWithPrefix(string hashPrefix, string[] pathPartsForMatching)
|
private static List<string> GetPotentialMatchesWithPrefix(string hashPrefix, string[] pathPartsForMatching)
|
||||||
@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.Services
|
|||||||
{
|
{
|
||||||
list.Add(hashPrefix + part);
|
list.Add(hashPrefix + part);
|
||||||
|
|
||||||
if (part.IndexOf(ComponentSeperator) == -1)
|
if (part.IndexOf(ComponentSeperator, StringComparison.Ordinal) == -1)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ namespace Emby.Server.Implementations.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (component.IndexOf(VariablePrefix, StringComparison.OrdinalIgnoreCase) != -1
|
if (component.IndexOf(VariablePrefix, StringComparison.OrdinalIgnoreCase) != -1
|
||||||
&& component.IndexOf(ComponentSeperator) != -1)
|
&& component.IndexOf(ComponentSeperator, StringComparison.Ordinal) != -1)
|
||||||
{
|
{
|
||||||
hasSeparators.Add(true);
|
hasSeparators.Add(true);
|
||||||
componentsList.AddRange(component.Split(ComponentSeperator));
|
componentsList.AddRange(component.Split(ComponentSeperator));
|
||||||
|
@ -10,7 +10,6 @@ using MediaBrowser.Controller.Configuration;
|
|||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.TV;
|
using MediaBrowser.Controller.TV;
|
||||||
using MediaBrowser.Model.Dto;
|
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -240,11 +240,11 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
|||||||
if (protocol == MediaProtocol.File)
|
if (protocol == MediaProtocol.File)
|
||||||
{
|
{
|
||||||
var date = _fileSystem.GetLastWriteTimeUtc(mediaPath);
|
var date = _fileSystem.GetLastWriteTimeUtc(mediaPath);
|
||||||
filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture) + "_" + date.Ticks.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D");
|
filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture) + "_" + date.Ticks.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D");
|
filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
var prefix = filename.Substring(0, 1);
|
var prefix = filename.Substring(0, 1);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -48,7 +49,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
private static string GetFileInputArgument(string path)
|
private static string GetFileInputArgument(string path)
|
||||||
{
|
{
|
||||||
if (path.IndexOf("://") != -1)
|
if (path.IndexOf("://", StringComparison.Ordinal) != -1)
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", path);
|
return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", path);
|
||||||
}
|
}
|
||||||
@ -67,7 +68,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
private static string NormalizePath(string path)
|
private static string NormalizePath(string path)
|
||||||
{
|
{
|
||||||
// Quotes are valid path characters in linux and they need to be escaped here with a leading \
|
// Quotes are valid path characters in linux and they need to be escaped here with a leading \
|
||||||
return path.Replace("\"", "\\\"");
|
return path.Replace("\"", "\\\"", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,7 +374,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
var args = extractChapters
|
var args = extractChapters
|
||||||
? "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_chapters -show_format"
|
? "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_chapters -show_format"
|
||||||
: "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_format";
|
: "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_format";
|
||||||
args = string.Format(args, probeSizeArgument, inputPath).Trim();
|
args = string.Format(CultureInfo.InvariantCulture, args, probeSizeArgument, inputPath).Trim();
|
||||||
|
|
||||||
var process = new Process
|
var process = new Process
|
||||||
{
|
{
|
||||||
@ -853,7 +853,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
// https://ffmpeg.org/ffmpeg-filters.html#Notes-on-filtergraph-escaping
|
// https://ffmpeg.org/ffmpeg-filters.html#Notes-on-filtergraph-escaping
|
||||||
// We need to double escape
|
// We need to double escape
|
||||||
|
|
||||||
return path.Replace('\\', '/').Replace(":", "\\:").Replace("'", "'\\\\\\''");
|
return path.Replace('\\', '/').Replace(":", "\\:", StringComparison.Ordinal).Replace("'", "'\\\\\\''", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<!-- Code Analyzers-->
|
<!-- Code Analyzers-->
|
||||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
<!-- <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" /> -->
|
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
|
||||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
||||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||||
|
@ -42,7 +42,8 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||||||
var info = new MediaInfo
|
var info = new MediaInfo
|
||||||
{
|
{
|
||||||
Path = path,
|
Path = path,
|
||||||
Protocol = protocol
|
Protocol = protocol,
|
||||||
|
VideoType = videoType
|
||||||
};
|
};
|
||||||
|
|
||||||
FFProbeHelpers.NormalizeFFProbeResult(data);
|
FFProbeHelpers.NormalizeFFProbeResult(data);
|
||||||
@ -1133,7 +1134,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||||||
{
|
{
|
||||||
// Only use the comma as a delimeter if there are no slashes or pipes.
|
// Only use the comma as a delimeter if there are no slashes or pipes.
|
||||||
// We want to be careful not to split names that have commas in them
|
// We want to be careful not to split names that have commas in them
|
||||||
var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ?
|
var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i, StringComparison.Ordinal) != -1) ?
|
||||||
_nameDelimiters :
|
_nameDelimiters :
|
||||||
new[] { ',' };
|
new[] { ',' };
|
||||||
|
|
||||||
@ -1377,8 +1378,8 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||||||
if (subtitle.Contains('/', StringComparison.Ordinal)) // It contains a episode number and season number
|
if (subtitle.Contains('/', StringComparison.Ordinal)) // It contains a episode number and season number
|
||||||
{
|
{
|
||||||
string[] numbers = subtitle.Split(' ');
|
string[] numbers = subtitle.Split(' ');
|
||||||
video.IndexNumber = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[0]);
|
video.IndexNumber = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[0], CultureInfo.InvariantCulture);
|
||||||
int totalEpisodesInSeason = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[1]);
|
int totalEpisodesInSeason = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[1], CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
description = string.Join(" ", numbers, 1, numbers.Length - 1).Trim(); // Skip the first, concatenate the rest, clean up spaces and save it
|
description = string.Join(" ", numbers, 1, numbers.Length - 1).Trim(); // Skip the first, concatenate the rest, clean up spaces and save it
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
private void RemoteNativeFormatting(SubtitleTrackEvent p)
|
private void RemoteNativeFormatting(SubtitleTrackEvent p)
|
||||||
{
|
{
|
||||||
int indexOfBegin = p.Text.IndexOf('{');
|
int indexOfBegin = p.Text.IndexOf('{', StringComparison.Ordinal);
|
||||||
string pre = string.Empty;
|
string pre = string.Empty;
|
||||||
while (indexOfBegin >= 0 && p.Text.IndexOf('}') > indexOfBegin)
|
while (indexOfBegin >= 0 && p.Text.IndexOf('}', StringComparison.Ordinal) > indexOfBegin)
|
||||||
{
|
{
|
||||||
string s = p.Text.Substring(indexOfBegin);
|
string s = p.Text.Substring(indexOfBegin);
|
||||||
if (s.StartsWith("{\\an1}", StringComparison.Ordinal) ||
|
if (s.StartsWith("{\\an1}", StringComparison.Ordinal) ||
|
||||||
@ -116,10 +116,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
pre = s.Substring(0, 5) + "}";
|
pre = s.Substring(0, 5) + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexOfEnd = p.Text.IndexOf('}');
|
int indexOfEnd = p.Text.IndexOf('}', StringComparison.Ordinal);
|
||||||
p.Text = p.Text.Remove(indexOfBegin, (indexOfEnd - indexOfBegin) + 1);
|
p.Text = p.Text.Remove(indexOfBegin, (indexOfEnd - indexOfBegin) + 1);
|
||||||
|
|
||||||
indexOfBegin = p.Text.IndexOf('{');
|
indexOfBegin = p.Text.IndexOf('{', StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Text = pre + p.Text;
|
p.Text = pre + p.Text;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -50,14 +51,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
{
|
{
|
||||||
eventsStarted = true;
|
eventsStarted = true;
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";"))
|
else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
// skip comment lines
|
// skip comment lines
|
||||||
}
|
}
|
||||||
else if (eventsStarted && line.Trim().Length > 0)
|
else if (eventsStarted && line.Trim().Length > 0)
|
||||||
{
|
{
|
||||||
string s = line.Trim().ToLowerInvariant();
|
string s = line.Trim().ToLowerInvariant();
|
||||||
if (s.StartsWith("format:"))
|
if (s.StartsWith("format:", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
if (line.Length > 10)
|
if (line.Length > 10)
|
||||||
{
|
{
|
||||||
@ -103,7 +104,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
string[] splittedLine;
|
string[] splittedLine;
|
||||||
|
|
||||||
if (s.StartsWith("dialogue:"))
|
if (s.StartsWith("dialogue:", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
splittedLine = line.Substring(10).Split(',');
|
splittedLine = line.Substring(10).Split(',');
|
||||||
}
|
}
|
||||||
@ -181,10 +182,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
string[] timeCode = time.Split(':', '.');
|
string[] timeCode = time.Split(':', '.');
|
||||||
return new TimeSpan(
|
return new TimeSpan(
|
||||||
0,
|
0,
|
||||||
int.Parse(timeCode[0]),
|
int.Parse(timeCode[0], CultureInfo.InvariantCulture),
|
||||||
int.Parse(timeCode[1]),
|
int.Parse(timeCode[1], CultureInfo.InvariantCulture),
|
||||||
int.Parse(timeCode[2]),
|
int.Parse(timeCode[2], CultureInfo.InvariantCulture),
|
||||||
int.Parse(timeCode[3]) * 10).Ticks;
|
int.Parse(timeCode[3], CultureInfo.InvariantCulture) * 10).Ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetFormattedText(string text)
|
private static string GetFormattedText(string text)
|
||||||
@ -193,11 +194,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
for (int i = 0; i < 10; i++) // just look ten times...
|
for (int i = 0; i < 10; i++) // just look ten times...
|
||||||
{
|
{
|
||||||
if (text.Contains(@"{\fn"))
|
if (text.Contains(@"{\fn", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
int start = text.IndexOf(@"{\fn");
|
int start = text.IndexOf(@"{\fn", StringComparison.Ordinal);
|
||||||
int end = text.IndexOf('}', start);
|
int end = text.IndexOf('}', start);
|
||||||
if (end > 0 && !text.Substring(start).StartsWith("{\\fn}"))
|
if (end > 0 && !text.Substring(start).StartsWith("{\\fn}", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
string fontName = text.Substring(start + 4, end - (start + 4));
|
string fontName = text.Substring(start + 4, end - (start + 4));
|
||||||
string extraTags = string.Empty;
|
string extraTags = string.Empty;
|
||||||
@ -212,7 +213,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
text = text.Insert(start, "<font face=\"" + fontName + "\"" + extraTags + ">");
|
text = text.Insert(start, "<font face=\"" + fontName + "\"" + extraTags + ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexOfEndTag = text.IndexOf("{\\fn}", start);
|
int indexOfEndTag = text.IndexOf("{\\fn}", start, StringComparison.Ordinal);
|
||||||
if (indexOfEndTag > 0)
|
if (indexOfEndTag > 0)
|
||||||
{
|
{
|
||||||
text = text.Remove(indexOfEndTag, "{\\fn}".Length).Insert(indexOfEndTag, "</font>");
|
text = text.Remove(indexOfEndTag, "{\\fn}".Length).Insert(indexOfEndTag, "</font>");
|
||||||
@ -224,11 +225,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text.Contains(@"{\fs"))
|
if (text.Contains(@"{\fs", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
int start = text.IndexOf(@"{\fs");
|
int start = text.IndexOf(@"{\fs", StringComparison.Ordinal);
|
||||||
int end = text.IndexOf('}', start);
|
int end = text.IndexOf('}', start);
|
||||||
if (end > 0 && !text.Substring(start).StartsWith("{\\fs}"))
|
if (end > 0 && !text.Substring(start).StartsWith("{\\fs}", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
string fontSize = text.Substring(start + 4, end - (start + 4));
|
string fontSize = text.Substring(start + 4, end - (start + 4));
|
||||||
string extraTags = string.Empty;
|
string extraTags = string.Empty;
|
||||||
@ -245,7 +246,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
text = text.Insert(start, "<font size=\"" + fontSize + "\"" + extraTags + ">");
|
text = text.Insert(start, "<font size=\"" + fontSize + "\"" + extraTags + ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexOfEndTag = text.IndexOf("{\\fs}", start);
|
int indexOfEndTag = text.IndexOf("{\\fs}", start, StringComparison.Ordinal);
|
||||||
if (indexOfEndTag > 0)
|
if (indexOfEndTag > 0)
|
||||||
{
|
{
|
||||||
text = text.Remove(indexOfEndTag, "{\\fs}".Length).Insert(indexOfEndTag, "</font>");
|
text = text.Remove(indexOfEndTag, "{\\fs}".Length).Insert(indexOfEndTag, "</font>");
|
||||||
@ -258,17 +259,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text.Contains(@"{\c"))
|
if (text.Contains(@"{\c", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
int start = text.IndexOf(@"{\c");
|
int start = text.IndexOf(@"{\c", StringComparison.Ordinal);
|
||||||
int end = text.IndexOf('}', start);
|
int end = text.IndexOf('}', start);
|
||||||
if (end > 0 && !text.Substring(start).StartsWith("{\\c}"))
|
if (end > 0 && !text.Substring(start).StartsWith("{\\c}", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
string color = text.Substring(start + 4, end - (start + 4));
|
string color = text.Substring(start + 4, end - (start + 4));
|
||||||
string extraTags = string.Empty;
|
string extraTags = string.Empty;
|
||||||
CheckAndAddSubTags(ref color, ref extraTags, out bool italic);
|
CheckAndAddSubTags(ref color, ref extraTags, out bool italic);
|
||||||
|
|
||||||
color = color.Replace("&", string.Empty).TrimStart('H');
|
color = color.Replace("&", string.Empty, StringComparison.Ordinal).TrimStart('H');
|
||||||
color = color.PadLeft(6, '0');
|
color = color.PadLeft(6, '0');
|
||||||
|
|
||||||
// switch to rrggbb from bbggrr
|
// switch to rrggbb from bbggrr
|
||||||
@ -285,7 +286,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + ">");
|
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexOfEndTag = text.IndexOf("{\\c}", start);
|
int indexOfEndTag = text.IndexOf("{\\c}", start, StringComparison.Ordinal);
|
||||||
if (indexOfEndTag > 0)
|
if (indexOfEndTag > 0)
|
||||||
{
|
{
|
||||||
text = text.Remove(indexOfEndTag, "{\\c}".Length).Insert(indexOfEndTag, "</font>");
|
text = text.Remove(indexOfEndTag, "{\\c}".Length).Insert(indexOfEndTag, "</font>");
|
||||||
@ -297,17 +298,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text.Contains(@"{\1c")) // "1" specifices primary color
|
if (text.Contains(@"{\1c", StringComparison.Ordinal)) // "1" specifices primary color
|
||||||
{
|
{
|
||||||
int start = text.IndexOf(@"{\1c");
|
int start = text.IndexOf(@"{\1c", StringComparison.Ordinal);
|
||||||
int end = text.IndexOf('}', start);
|
int end = text.IndexOf('}', start);
|
||||||
if (end > 0 && !text.Substring(start).StartsWith("{\\1c}"))
|
if (end > 0 && !text.Substring(start).StartsWith("{\\1c}", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
string color = text.Substring(start + 5, end - (start + 5));
|
string color = text.Substring(start + 5, end - (start + 5));
|
||||||
string extraTags = string.Empty;
|
string extraTags = string.Empty;
|
||||||
CheckAndAddSubTags(ref color, ref extraTags, out bool italic);
|
CheckAndAddSubTags(ref color, ref extraTags, out bool italic);
|
||||||
|
|
||||||
color = color.Replace("&", string.Empty).TrimStart('H');
|
color = color.Replace("&", string.Empty, StringComparison.Ordinal).TrimStart('H');
|
||||||
color = color.PadLeft(6, '0');
|
color = color.PadLeft(6, '0');
|
||||||
|
|
||||||
// switch to rrggbb from bbggrr
|
// switch to rrggbb from bbggrr
|
||||||
@ -329,25 +330,25 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text = text.Replace(@"{\i1}", "<i>");
|
text = text.Replace(@"{\i1}", "<i>", StringComparison.Ordinal);
|
||||||
text = text.Replace(@"{\i0}", "</i>");
|
text = text.Replace(@"{\i0}", "</i>", StringComparison.Ordinal);
|
||||||
text = text.Replace(@"{\i}", "</i>");
|
text = text.Replace(@"{\i}", "</i>", StringComparison.Ordinal);
|
||||||
if (CountTagInText(text, "<i>") > CountTagInText(text, "</i>"))
|
if (CountTagInText(text, "<i>") > CountTagInText(text, "</i>"))
|
||||||
{
|
{
|
||||||
text += "</i>";
|
text += "</i>";
|
||||||
}
|
}
|
||||||
|
|
||||||
text = text.Replace(@"{\u1}", "<u>");
|
text = text.Replace(@"{\u1}", "<u>", StringComparison.Ordinal);
|
||||||
text = text.Replace(@"{\u0}", "</u>");
|
text = text.Replace(@"{\u0}", "</u>", StringComparison.Ordinal);
|
||||||
text = text.Replace(@"{\u}", "</u>");
|
text = text.Replace(@"{\u}", "</u>", StringComparison.Ordinal);
|
||||||
if (CountTagInText(text, "<u>") > CountTagInText(text, "</u>"))
|
if (CountTagInText(text, "<u>") > CountTagInText(text, "</u>"))
|
||||||
{
|
{
|
||||||
text += "</u>";
|
text += "</u>";
|
||||||
}
|
}
|
||||||
|
|
||||||
text = text.Replace(@"{\b1}", "<b>");
|
text = text.Replace(@"{\b1}", "<b>", StringComparison.Ordinal);
|
||||||
text = text.Replace(@"{\b0}", "</b>");
|
text = text.Replace(@"{\b0}", "</b>", StringComparison.Ordinal);
|
||||||
text = text.Replace(@"{\b}", "</b>");
|
text = text.Replace(@"{\b}", "</b>", StringComparison.Ordinal);
|
||||||
if (CountTagInText(text, "<b>") > CountTagInText(text, "</b>"))
|
if (CountTagInText(text, "<b>") > CountTagInText(text, "</b>"))
|
||||||
{
|
{
|
||||||
text += "</b>";
|
text += "</b>";
|
||||||
@ -362,7 +363,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
private static int CountTagInText(string text, string tag)
|
private static int CountTagInText(string text, string tag)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int index = text.IndexOf(tag);
|
int index = text.IndexOf(tag, StringComparison.Ordinal);
|
||||||
while (index >= 0)
|
while (index >= 0)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@ -371,7 +372,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = text.IndexOf(tag, index + 1);
|
index = text.IndexOf(tag, index + 1, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@ -380,7 +381,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
private static void CheckAndAddSubTags(ref string tagName, ref string extraTags, out bool italic)
|
private static void CheckAndAddSubTags(ref string tagName, ref string extraTags, out bool italic)
|
||||||
{
|
{
|
||||||
italic = false;
|
italic = false;
|
||||||
int indexOfSPlit = tagName.IndexOf(@"\");
|
int indexOfSPlit = tagName.IndexOf('\\', StringComparison.Ordinal);
|
||||||
if (indexOfSPlit > 0)
|
if (indexOfSPlit > 0)
|
||||||
{
|
{
|
||||||
string rest = tagName.Substring(indexOfSPlit).TrimStart('\\');
|
string rest = tagName.Substring(indexOfSPlit).TrimStart('\\');
|
||||||
@ -388,9 +389,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
if (rest.StartsWith("fs") && rest.Length > 2)
|
if (rest.StartsWith("fs", StringComparison.Ordinal) && rest.Length > 2)
|
||||||
{
|
{
|
||||||
indexOfSPlit = rest.IndexOf(@"\");
|
indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
|
||||||
string fontSize = rest;
|
string fontSize = rest;
|
||||||
if (indexOfSPlit > 0)
|
if (indexOfSPlit > 0)
|
||||||
{
|
{
|
||||||
@ -404,9 +405,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
extraTags += " size=\"" + fontSize.Substring(2) + "\"";
|
extraTags += " size=\"" + fontSize.Substring(2) + "\"";
|
||||||
}
|
}
|
||||||
else if (rest.StartsWith("fn") && rest.Length > 2)
|
else if (rest.StartsWith("fn", StringComparison.Ordinal) && rest.Length > 2)
|
||||||
{
|
{
|
||||||
indexOfSPlit = rest.IndexOf(@"\");
|
indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
|
||||||
string fontName = rest;
|
string fontName = rest;
|
||||||
if (indexOfSPlit > 0)
|
if (indexOfSPlit > 0)
|
||||||
{
|
{
|
||||||
@ -420,9 +421,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
extraTags += " face=\"" + fontName.Substring(2) + "\"";
|
extraTags += " face=\"" + fontName.Substring(2) + "\"";
|
||||||
}
|
}
|
||||||
else if (rest.StartsWith("c") && rest.Length > 2)
|
else if (rest.StartsWith("c", StringComparison.Ordinal) && rest.Length > 2)
|
||||||
{
|
{
|
||||||
indexOfSPlit = rest.IndexOf(@"\");
|
indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
|
||||||
string fontColor = rest;
|
string fontColor = rest;
|
||||||
if (indexOfSPlit > 0)
|
if (indexOfSPlit > 0)
|
||||||
{
|
{
|
||||||
@ -435,7 +436,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
}
|
}
|
||||||
|
|
||||||
string color = fontColor.Substring(2);
|
string color = fontColor.Substring(2);
|
||||||
color = color.Replace("&", string.Empty).TrimStart('H');
|
color = color.Replace("&", string.Empty, StringComparison.Ordinal).TrimStart('H');
|
||||||
color = color.PadLeft(6, '0');
|
color = color.PadLeft(6, '0');
|
||||||
// switch to rrggbb from bbggrr
|
// switch to rrggbb from bbggrr
|
||||||
color = "#" + color.Remove(color.Length - 6) + color.Substring(color.Length - 2, 2) + color.Substring(color.Length - 4, 2) + color.Substring(color.Length - 6, 2);
|
color = "#" + color.Remove(color.Length - 6) + color.Substring(color.Length - 2, 2) + color.Substring(color.Length - 4, 2) + color.Substring(color.Length - 6, 2);
|
||||||
@ -443,9 +444,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
extraTags += " color=\"" + color + "\"";
|
extraTags += " color=\"" + color + "\"";
|
||||||
}
|
}
|
||||||
else if (rest.StartsWith("i1") && rest.Length > 1)
|
else if (rest.StartsWith("i1", StringComparison.Ordinal) && rest.Length > 1)
|
||||||
{
|
{
|
||||||
indexOfSPlit = rest.IndexOf(@"\");
|
indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
|
||||||
italic = true;
|
italic = true;
|
||||||
if (indexOfSPlit > 0)
|
if (indexOfSPlit > 0)
|
||||||
{
|
{
|
||||||
@ -456,9 +457,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
rest = string.Empty;
|
rest = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rest.Length > 0 && rest.Contains("\\"))
|
else if (rest.Length > 0 && rest.Contains('\\', StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
indexOfSPlit = rest.IndexOf(@"\");
|
indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
|
||||||
rest = rest.Substring(indexOfSPlit).TrimStart('\\');
|
rest = rest.Substring(indexOfSPlit).TrimStart('\\');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,7 +415,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
// FFmpeg automatically convert character encoding when it is UTF-16
|
// FFmpeg automatically convert character encoding when it is UTF-16
|
||||||
// If we specify character encoding, it rejects with "do not specify a character encoding" and "Unable to recode subtitle event"
|
// If we specify character encoding, it rejects with "do not specify a character encoding" and "Unable to recode subtitle event"
|
||||||
if ((inputPath.EndsWith(".smi") || inputPath.EndsWith(".sami")) &&
|
if ((inputPath.EndsWith(".smi", StringComparison.Ordinal) || inputPath.EndsWith(".sami", StringComparison.Ordinal)) &&
|
||||||
(encodingParam.Equals("UTF-16BE", StringComparison.OrdinalIgnoreCase) ||
|
(encodingParam.Equals("UTF-16BE", StringComparison.OrdinalIgnoreCase) ||
|
||||||
encodingParam.Equals("UTF-16LE", StringComparison.OrdinalIgnoreCase)))
|
encodingParam.Equals("UTF-16LE", StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
@ -506,7 +506,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
string.Format(CultureInfo.InvariantCulture, "ffmpeg subtitle conversion failed for {0}", inputPath));
|
string.Format(CultureInfo.InvariantCulture, "ffmpeg subtitle conversion failed for {0}", inputPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
await SetAssFont(outputPath).ConfigureAwait(false);
|
await SetAssFont(outputPath, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.LogInformation("ffmpeg subtitle conversion succeeded for {Path}", inputPath);
|
_logger.LogInformation("ffmpeg subtitle conversion succeeded for {Path}", inputPath);
|
||||||
}
|
}
|
||||||
@ -668,7 +668,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
|
|
||||||
if (string.Equals(outputCodec, "ass", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(outputCodec, "ass", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
await SetAssFont(outputPath).ConfigureAwait(false);
|
await SetAssFont(outputPath, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,8 +676,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
/// Sets the ass font.
|
/// Sets the ass font.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="file">The file.</param>
|
/// <param name="file">The file.</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <c>System.Threading.CancellationToken.None</c>.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
private async Task SetAssFont(string file)
|
private async Task SetAssFont(string file, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Setting ass font within {File}", file);
|
_logger.LogInformation("Setting ass font within {File}", file);
|
||||||
|
|
||||||
@ -692,14 +693,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
text = await reader.ReadToEndAsync().ConfigureAwait(false);
|
text = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var newText = text.Replace(",Arial,", ",Arial Unicode MS,");
|
var newText = text.Replace(",Arial,", ",Arial Unicode MS,", StringComparison.Ordinal);
|
||||||
|
|
||||||
if (!string.Equals(text, newText))
|
if (!string.Equals(text, newText, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
|
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
using (var writer = new StreamWriter(fileStream, encoding))
|
using (var writer = new StreamWriter(fileStream, encoding))
|
||||||
{
|
{
|
||||||
writer.Write(newText);
|
await writer.WriteAsync(newText.AsMemory(), cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -736,7 +737,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||||||
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName;
|
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName;
|
||||||
|
|
||||||
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
|
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
|
||||||
if ((path.EndsWith(".ass") || path.EndsWith(".ssa") || path.EndsWith(".srt"))
|
if ((path.EndsWith(".ass", StringComparison.Ordinal) || path.EndsWith(".ssa", StringComparison.Ordinal) || path.EndsWith(".srt", StringComparison.Ordinal))
|
||||||
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|
||||||
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
|
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user