aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Common.Implementations/BaseApplicationHost.cs14
-rw-r--r--Emby.Common.Implementations/Diagnostics/CommonProcess.cs108
-rw-r--r--Emby.Common.Implementations/Diagnostics/ProcessFactory.cs12
-rw-r--r--Emby.Common.Implementations/Threading/CommonTimer.cs39
-rw-r--r--Emby.Common.Implementations/Threading/TimerFactory.cs21
-rw-r--r--Emby.Common.Implementations/project.json2
-rw-r--r--Emby.Server.sln18
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs7
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs41
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs26
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs148
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs7
-rw-r--r--MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj15
-rw-r--r--MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.nuget.targets6
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs15
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs111
-rw-r--r--MediaBrowser.MediaEncoding/project.json17
-rw-r--r--MediaBrowser.Model/Diagnostics/IProcessFactory.cs5
-rw-r--r--MediaBrowser.Model/TextEncoding/IEncoding.cs5
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj3
-rw-r--r--MediaBrowser.Server.Implementations/TextEncoding/TextEncoding.cs33
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs9
23 files changed, 449 insertions, 219 deletions
diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs
index 2fe82e5a4..897557efd 100644
--- a/Emby.Common.Implementations/BaseApplicationHost.cs
+++ b/Emby.Common.Implementations/BaseApplicationHost.cs
@@ -27,11 +27,16 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using Emby.Common.Implementations.Cryptography;
+using Emby.Common.Implementations.Diagnostics;
+using Emby.Common.Implementations.Threading;
using MediaBrowser.Common;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
+using MediaBrowser.Model.Threading;
+
#if NETSTANDARD1_6
using System.Runtime.Loader;
#endif
@@ -146,6 +151,9 @@ namespace Emby.Common.Implementations
protected ISystemEvents SystemEvents { get; private set; }
+ protected IProcessFactory ProcessFactory { get; private set; }
+ protected ITimerFactory TimerFactory { get; private set; }
+
/// <summary>
/// Gets the name.
/// </summary>
@@ -535,6 +543,12 @@ return null;
IsoManager = new IsoManager();
RegisterSingleInstance(IsoManager);
+ ProcessFactory = new ProcessFactory();
+ RegisterSingleInstance(ProcessFactory);
+
+ TimerFactory = new TimerFactory();
+ RegisterSingleInstance(TimerFactory);
+
return Task.FromResult(true);
}
diff --git a/Emby.Common.Implementations/Diagnostics/CommonProcess.cs b/Emby.Common.Implementations/Diagnostics/CommonProcess.cs
new file mode 100644
index 000000000..06677bc29
--- /dev/null
+++ b/Emby.Common.Implementations/Diagnostics/CommonProcess.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Diagnostics;
+
+namespace Emby.Common.Implementations.Diagnostics
+{
+ public class CommonProcess : IProcess
+ {
+ public event EventHandler Exited;
+
+ private readonly ProcessOptions _options;
+ private readonly Process _process;
+
+ public CommonProcess(ProcessOptions options)
+ {
+ _options = options;
+
+ var startInfo = new ProcessStartInfo
+ {
+ Arguments = options.Arguments,
+ FileName = options.FileName,
+ WorkingDirectory = options.WorkingDirectory,
+ UseShellExecute = options.UseShellExecute,
+ CreateNoWindow = options.CreateNoWindow,
+ RedirectStandardError = options.RedirectStandardError,
+ RedirectStandardInput = options.RedirectStandardInput,
+ RedirectStandardOutput = options.RedirectStandardOutput
+ };
+
+#if NET46
+ startInfo.ErrorDialog = options.ErrorDialog;
+
+ if (options.IsHidden)
+ {
+ startInfo.WindowStyle = ProcessWindowStyle.Hidden;
+ }
+#endif
+
+ _process = new Process
+ {
+ StartInfo = startInfo
+ };
+
+ if (options.EnableRaisingEvents)
+ {
+ _process.EnableRaisingEvents = true;
+ _process.Exited += _process_Exited;
+ }
+ }
+
+ private void _process_Exited(object sender, EventArgs e)
+ {
+ if (Exited != null)
+ {
+ Exited(_process, e);
+ }
+ }
+
+ public ProcessOptions StartInfo
+ {
+ get { return _options; }
+ }
+
+ public StreamWriter StandardInput
+ {
+ get { return _process.StandardInput; }
+ }
+
+ public StreamReader StandardError
+ {
+ get { return _process.StandardError; }
+ }
+
+ public StreamReader StandardOutput
+ {
+ get { return _process.StandardOutput; }
+ }
+
+ public int ExitCode
+ {
+ get { return _process.ExitCode; }
+ }
+
+ public void Start()
+ {
+ _process.Start();
+ }
+
+ public void Kill()
+ {
+ _process.Kill();
+ }
+
+ public bool WaitForExit(int timeMs)
+ {
+ return _process.WaitForExit(timeMs);
+ }
+
+ public void Dispose()
+ {
+ _process.Dispose();
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Diagnostics/ProcessFactory.cs b/Emby.Common.Implementations/Diagnostics/ProcessFactory.cs
new file mode 100644
index 000000000..292da023c
--- /dev/null
+++ b/Emby.Common.Implementations/Diagnostics/ProcessFactory.cs
@@ -0,0 +1,12 @@
+using MediaBrowser.Model.Diagnostics;
+
+namespace Emby.Common.Implementations.Diagnostics
+{
+ public class ProcessFactory : IProcessFactory
+ {
+ public IProcess Create(ProcessOptions options)
+ {
+ return new CommonProcess(options);
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Threading/CommonTimer.cs b/Emby.Common.Implementations/Threading/CommonTimer.cs
new file mode 100644
index 000000000..8895f6798
--- /dev/null
+++ b/Emby.Common.Implementations/Threading/CommonTimer.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Threading;
+
+namespace Emby.Common.Implementations.Threading
+{
+ public class CommonTimer : ITimer
+ {
+ private readonly Timer _timer;
+
+ public CommonTimer(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period)
+ {
+ _timer = new Timer(new TimerCallback(callback), state, dueTime, period);
+ }
+
+ public CommonTimer(Action<object> callback, object state, int dueTimeMs, int periodMs)
+ {
+ _timer = new Timer(new TimerCallback(callback), state, dueTimeMs, periodMs);
+ }
+
+ public void Change(TimeSpan dueTime, TimeSpan period)
+ {
+ _timer.Change(dueTime, period);
+ }
+
+ public void Change(int dueTimeMs, int periodMs)
+ {
+ _timer.Change(dueTimeMs, periodMs);
+ }
+
+ public void Dispose()
+ {
+ _timer.Dispose();
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Threading/TimerFactory.cs b/Emby.Common.Implementations/Threading/TimerFactory.cs
new file mode 100644
index 000000000..028dd0963
--- /dev/null
+++ b/Emby.Common.Implementations/Threading/TimerFactory.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Threading;
+
+namespace Emby.Common.Implementations.Threading
+{
+ public class TimerFactory : ITimerFactory
+ {
+ public ITimer Create(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period)
+ {
+ return new CommonTimer(callback, state, dueTime, period);
+ }
+
+ public ITimer Create(Action<object> callback, object state, int dueTimeMs, int periodMs)
+ {
+ return new CommonTimer(callback, state, dueTimeMs, periodMs);
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/project.json b/Emby.Common.Implementations/project.json
index 444d0e13e..a65b86345 100644
--- a/Emby.Common.Implementations/project.json
+++ b/Emby.Common.Implementations/project.json
@@ -44,6 +44,8 @@
"target": "project"
},
"System.IO.FileSystem.DriveInfo": "4.0.0",
+ "System.Diagnostics.Process": "4.1.0",
+ "System.Threading.Timer": "4.0.1",
"System.Net.Requests": "4.0.11",
"System.Xml.XmlSerializer": "4.0.11",
"System.Net.Http": "4.1.0",
diff --git a/Emby.Server.sln b/Emby.Server.sln
index 2e2e093d5..e9073a8d0 100644
--- a/Emby.Server.sln
+++ b/Emby.Server.sln
@@ -42,6 +42,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Emby.Dlna", "Emby.Dlna\Emby
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Photos", "Emby.Photos\Emby.Photos.csproj", "{89AB4548-770D-41FD-A891-8DAFF44F452C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Api", "MediaBrowser.Api\MediaBrowser.Api.csproj", "{4FD51AC5-2C16-4308-A993-C3A84F3B4582}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -145,6 +149,18 @@ Global
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -166,5 +182,7 @@ Global
{C227ADB7-E256-4E70-A8B9-22B9E0CF4F55} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{F40E364D-01D9-4BBF-B82C-5D6C55E0A1F5} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{89AB4548-770D-41FD-A891-8DAFF44F452C} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
EndGlobalSection
EndGlobal
diff --git a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
index 06f992efd..5a554d26f 100644
--- a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
@@ -7,15 +7,13 @@ using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Diagnostics;
namespace MediaBrowser.MediaEncoding.Encoder
{
public class AudioEncoder : BaseEncoder
{
- public AudioEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IIsoManager isoManager, ILibraryManager libraryManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager) : base(mediaEncoder, logger, configurationManager, fileSystem, isoManager, libraryManager, sessionManager, subtitleEncoder, mediaSourceManager)
+ public AudioEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IIsoManager isoManager, ILibraryManager libraryManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager, IProcessFactory processFactory) : base(mediaEncoder, logger, configurationManager, fileSystem, isoManager, libraryManager, sessionManager, subtitleEncoder, mediaSourceManager, processFactory)
{
}
@@ -116,5 +114,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
get { return false; }
}
+
}
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index f43f01871..b8087fded 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -11,15 +11,12 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.Dlna;
namespace MediaBrowser.MediaEncoding.Encoder
@@ -35,6 +32,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
protected readonly ISessionManager SessionManager;
protected readonly ISubtitleEncoder SubtitleEncoder;
protected readonly IMediaSourceManager MediaSourceManager;
+ protected IProcessFactory ProcessFactory;
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
@@ -46,7 +44,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
ILibraryManager libraryManager,
ISessionManager sessionManager,
ISubtitleEncoder subtitleEncoder,
- IMediaSourceManager mediaSourceManager)
+ IMediaSourceManager mediaSourceManager, IProcessFactory processFactory)
{
MediaEncoder = mediaEncoder;
Logger = logger;
@@ -57,6 +55,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
SessionManager = sessionManager;
SubtitleEncoder = subtitleEncoder;
MediaSourceManager = mediaSourceManager;
+ ProcessFactory = processFactory;
}
public async Task<EncodingJob> Start(EncodingJobOptions options,
@@ -75,27 +74,23 @@ namespace MediaBrowser.MediaEncoding.Encoder
var commandLineArgs = await GetCommandLineArguments(encodingJob).ConfigureAwait(false);
- var process = new Process
+ var process = ProcessFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
-
- // Must consume both stdout and stderr or deadlocks may occur
- //RedirectStandardOutput = true,
- RedirectStandardError = true,
- RedirectStandardInput = true,
+ CreateNoWindow = true,
+ UseShellExecute = false,
- FileName = MediaEncoder.EncoderPath,
- Arguments = commandLineArgs,
+ // Must consume both stdout and stderr or deadlocks may occur
+ //RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ RedirectStandardInput = true,
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false
- },
+ FileName = MediaEncoder.EncoderPath,
+ Arguments = commandLineArgs,
+ IsHidden = true,
+ ErrorDialog = false,
EnableRaisingEvents = true
- };
+ });
var workingDirectory = GetWorkingDirectory(options);
if (!string.IsNullOrWhiteSpace(workingDirectory))
@@ -149,7 +144,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return encodingJob;
}
- private void Cancel(Process process, EncodingJob job)
+ private void Cancel(IProcess process, EncodingJob job)
{
Logger.Info("Killing ffmpeg process for {0}", job.OutputFilePath);
@@ -164,7 +159,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary>
/// <param name="process">The process.</param>
/// <param name="job">The job.</param>
- private void OnFfMpegProcessExited(Process process, EncodingJob job)
+ private void OnFfMpegProcessExited(IProcess process, EncodingJob job)
{
job.HasExited = true;
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index a78d6cfd6..20b5eb05d 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.Logging;
namespace MediaBrowser.MediaEncoding.Encoder
@@ -8,10 +9,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
public class EncoderValidator
{
private readonly ILogger _logger;
+ private readonly IProcessFactory _processFactory;
- public EncoderValidator(ILogger logger)
+ public EncoderValidator(ILogger logger, IProcessFactory processFactory)
{
_logger = logger;
+ _processFactory = processFactory;
}
public Tuple<List<string>, List<string>> Validate(string encoderPath)
@@ -145,19 +148,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
private string GetProcessOutput(string path, string arguments)
{
- var process = new Process
+ var process = _processFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- FileName = path,
- Arguments = arguments,
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false,
- RedirectStandardOutput = true
- }
- };
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ FileName = path,
+ Arguments = arguments,
+ IsHidden = true,
+ ErrorDialog = false,
+ RedirectStandardOutput = true
+ });
_logger.Info("Running {0} {1}", path, arguments);
diff --git a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs b/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs
index 7f4e7909a..42048ab9e 100644
--- a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs
@@ -88,9 +88,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <returns>Task.</returns>
private async Task DownloadFontFile(string fontsDirectory, string fontFilename, IProgress<double> progress)
{
- var existingFile = Directory
- .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories)
- .FirstOrDefault();
+ var existingFile = _fileSystem
+ .GetFilePaths(_appPaths.ProgramDataPath, true)
+ .FirstOrDefault(i => string.Equals(fontFilename, Path.GetFileName(i), StringComparison.OrdinalIgnoreCase));
if (existingFile != null)
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index bf6ff7655..d9571f8e5 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -14,19 +14,16 @@ using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.Diagnostics;
namespace MediaBrowser.MediaEncoding.Encoder
{
@@ -81,14 +78,19 @@ namespace MediaBrowser.MediaEncoding.Encoder
protected readonly Func<IMediaSourceManager> MediaSourceManager;
private readonly IHttpClient _httpClient;
private readonly IZipClient _zipClient;
+ private readonly IProcessFactory _processFactory;
private readonly IMemoryStreamProvider _memoryStreamProvider;
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
private readonly bool _hasExternalEncoder;
- private string _originalFFMpegPath;
- private string _originalFFProbePath;
-
- public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager, IHttpClient httpClient, IZipClient zipClient, IMemoryStreamProvider memoryStreamProvider)
+ private readonly string _originalFFMpegPath;
+ private readonly string _originalFFProbePath;
+ private readonly int DefaultImageExtractionTimeoutMs;
+ private readonly bool EnableEncoderFontFile;
+
+ public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager, IHttpClient httpClient, IZipClient zipClient, IMemoryStreamProvider memoryStreamProvider, IProcessFactory processFactory,
+ int defaultImageExtractionTimeoutMs,
+ bool enableEncoderFontFile)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
@@ -104,6 +106,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
_httpClient = httpClient;
_zipClient = zipClient;
_memoryStreamProvider = memoryStreamProvider;
+ _processFactory = processFactory;
+ DefaultImageExtractionTimeoutMs = defaultImageExtractionTimeoutMs;
+ EnableEncoderFontFile = enableEncoderFontFile;
FFProbePath = ffProbePath;
FFMpegPath = ffMpegPath;
_originalFFProbePath = ffProbePath;
@@ -158,12 +163,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!string.IsNullOrWhiteSpace(FFMpegPath))
{
- var result = new EncoderValidator(_logger).Validate(FFMpegPath);
+ var result = new EncoderValidator(_logger, _processFactory).Validate(FFMpegPath);
SetAvailableDecoders(result.Item1);
SetAvailableEncoders(result.Item2);
- if (Environment.OSVersion.Platform == PlatformID.Win32NT)
+ if (EnableEncoderFontFile)
{
var directory = Path.GetDirectoryName(FFMpegPath);
@@ -255,7 +260,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private bool ValidateVersion(string path, bool logOutput)
{
- return new EncoderValidator(_logger).ValidateVersion(path, logOutput);
+ return new EncoderValidator(_logger, _processFactory).ValidateVersion(path, logOutput);
}
private void ConfigureEncoderPaths()
@@ -509,27 +514,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
? "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_chapters -show_format"
: "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_format";
- var process = new Process
+ var process = _processFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
-
- // Must consume both or ffmpeg may hang due to deadlocks. See comments below.
- RedirectStandardOutput = true,
- //RedirectStandardError = true,
- RedirectStandardInput = false,
- FileName = FFProbePath,
- Arguments = string.Format(args,
- probeSizeArgument, inputPath).Trim(),
-
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false
- },
-
+ CreateNoWindow = true,
+ UseShellExecute = false,
+
+ // Must consume both or ffmpeg may hang due to deadlocks. See comments below.
+ RedirectStandardOutput = true,
+ //RedirectStandardError = true,
+ RedirectStandardInput = false,
+ FileName = FFProbePath,
+ Arguments = string.Format(args, probeSizeArgument, inputPath).Trim(),
+
+ IsHidden = true,
+ ErrorDialog = false,
EnableRaisingEvents = true
- };
+ });
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
@@ -644,26 +644,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
var args = "{0} -i {1} -map 0:v:{2} -an -filter:v idet -frames:v 500 -an -f null /dev/null";
- var process = new Process
+ var process = _processFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
-
- // Must consume both or ffmpeg may hang due to deadlocks. See comments below.
- //RedirectStandardOutput = true,
- RedirectStandardError = true,
- RedirectStandardInput = false,
- FileName = FFMpegPath,
- Arguments = string.Format(args, probeSizeArgument, inputPath, videoStream.Index.ToString(CultureInfo.InvariantCulture)).Trim(),
-
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false
- },
-
+ CreateNoWindow = true,
+ UseShellExecute = false,
+
+ // Must consume both or ffmpeg may hang due to deadlocks. See comments below.
+ //RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ RedirectStandardInput = false,
+ FileName = FFMpegPath,
+ Arguments = string.Format(args, probeSizeArgument, inputPath, videoStream.Index.ToString(CultureInfo.InvariantCulture)).Trim(),
+
+ IsHidden = true,
+ ErrorDialog = false,
EnableRaisingEvents = true
- };
+ });
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
var idetFoundInterlaced = false;
@@ -916,18 +912,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args;
}
- var process = new Process
+ var process = _processFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- FileName = FFMpegPath,
- Arguments = args,
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false
- }
- };
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ FileName = FFMpegPath,
+ Arguments = args,
+ IsHidden = true,
+ ErrorDialog = false
+ });
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
@@ -944,7 +937,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var timeoutMs = ConfigurationManager.Configuration.ImageExtractionTimeoutMs;
if (timeoutMs <= 0)
{
- timeoutMs = Environment.Is64BitOperatingSystem ? (Environment.ProcessorCount > 2 ? 14000 : 20000) : 40000;
+ timeoutMs = DefaultImageExtractionTimeoutMs;
}
ranToCompletion = process.WaitForExit(timeoutMs);
@@ -1022,19 +1015,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
args = probeSize + " " + args;
}
- var process = new Process
+ var process = _processFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- FileName = FFMpegPath,
- Arguments = args,
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false,
- RedirectStandardInput = true
- }
- };
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ FileName = FFMpegPath,
+ Arguments = args,
+ IsHidden = true,
+ ErrorDialog = false,
+ RedirectStandardInput = true
+ });
_logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments);
@@ -1107,7 +1097,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
LibraryManager,
SessionManager,
SubtitleEncoder(),
- MediaSourceManager())
+ MediaSourceManager(),
+ _processFactory)
.Start(options, progress, cancellationToken).ConfigureAwait(false);
await job.TaskCompletionSource.Task.ConfigureAwait(false);
@@ -1127,7 +1118,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
LibraryManager,
SessionManager,
SubtitleEncoder(),
- MediaSourceManager())
+ MediaSourceManager(),
+ _processFactory)
.Start(options, progress, cancellationToken).ConfigureAwait(false);
await job.TaskCompletionSource.Task.ConfigureAwait(false);
@@ -1231,14 +1223,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
private class ProcessWrapper : IDisposable
{
- public readonly Process Process;
+ public readonly IProcess Process;
public bool HasExited;
public int? ExitCode;
private readonly MediaEncoder _mediaEncoder;
private readonly ILogger _logger;
public bool IsRedirectingStdin { get; private set; }
- public ProcessWrapper(Process process, MediaEncoder mediaEncoder, ILogger logger, bool isRedirectingStdin)
+ public ProcessWrapper(IProcess process, MediaEncoder mediaEncoder, ILogger logger, bool isRedirectingStdin)
{
Process = process;
_mediaEncoder = mediaEncoder;
@@ -1249,7 +1241,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
void Process_Exited(object sender, EventArgs e)
{
- var process = (Process)sender;
+ var process = (IProcess)sender;
HasExited = true;
@@ -1269,7 +1261,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
DisposeProcess(process);
}
- private void DisposeProcess(Process process)
+ private void DisposeProcess(IProcess process)
{
try
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
index 73f82b61c..cbbca479a 100644
--- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
@@ -8,15 +8,13 @@ using MediaBrowser.Model.Logging;
using System;
using System.IO;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Diagnostics;
namespace MediaBrowser.MediaEncoding.Encoder
{
public class VideoEncoder : BaseEncoder
{
- public VideoEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IIsoManager isoManager, ILibraryManager libraryManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager) : base(mediaEncoder, logger, configurationManager, fileSystem, isoManager, libraryManager, sessionManager, subtitleEncoder, mediaSourceManager)
+ public VideoEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IIsoManager isoManager, ILibraryManager libraryManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager, IProcessFactory processFactory) : base(mediaEncoder, logger, configurationManager, fileSystem, isoManager, libraryManager, sessionManager, subtitleEncoder, mediaSourceManager, processFactory)
{
}
@@ -193,5 +191,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
get { return true; }
}
+
}
} \ No newline at end of file
diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
index 89e0b61c1..63e789a59 100644
--- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
+++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
@@ -9,10 +9,10 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MediaBrowser.MediaEncoding</RootNamespace>
<AssemblyName>MediaBrowser.MediaEncoding</AssemblyName>
- <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <TargetFrameworkProfile />
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -37,13 +37,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
<Reference Include="UniversalDetector, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\UniversalDetector.1.0.1\lib\portable-net45+sl4+wp71+win8+wpa81\UniversalDetector.dll</HintPath>
<Private>True</Private>
@@ -108,7 +101,7 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.nuget.targets b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.nuget.targets
new file mode 100644
index 000000000..e69ce0e64
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.nuget.targets
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Target Name="EmitMSBuildWarning" BeforeTargets="Build">
+ <Warning Text="Packages containing MSBuild targets and props files cannot be fully installed in projects targeting multiple frameworks. The MSBuild targets and props files have been ignored." />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs b/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs
index d8f36de9a..e26a6392c 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs
@@ -14,6 +14,7 @@ using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
@@ -31,14 +32,16 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private readonly IEncryptionManager _encryption;
private readonly IJsonSerializer _json;
+ private readonly IFileSystem _fileSystem;
- public OpenSubtitleDownloader(ILogManager logManager, IHttpClient httpClient, IServerConfigurationManager config, IEncryptionManager encryption, IJsonSerializer json)
+ public OpenSubtitleDownloader(ILogManager logManager, IHttpClient httpClient, IServerConfigurationManager config, IEncryptionManager encryption, IJsonSerializer json, IFileSystem fileSystem)
{
_logger = logManager.GetLogger(GetType().Name);
_httpClient = httpClient;
_config = config;
_encryption = encryption;
_json = json;
+ _fileSystem = fileSystem;
_config.NamedConfigurationUpdating += _config_NamedConfigurationUpdating;
@@ -133,7 +136,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
if ((DateTime.UtcNow - _lastRateLimitException).TotalHours < 1)
{
- throw new ApplicationException("OpenSubtitles rate limit reached");
+ throw new Exception("OpenSubtitles rate limit reached");
}
var resultDownLoad = await OpenSubtitles.DownloadSubtitlesAsync(downloadsList, cancellationToken).ConfigureAwait(false);
@@ -141,12 +144,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
if ((resultDownLoad.Status ?? string.Empty).IndexOf("407", StringComparison.OrdinalIgnoreCase) != -1)
{
_lastRateLimitException = DateTime.UtcNow;
- throw new ApplicationException("OpenSubtitles rate limit reached");
+ throw new Exception("OpenSubtitles rate limit reached");
}
if (!(resultDownLoad is MethodResponseSubtitleDownload))
{
- throw new ApplicationException("Invalid response type");
+ throw new Exception("Invalid response type");
}
var results = ((MethodResponseSubtitleDownload)resultDownLoad).Results;
@@ -269,11 +272,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var subLanguageId = NormalizeLanguage(request.Language);
string hash;
- using (var fileStream = File.OpenRead(request.MediaPath))
+ using (var fileStream = _fileSystem.OpenRead(request.MediaPath))
{
hash = Utilities.ComputeHash(fileStream);
}
- var fileInfo = new FileInfo(request.MediaPath);
+ var fileInfo = _fileSystem.GetFileInfo(request.MediaPath);
var movieByteSize = fileInfo.Length;
var searchImdbId = request.ContentType == VideoContentType.Movie ? imdbId.ToString(_usCulture) : "";
var subtitleSearchParameters = request.ContentType == VideoContentType.Episode
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index 416184f49..1248d138d 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -18,9 +18,8 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Diagnostics;
+using MediaBrowser.Model.TextEncoding;
using UniversalDetector;
namespace MediaBrowser.MediaEncoding.Subtitles
@@ -36,8 +35,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private readonly IHttpClient _httpClient;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IMemoryStreamProvider _memoryStreamProvider;
+ private readonly IProcessFactory _processFactory;
+ private readonly IEncoding _textEncoding;
- public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IJsonSerializer json, IHttpClient httpClient, IMediaSourceManager mediaSourceManager, IMemoryStreamProvider memoryStreamProvider)
+ public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IJsonSerializer json, IHttpClient httpClient, IMediaSourceManager mediaSourceManager, IMemoryStreamProvider memoryStreamProvider, IProcessFactory processFactory, IEncoding textEncoding)
{
_libraryManager = libraryManager;
_logger = logger;
@@ -48,6 +49,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_httpClient = httpClient;
_mediaSourceManager = mediaSourceManager;
_memoryStreamProvider = memoryStreamProvider;
+ _processFactory = processFactory;
+ _textEncoding = textEncoding;
}
private string SubtitleCachePath
@@ -418,7 +421,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// or
/// outputPath
/// </exception>
- /// <exception cref="System.ApplicationException"></exception>
private async Task ConvertTextSubtitleToSrtInternal(string inputPath, string language, MediaProtocol inputProtocol, string outputPath, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(inputPath))
@@ -440,23 +442,20 @@ namespace MediaBrowser.MediaEncoding.Subtitles
encodingParam = " -sub_charenc " + encodingParam;
}
- var process = new Process
+ var process = _processFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- RedirectStandardOutput = false,
- RedirectStandardError = true,
- RedirectStandardInput = true,
+ RedirectStandardOutput = false,
+ RedirectStandardError = true,
+ RedirectStandardInput = true,
- CreateNoWindow = true,
- UseShellExecute = false,
- FileName = _mediaEncoder.EncoderPath,
- Arguments = string.Format("{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath),
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ FileName = _mediaEncoder.EncoderPath,
+ Arguments = string.Format("{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath),
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false
- }
- };
+ IsHidden = true,
+ ErrorDialog = false
+ });
_logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
@@ -538,7 +537,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_logger.Error(msg);
- throw new ApplicationException(msg);
+ throw new Exception(msg);
}
await SetAssFont(outputPath).ConfigureAwait(false);
}
@@ -593,23 +592,20 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s {2} \"{3}\"", inputPath,
subtitleStreamIndex, outputCodec, outputPath);
- var process = new Process
+ var process = _processFactory.Create(new ProcessOptions
{
- StartInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
+ CreateNoWindow = true,
+ UseShellExecute = false,
- RedirectStandardOutput = false,
- RedirectStandardError = true,
- RedirectStandardInput = true,
+ RedirectStandardOutput = false,
+ RedirectStandardError = true,
+ RedirectStandardInput = true,
- FileName = _mediaEncoder.EncoderPath,
- Arguments = processArgs,
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false
- }
- };
+ FileName = _mediaEncoder.EncoderPath,
+ Arguments = processArgs,
+ IsHidden = true,
+ ErrorDialog = false
+ });
_logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
@@ -675,10 +671,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
}
- catch (DirectoryNotFoundException)
- {
-
- }
catch (IOException ex)
{
_logger.ErrorException("Error deleting extracted subtitle {0}", ex, outputPath);
@@ -695,7 +687,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_logger.Error(msg);
- throw new ApplicationException(msg);
+ throw new Exception(msg);
}
else
{
@@ -749,20 +741,26 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string text;
Encoding encoding;
- using (var reader = new StreamReader(file, true))
+ using (var fileStream = _fileSystem.OpenRead(file))
{
- encoding = reader.CurrentEncoding;
+ using (var reader = new StreamReader(fileStream, true))
+ {
+ encoding = reader.CurrentEncoding;
- text = await reader.ReadToEndAsync().ConfigureAwait(false);
+ text = await reader.ReadToEndAsync().ConfigureAwait(false);
+ }
}
var newText = text.Replace(",Arial,", ",Arial Unicode MS,");
if (!string.Equals(text, newText))
{
- using (var writer = new StreamWriter(file, false, encoding))
+ using (var fileStream = _fileSystem.GetFileStream(file, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{
- writer.Write(newText);
+ using (var writer = new StreamWriter(fileStream, encoding))
+ {
+ writer.Write(newText);
+ }
}
}
}
@@ -795,7 +793,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
if (protocol == MediaProtocol.File)
{
- if (GetFileEncoding(path).Equals(Encoding.UTF8))
+ if (_textEncoding.GetFileEncoding(path).Equals(Encoding.UTF8))
{
return string.Empty;
}
@@ -902,29 +900,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
return null;
}
- private Encoding GetFileEncoding(string srcFile)
- {
- // *** Detect byte order mark if any - otherwise assume default
- var buffer = new byte[5];
-
- using (var file = _fileSystem.GetFileStream(srcFile, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite))
- {
- file.Read(buffer, 0, 5);
- }
-
- if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
- return Encoding.UTF8;
- if (buffer[0] == 0xfe && buffer[1] == 0xff)
- return Encoding.Unicode;
- if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
- return Encoding.UTF32;
- if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
- return Encoding.UTF7;
-
- // It's ok - anything aside from utf is ok since that's what we're looking for
- return Encoding.Default;
- }
-
private async Task<Stream> GetStream(string path, MediaProtocol protocol, CancellationToken cancellationToken)
{
if (protocol == MediaProtocol.Http)
diff --git a/MediaBrowser.MediaEncoding/project.json b/MediaBrowser.MediaEncoding/project.json
new file mode 100644
index 000000000..fbbe9eaf3
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/project.json
@@ -0,0 +1,17 @@
+{
+ "frameworks":{
+ "netstandard1.6":{
+ "dependencies":{
+ "NETStandard.Library":"1.6.0",
+ }
+ },
+ ".NETPortable,Version=v4.5,Profile=Profile7":{
+ "buildOptions": {
+ "define": [ ]
+ },
+ "frameworkAssemblies":{
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Model/Diagnostics/IProcessFactory.cs b/MediaBrowser.Model/Diagnostics/IProcessFactory.cs
index 998bbcd28..a60c4b4fb 100644
--- a/MediaBrowser.Model/Diagnostics/IProcessFactory.cs
+++ b/MediaBrowser.Model/Diagnostics/IProcessFactory.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace MediaBrowser.Model.Diagnostics
{
@@ -22,6 +18,7 @@ namespace MediaBrowser.Model.Diagnostics
public bool ErrorDialog { get; set; }
public bool RedirectStandardError { get; set; }
public bool RedirectStandardInput { get; set; }
+ public bool RedirectStandardOutput { get; set; }
public bool IsHidden { get; set; }
}
}
diff --git a/MediaBrowser.Model/TextEncoding/IEncoding.cs b/MediaBrowser.Model/TextEncoding/IEncoding.cs
index 3b9652e3a..3d884c9d2 100644
--- a/MediaBrowser.Model/TextEncoding/IEncoding.cs
+++ b/MediaBrowser.Model/TextEncoding/IEncoding.cs
@@ -1,9 +1,12 @@
-
+using System.Text;
+
namespace MediaBrowser.Model.TextEncoding
{
public interface IEncoding
{
byte[] GetASCIIBytes(string text);
string GetASCIIString(byte[] bytes, int startIndex, int length);
+
+ Encoding GetFileEncoding(string path);
}
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index e6f203120..24fe077c2 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -70,6 +70,9 @@
<Reference Include="ServiceStack.Api.Swagger">
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath>
</Reference>
+ <Reference Include="ServiceStack.Common">
+ <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Common.dll</HintPath>
+ </Reference>
<Reference Include="SharpCompress, Version=0.10.3.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
diff --git a/MediaBrowser.Server.Implementations/TextEncoding/TextEncoding.cs b/MediaBrowser.Server.Implementations/TextEncoding/TextEncoding.cs
index c1029dfb5..4c047b7d5 100644
--- a/MediaBrowser.Server.Implementations/TextEncoding/TextEncoding.cs
+++ b/MediaBrowser.Server.Implementations/TextEncoding/TextEncoding.cs
@@ -1,10 +1,18 @@
using System.Text;
+using MediaBrowser.Model.IO;
using MediaBrowser.Model.TextEncoding;
namespace MediaBrowser.Server.Implementations.TextEncoding
{
- public class TextEncoding : IEncoding
+ public class TextEncoding : IEncoding
{
+ private readonly IFileSystem _fileSystem;
+
+ public TextEncoding(IFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+
public byte[] GetASCIIBytes(string text)
{
return Encoding.ASCII.GetBytes(text);
@@ -14,5 +22,28 @@ namespace MediaBrowser.Server.Implementations.TextEncoding
{
return Encoding.ASCII.GetString(bytes, 0, bytes.Length);
}
+
+ public Encoding GetFileEncoding(string srcFile)
+ {
+ // *** Detect byte order mark if any - otherwise assume default
+ var buffer = new byte[5];
+
+ using (var file = _fileSystem.OpenRead(srcFile))
+ {
+ file.Read(buffer, 0, 5);
+ }
+
+ if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
+ return Encoding.UTF8;
+ if (buffer[0] == 0xfe && buffer[1] == 0xff)
+ return Encoding.Unicode;
+ if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
+ return Encoding.UTF32;
+ if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
+ return Encoding.UTF7;
+
+ // It's ok - anything aside from utf is ok since that's what we're looking for
+ return Encoding.Default;
+ }
}
}
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 7ff50df63..2e86b6c3e 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -547,7 +547,7 @@ namespace MediaBrowser.Server.Startup.Common
StringExtensions.LocalizationManager = LocalizationManager;
RegisterSingleInstance(LocalizationManager);
- IEncoding textEncoding = new TextEncoding();
+ IEncoding textEncoding = new TextEncoding(FileSystemManager);
RegisterSingleInstance(textEncoding);
Utilities.EncodingHelper = textEncoding;
RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer(FileSystemManager, textEncoding));
@@ -697,7 +697,7 @@ namespace MediaBrowser.Server.Startup.Common
RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
RegisterSingleInstance<IAuthService>(new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager));
- SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamProvider);
+ SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamProvider, ProcessFactory, textEncoding);
RegisterSingleInstance(SubtitleEncoder);
await displayPreferencesRepo.Initialize().ConfigureAwait(false);
@@ -789,7 +789,10 @@ namespace MediaBrowser.Server.Startup.Common
() => SubtitleEncoder,
() => MediaSourceManager,
HttpClient,
- ZipClient, MemoryStreamProvider);
+ ZipClient, MemoryStreamProvider,
+ ProcessFactory,
+ Environment.Is64BitOperatingSystem ? (Environment.ProcessorCount > 2 ? 14000 : 20000) : 40000,
+ Environment.OSVersion.Platform == PlatformID.Win32NT);
MediaEncoder = mediaEncoder;
RegisterSingleInstance(MediaEncoder);