diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-31 23:07:45 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-31 23:07:45 -0400 |
| commit | 13d8110ce29a7d976c3e88dc4b330922964ac11a (patch) | |
| tree | ddc2a61bfd9d001224aa640e220c7903ac62cb74 /MediaBrowser.Api | |
| parent | b28857feea210a40f984e69517bcbafbfb639773 (diff) | |
make api project portable
Diffstat (limited to 'MediaBrowser.Api')
24 files changed, 222 insertions, 254 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 588236a399..8f5b5eaaf3 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -16,9 +16,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; +using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.IO; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api { @@ -46,6 +47,8 @@ namespace MediaBrowser.Api private readonly ISessionManager _sessionManager; private readonly IFileSystem _fileSystem; private readonly IMediaSourceManager _mediaSourceManager; + public readonly ITimerFactory TimerFactory; + public readonly IProcessFactory ProcessFactory; /// <summary> /// The active transcoding jobs @@ -63,13 +66,15 @@ namespace MediaBrowser.Api /// <param name="config">The configuration.</param> /// <param name="fileSystem">The file system.</param> /// <param name="mediaSourceManager">The media source manager.</param> - public ApiEntryPoint(ILogger logger, ISessionManager sessionManager, IServerConfigurationManager config, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager) + public ApiEntryPoint(ILogger logger, ISessionManager sessionManager, IServerConfigurationManager config, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager, ITimerFactory timerFactory, IProcessFactory processFactory) { Logger = logger; _sessionManager = sessionManager; _config = config; _fileSystem = fileSystem; _mediaSourceManager = mediaSourceManager; + TimerFactory = timerFactory; + ProcessFactory = processFactory; Instance = this; _sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress; @@ -116,7 +121,7 @@ namespace MediaBrowser.Api { DeleteEncodedMediaCache(); } - catch (DirectoryNotFoundException) + catch (FileNotFoundException) { // Don't clutter the log } @@ -168,7 +173,8 @@ namespace MediaBrowser.Api // Try to allow for some time to kill the ffmpeg processes and delete the partial stream files if (jobCount > 0) { - Thread.Sleep(1000); + var task = Task.Delay(1000); + Task.WaitAll(task); } } @@ -190,14 +196,14 @@ namespace MediaBrowser.Api string liveStreamId, string transcodingJobId, TranscodingJobType type, - Process process, + IProcess process, string deviceId, StreamState state, CancellationTokenSource cancellationTokenSource) { lock (_activeTranscodingJobs) { - var job = new TranscodingJob(Logger) + var job = new TranscodingJob(Logger, TimerFactory) { Type = type, Path = path, @@ -600,10 +606,6 @@ namespace MediaBrowser.Api DeleteHlsPartialStreamFiles(path); } } - catch (DirectoryNotFoundException) - { - - } catch (FileNotFoundException) { @@ -651,10 +653,6 @@ namespace MediaBrowser.Api //Logger.Debug("Deleting HLS file {0}", file); _fileSystem.DeleteFile(file); } - catch (DirectoryNotFoundException) - { - - } catch (FileNotFoundException) { @@ -706,7 +704,7 @@ namespace MediaBrowser.Api /// Gets or sets the process. /// </summary> /// <value>The process.</value> - public Process Process { get; set; } + public IProcess Process { get; set; } public ILogger Logger { get; private set; } /// <summary> /// Gets or sets the active request count. @@ -717,7 +715,9 @@ namespace MediaBrowser.Api /// Gets or sets the kill timer. /// </summary> /// <value>The kill timer.</value> - private Timer KillTimer { get; set; } + private ITimer KillTimer { get; set; } + + private readonly ITimerFactory _timerFactory; public string DeviceId { get; set; } @@ -747,9 +747,10 @@ namespace MediaBrowser.Api public DateTime LastPingDate { get; set; } public int PingTimeout { get; set; } - public TranscodingJob(ILogger logger) + public TranscodingJob(ILogger logger, ITimerFactory timerFactory) { Logger = logger; + _timerFactory = timerFactory; } public void StopKillTimer() @@ -775,12 +776,12 @@ namespace MediaBrowser.Api } } - public void StartKillTimer(TimerCallback callback) + public void StartKillTimer(Action<object> callback) { StartKillTimer(callback, PingTimeout); } - public void StartKillTimer(TimerCallback callback, int intervalMs) + public void StartKillTimer(Action<object> callback, int intervalMs) { if (HasExited) { @@ -792,7 +793,7 @@ namespace MediaBrowser.Api if (KillTimer == null) { //Logger.Debug("Starting kill timer at {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId); - KillTimer = new Timer(callback, this, intervalMs, Timeout.Infinite); + KillTimer = _timerFactory.Create(callback, this, intervalMs, Timeout.Infinite); } else { diff --git a/MediaBrowser.Api/BasePeriodicWebSocketListener.cs b/MediaBrowser.Api/BasePeriodicWebSocketListener.cs index b650cd4c2d..fe7de387f8 100644 --- a/MediaBrowser.Api/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Api/BasePeriodicWebSocketListener.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api { @@ -22,8 +23,8 @@ namespace MediaBrowser.Api /// <summary> /// The _active connections /// </summary> - protected readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>> ActiveConnections = - new List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>>(); + protected readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType, SemaphoreSlim>> ActiveConnections = + new List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType, SemaphoreSlim>>(); /// <summary> /// Gets the name. @@ -43,12 +44,9 @@ namespace MediaBrowser.Api /// </summary> protected ILogger Logger; - /// <summary> - /// Initializes a new instance of the <see cref="BasePeriodicWebSocketListener{TStateType}" /> class. - /// </summary> - /// <param name="logger">The logger.</param> - /// <exception cref="System.ArgumentNullException">logger</exception> - protected BasePeriodicWebSocketListener(ILogger logger) + protected ITimerFactory TimerFactory { get; private set; } + + protected BasePeriodicWebSocketListener(ILogger logger, ITimerFactory timerFactory) { if (logger == null) { @@ -56,6 +54,7 @@ namespace MediaBrowser.Api } Logger = logger; + TimerFactory = timerFactory; } /// <summary> @@ -124,7 +123,7 @@ namespace MediaBrowser.Api Logger.Debug("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); var timer = SendOnTimer ? - new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : + TimerFactory.Create(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : null; var state = new TStateType @@ -137,7 +136,7 @@ namespace MediaBrowser.Api lock (ActiveConnections) { - ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>(message.Connection, cancellationTokenSource, timer, state, semaphore)); + ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType, SemaphoreSlim>(message.Connection, cancellationTokenSource, timer, state, semaphore)); } if (timer != null) @@ -154,7 +153,7 @@ namespace MediaBrowser.Api { var connection = (IWebSocketConnection)state; - Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> tuple; + Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType, SemaphoreSlim> tuple; lock (ActiveConnections) { @@ -177,7 +176,7 @@ namespace MediaBrowser.Api protected void SendData(bool force) { - List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>> tuples; + List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType, SemaphoreSlim>> tuples; lock (ActiveConnections) { @@ -205,7 +204,7 @@ namespace MediaBrowser.Api } } - private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> tuple) + private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType, SemaphoreSlim> tuple) { var connection = tuple.Item1; @@ -266,7 +265,7 @@ namespace MediaBrowser.Api /// Disposes the connection. /// </summary> /// <param name="connection">The connection.</param> - private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> connection) + private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType, SemaphoreSlim> connection) { Logger.Debug("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index c05446fbb8..bab538c91f 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -4,12 +4,8 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; using MediaBrowser.Model.Services; namespace MediaBrowser.Api @@ -110,6 +106,7 @@ namespace MediaBrowser.Api public class EnvironmentService : BaseApiService { const char UncSeparator = '\\'; + const string UncSeparatorString = "\\"; /// <summary> /// The _network manager @@ -139,7 +136,7 @@ namespace MediaBrowser.Api try { var qnap = "/share/CACHEDEV1_DATA"; - if (Directory.Exists(qnap)) + if (_fileSystem.DirectoryExists(qnap)) { result.Path = qnap; } @@ -166,7 +163,7 @@ namespace MediaBrowser.Api throw new ArgumentNullException("Path"); } - var networkPrefix = UncSeparator.ToString(CultureInfo.InvariantCulture) + UncSeparator.ToString(CultureInfo.InvariantCulture); + var networkPrefix = UncSeparatorString + UncSeparatorString; if (path.StartsWith(networkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf(UncSeparator) == 1) { @@ -203,13 +200,11 @@ namespace MediaBrowser.Api /// <returns>IEnumerable{FileSystemEntryInfo}.</returns> private IEnumerable<FileSystemEntryInfo> GetDrives() { - // Only include drives in the ready state or this method could end up being very slow, waiting for drives to timeout - return DriveInfo.GetDrives().Where(d => d.IsReady).Select(d => new FileSystemEntryInfo + return _fileSystem.GetDrives().Select(d => new FileSystemEntryInfo { - Name = GetName(d), - Path = d.RootDirectory.FullName, + Name = d.Name, + Path = d.FullName, Type = FileSystemEntryType.Directory - }); } @@ -228,16 +223,6 @@ namespace MediaBrowser.Api } /// <summary> - /// Gets the name. - /// </summary> - /// <param name="drive">The drive.</param> - /// <returns>System.String.</returns> - private string GetName(DriveInfo drive) - { - return drive.Name; - } - - /// <summary> /// Gets the network shares. /// </summary> /// <param name="path">The path.</param> diff --git a/MediaBrowser.Api/Images/ImageByNameService.cs b/MediaBrowser.Api/Images/ImageByNameService.cs index 12ac8f68f0..e0a9246c10 100644 --- a/MediaBrowser.Api/Images/ImageByNameService.cs +++ b/MediaBrowser.Api/Images/ImageByNameService.cs @@ -150,7 +150,7 @@ namespace MediaBrowser.Api.Images .OrderBy(i => i.Name) .ToList(); } - catch (DirectoryNotFoundException) + catch (IOException) { return new List<ImageByNameInfo>(); } diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index dba90d2730..c41907a878 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -320,7 +320,7 @@ namespace MediaBrowser.Api.Images { if (info.IsLocalFile) { - var fileInfo = new FileInfo(info.Path); + var fileInfo = _fileSystem.GetFileInfo(info.Path); length = fileInfo.Length; var size = _imageProcessor.GetImageSize(info); diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index f6c9c9767b..eb871746d7 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -234,21 +234,18 @@ namespace MediaBrowser.Api.Images try { - using (var reader = new StreamReader(pointerCachePath)) - { - contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); - } + contentPath = _fileSystem.ReadAllText(pointerCachePath); - if (_fileSystem.FileExists(contentPath)) + if (_fileSystem.FileExists(contentPath)) { return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } } - catch (DirectoryNotFoundException) + catch (FileNotFoundException) { // Means the file isn't cached yet } - catch (FileNotFoundException) + catch (IOException) { // Means the file isn't cached yet } @@ -256,10 +253,7 @@ namespace MediaBrowser.Api.Images await DownloadImage(request.ImageUrl, urlHash, pointerCachePath).ConfigureAwait(false); // Read the pointer file again - using (var reader = new StreamReader(pointerCachePath)) - { - contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); - } + contentPath = _fileSystem.ReadAllText(pointerCachePath); return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } @@ -294,10 +288,7 @@ namespace MediaBrowser.Api.Images } _fileSystem.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); - using (var writer = new StreamWriter(pointerCachePath)) - { - await writer.WriteAsync(fullCachePath).ConfigureAwait(false); - } + _fileSystem.WriteAllText(pointerCachePath, fullCachePath); } /// <summary> diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index bdb9133d34..1700a10cd3 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -247,21 +247,18 @@ namespace MediaBrowser.Api try { - using (var reader = new StreamReader(pointerCachePath)) - { - contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); - } + contentPath = _fileSystem.ReadAllText(pointerCachePath); if (_fileSystem.FileExists(contentPath)) { return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } } - catch (DirectoryNotFoundException) + catch (FileNotFoundException) { // Means the file isn't cached yet } - catch (FileNotFoundException) + catch (IOException) { // Means the file isn't cached yet } @@ -269,10 +266,7 @@ namespace MediaBrowser.Api await DownloadImage(request.ProviderName, request.ImageUrl, urlHash, pointerCachePath).ConfigureAwait(false); // Read the pointer file again - using (var reader = new StreamReader(pointerCachePath)) - { - contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); - } + contentPath = _fileSystem.ReadAllText(pointerCachePath); return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } @@ -303,10 +297,7 @@ namespace MediaBrowser.Api } _fileSystem.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); - using (var writer = new StreamWriter(pointerCachePath)) - { - await writer.WriteAsync(fullCachePath).ConfigureAwait(false); - } + _fileSystem.WriteAllText(pointerCachePath, fullCachePath); } /// <summary> diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs index 35948b453e..ea610ac5c1 100644 --- a/MediaBrowser.Api/Library/FileOrganizationService.cs +++ b/MediaBrowser.Api/Library/FileOrganizationService.cs @@ -204,10 +204,10 @@ namespace MediaBrowser.Api.Library public void Post(DeleteSmartMatchEntry request) { - request.Entries.ForEach(entry => + foreach (var entry in request.Entries) { _iFileOrganizationService.DeleteSmartMatchEntry(entry.Name, entry.Value); - }); + } } } } diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index 18afcd51e6..c3bb80dcb5 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -259,7 +259,7 @@ namespace MediaBrowser.Api.Library if (!_fileSystem.DirectoryExists(currentPath)) { - throw new DirectoryNotFoundException("The media collection does not exist"); + throw new FileNotFoundException("The media collection does not exist"); } if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && _fileSystem.DirectoryExists(newPath)) diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 83785466cd..fffd7ad7ef 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -22,7 +22,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.IO; using MediaBrowser.Model.Services; -using MediaBrowser.Server.Implementations.LiveTv.EmbyTV; namespace MediaBrowser.Api.LiveTv { @@ -708,11 +707,11 @@ namespace MediaBrowser.Api.LiveTv _fileSystem = fileSystem; } - public async Task<object> Get(GetLiveRecordingFile request) + public object Get(GetLiveRecordingFile request) { - var path = EmbyTV.Current.GetActiveRecordingPath(request.Id); + var path = _liveTvManager.GetEmbyTvActiveRecordingPath(request.Id); - if (path == null) + if (string.IsNullOrWhiteSpace(path)) { throw new FileNotFoundException(); } @@ -729,7 +728,7 @@ namespace MediaBrowser.Api.LiveTv public async Task<object> Get(GetLiveStreamFile request) { - var directStreamProvider = (await EmbyTV.Current.GetLiveStream(request.Id).ConfigureAwait(false)) as IDirectStreamProvider; + var directStreamProvider = (await _liveTvManager.GetEmbyTvLiveStream(request.Id).ConfigureAwait(false)) as IDirectStreamProvider; var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container); diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index fdfbaae0f0..df491ce855 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -11,10 +11,9 @@ <AssemblyName>MediaBrowser.Api</AssemblyName> <FileAlignment>512</FileAlignment> <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> - <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> - <ReleaseVersion> - </ReleaseVersion> - <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> @@ -46,13 +45,6 @@ <RunPostBuildEvent>Always</RunPostBuildEvent> </PropertyGroup> <ItemGroup> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Data" /> - <Reference Include="System.Xml" /> - </ItemGroup> - <ItemGroup> <Compile Include="..\SharedVersion.cs"> <Link>Properties\SharedVersion.cs</Link> </Compile> @@ -183,12 +175,8 @@ <Project>{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}</Project> <Name>MediaBrowser.Model</Name> </ProjectReference> - <ProjectReference Include="..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj"> - <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project> - <Name>MediaBrowser.Server.Implementations</Name> - </ProjectReference> </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <PropertyGroup> <PostBuildEvent> </PostBuildEvent> diff --git a/MediaBrowser.Api/MediaBrowser.Api.nuget.targets b/MediaBrowser.Api/MediaBrowser.Api.nuget.targets new file mode 100644 index 0000000000..e69ce0e64f --- /dev/null +++ b/MediaBrowser.Api/MediaBrowser.Api.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.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index ba3b3e348d..c628892149 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; -using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Dlna; @@ -14,18 +13,15 @@ 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.Text; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Model.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller; -using MediaBrowser.Controller.IO; +using MediaBrowser.Model.Diagnostics; namespace MediaBrowser.Api.Playback { @@ -1158,32 +1154,24 @@ namespace MediaBrowser.Api.Playback var transcodingId = Guid.NewGuid().ToString("N"); var commandLineArgs = GetCommandLineArguments(outputPath, state, true); - var process = new Process + var process = ApiEntryPoint.Instance.ProcessFactory.Create(new ProcessOptions { - StartInfo = new ProcessStartInfo - { - CreateNoWindow = true, - UseShellExecute = false, + CreateNoWindow = true, + UseShellExecute = false, - // Must consume both stdout and stderr or deadlocks may occur - //RedirectStandardOutput = true, - RedirectStandardError = true, - RedirectStandardInput = true, + // Must consume both stdout and stderr or deadlocks may occur + //RedirectStandardOutput = true, + RedirectStandardError = true, + RedirectStandardInput = true, - FileName = MediaEncoder.EncoderPath, - Arguments = commandLineArgs, + FileName = MediaEncoder.EncoderPath, + Arguments = commandLineArgs, - WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false - }, - - EnableRaisingEvents = true - }; - - if (!string.IsNullOrWhiteSpace(workingDirectory)) - { - process.StartInfo.WorkingDirectory = workingDirectory; - } + IsHidden = true, + ErrorDialog = false, + EnableRaisingEvents = true, + WorkingDirectory = !string.IsNullOrWhiteSpace(workingDirectory) ? workingDirectory : null + }); var transcodingJob = ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath, state.Request.PlaySessionId, @@ -1268,7 +1256,7 @@ namespace MediaBrowser.Api.Playback { if (EnableThrottling(state)) { - transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager); + transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager, ApiEntryPoint.Instance.TimerFactory, FileSystem); state.TranscodingThrottler.Start(); } } @@ -1520,7 +1508,7 @@ namespace MediaBrowser.Api.Playback /// <param name="process">The process.</param> /// <param name="job">The job.</param> /// <param name="state">The state.</param> - private void OnFfMpegProcessExited(Process process, TranscodingJob job, StreamState state) + private void OnFfMpegProcessExited(IProcess process, TranscodingJob job, StreamState state) { if (job != null) { @@ -2408,97 +2396,98 @@ namespace MediaBrowser.Api.Playback { return Task.FromResult(true); } + return Task.FromResult(true); - var dict = new Dictionary<string, string>(); + //var dict = new Dictionary<string, string>(); - var outputAudio = GetAudioEncoder(state); - if (!string.IsNullOrWhiteSpace(outputAudio)) - { - dict["outputAudio"] = outputAudio; - } - - var outputVideo = GetVideoEncoder(state); - if (!string.IsNullOrWhiteSpace(outputVideo)) - { - dict["outputVideo"] = outputVideo; - } + //var outputAudio = GetAudioEncoder(state); + //if (!string.IsNullOrWhiteSpace(outputAudio)) + //{ + // dict["outputAudio"] = outputAudio; + //} - if (ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase) && - ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase)) - { - return Task.FromResult(true); - } + //var outputVideo = GetVideoEncoder(state); + //if (!string.IsNullOrWhiteSpace(outputVideo)) + //{ + // dict["outputVideo"] = outputVideo; + //} - dict["id"] = AppHost.SystemId; - dict["type"] = state.VideoRequest == null ? "Audio" : "Video"; + //if (ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase) && + // ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + //{ + // return Task.FromResult(true); + //} - var audioStream = state.AudioStream; - if (audioStream != null && !string.IsNullOrWhiteSpace(audioStream.Codec)) - { - dict["inputAudio"] = audioStream.Codec; - } + //dict["id"] = AppHost.SystemId; + //dict["type"] = state.VideoRequest == null ? "Audio" : "Video"; - var videoStream = state.VideoStream; - if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec)) - { - dict["inputVideo"] = videoStream.Codec; - } + //var audioStream = state.AudioStream; + //if (audioStream != null && !string.IsNullOrWhiteSpace(audioStream.Codec)) + //{ + // dict["inputAudio"] = audioStream.Codec; + //} - var cert = GetType().Assembly.GetModules().First().GetSignerCertificate(); - if (cert != null) - { - dict["assemblySig"] = cert.GetCertHashString(); - dict["certSubject"] = cert.Subject ?? string.Empty; - dict["certIssuer"] = cert.Issuer ?? string.Empty; - } - else - { - return Task.FromResult(true); - } + //var videoStream = state.VideoStream; + //if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec)) + //{ + // dict["inputVideo"] = videoStream.Codec; + //} - if (state.SupportedAudioCodecs.Count > 0) - { - dict["supportedAudioCodecs"] = string.Join(",", state.SupportedAudioCodecs.ToArray()); - } + //var cert = GetType().Assembly.GetModules().First().GetSignerCertificate(); + //if (cert != null) + //{ + // dict["assemblySig"] = cert.GetCertHashString(); + // dict["certSubject"] = cert.Subject ?? string.Empty; + // dict["certIssuer"] = cert.Issuer ?? string.Empty; + //} + //else + //{ + // return Task.FromResult(true); + //} - var auth = AuthorizationContext.GetAuthorizationInfo(Request); + //if (state.SupportedAudioCodecs.Count > 0) + //{ + // dict["supportedAudioCodecs"] = string.Join(",", state.SupportedAudioCodecs.ToArray()); + //} - dict["appName"] = auth.Client ?? string.Empty; - dict["appVersion"] = auth.Version ?? string.Empty; - dict["device"] = auth.Device ?? string.Empty; - dict["deviceId"] = auth.DeviceId ?? string.Empty; - dict["context"] = "streaming"; + //var auth = AuthorizationContext.GetAuthorizationInfo(Request); - //Logger.Info(JsonSerializer.SerializeToString(dict)); - if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase)) - { - var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList(); - list.Add(outputAudio); - ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray(); - } + //dict["appName"] = auth.Client ?? string.Empty; + //dict["appVersion"] = auth.Version ?? string.Empty; + //dict["device"] = auth.Device ?? string.Empty; + //dict["deviceId"] = auth.DeviceId ?? string.Empty; + //dict["context"] = "streaming"; - if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase)) - { - var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList(); - list.Add(outputVideo); - ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray(); - } + ////Logger.Info(JsonSerializer.SerializeToString(dict)); + //if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + //{ + // var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList(); + // list.Add(outputAudio); + // ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray(); + //} - ServerConfigurationManager.SaveConfiguration(); + //if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + //{ + // var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList(); + // list.Add(outputVideo); + // ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray(); + //} - //Logger.Info(JsonSerializer.SerializeToString(dict)); - var options = new HttpRequestOptions() - { - Url = "https://mb3admin.com/admin/service/transcoding/report", - CancellationToken = CancellationToken.None, - LogRequest = false, - LogErrors = false, - BufferContent = false - }; - options.RequestContent = JsonSerializer.SerializeToString(dict); - options.RequestContentType = "application/json"; + //ServerConfigurationManager.SaveConfiguration(); - return HttpClient.Post(options); + ////Logger.Info(JsonSerializer.SerializeToString(dict)); + //var options = new HttpRequestOptions() + //{ + // Url = "https://mb3admin.com/admin/service/transcoding/report", + // CancellationToken = CancellationToken.None, + // LogRequest = false, + // LogErrors = false, + // BufferContent = false + //}; + //options.RequestContent = JsonSerializer.SerializeToString(dict); + //options.RequestContentType = "application/json"; + + //return HttpClient.Post(options); } /// <summary> diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 07ace5c2c2..353e832057 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -356,7 +356,8 @@ namespace MediaBrowser.Api.Playback.Hls { Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, file.FullName); - Thread.Sleep(100); + var task = Task.Delay(100); + Task.WaitAll(task); DeleteFile(file, retryCount + 1); } catch (Exception ex) @@ -378,7 +379,7 @@ namespace MediaBrowser.Api.Playback.Hls .OrderByDescending(fileSystem.GetLastWriteTimeUtc) .FirstOrDefault(); } - catch (DirectoryNotFoundException) + catch (IOException) { return null; } @@ -881,7 +882,7 @@ namespace MediaBrowser.Api.Playback.Hls if (state.IsOutputVideo && !EnableCopyTs(state) && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && (state.Request.StartTimeTicks ?? 0) > 0) { - timestampOffsetParam = " -output_ts_offset " + MediaEncoder.GetTimeParameter(state.Request.StartTimeTicks ?? 0).ToString(CultureInfo.InvariantCulture); + timestampOffsetParam = " -output_ts_offset " + MediaEncoder.GetTimeParameter(state.Request.StartTimeTicks ?? 0); } var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty; diff --git a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs index 4519268fcf..65c1af79e3 100644 --- a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs +++ b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs @@ -79,11 +79,13 @@ namespace MediaBrowser.Api.Playback.Hls { private readonly IServerApplicationPaths _appPaths; private readonly IServerConfigurationManager _config; + private readonly IFileSystem _fileSystem; - public HlsSegmentService(IServerApplicationPaths appPaths, IServerConfigurationManager config) + public HlsSegmentService(IServerApplicationPaths appPaths, IServerConfigurationManager config, IFileSystem fileSystem) { _appPaths = appPaths; _config = config; + _fileSystem = fileSystem; } public Task<object> Get(GetHlsPlaylistLegacy request) @@ -111,7 +113,7 @@ namespace MediaBrowser.Api.Playback.Hls var normalizedPlaylistId = request.PlaylistId; - var playlistPath = Directory.EnumerateFiles(_config.ApplicationPaths.TranscodingTempPath, "*") + var playlistPath = _fileSystem.GetFilePaths(_config.ApplicationPaths.TranscodingTempPath) .FirstOrDefault(i => string.Equals(Path.GetExtension(i), ".m3u8", StringComparison.OrdinalIgnoreCase) && i.IndexOf(normalizedPlaylistId, StringComparison.OrdinalIgnoreCase) != -1); return GetFileResult(file, playlistPath); diff --git a/MediaBrowser.Api/Playback/TranscodingThrottler.cs b/MediaBrowser.Api/Playback/TranscodingThrottler.cs index a7d53cd447..c42d0c3e4c 100644 --- a/MediaBrowser.Api/Playback/TranscodingThrottler.cs +++ b/MediaBrowser.Api/Playback/TranscodingThrottler.cs @@ -2,8 +2,8 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using System; -using System.IO; -using System.Threading; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api.Playback { @@ -11,15 +11,19 @@ namespace MediaBrowser.Api.Playback { private readonly TranscodingJob _job; private readonly ILogger _logger; - private Timer _timer; + private ITimer _timer; private bool _isPaused; private readonly IConfigurationManager _config; + private readonly ITimerFactory _timerFactory; + private readonly IFileSystem _fileSystem; - public TranscodingThrottler(TranscodingJob job, ILogger logger, IConfigurationManager config) + public TranscodingThrottler(TranscodingJob job, ILogger logger, IConfigurationManager config, ITimerFactory timerFactory, IFileSystem fileSystem) { _job = job; _logger = logger; _config = config; + _timerFactory = timerFactory; + _fileSystem = fileSystem; } private EncodingOptions GetOptions() @@ -29,7 +33,7 @@ namespace MediaBrowser.Api.Playback public void Start() { - _timer = new Timer(TimerCallback, null, 5000, 5000); + _timer = _timerFactory.Create(TimerCallback, null, 5000, 5000); } private void TimerCallback(object state) @@ -120,7 +124,7 @@ namespace MediaBrowser.Api.Playback try { - var bytesTranscoded = job.BytesTranscoded ?? new FileInfo(path).Length; + var bytesTranscoded = job.BytesTranscoded ?? _fileSystem.GetFileInfo(path).Length; // Estimate the bytes the transcoder should be ahead double gapFactor = gapLengthInTicks; diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index 6e64345b9f..ee74ec450c 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -1,10 +1,10 @@ -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Events; +using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api.ScheduledTasks { @@ -31,10 +31,8 @@ namespace MediaBrowser.Api.ScheduledTasks /// <summary> /// Initializes a new instance of the <see cref="ScheduledTasksWebSocketListener" /> class. /// </summary> - /// <param name="logger">The logger.</param> - /// <param name="taskManager">The task manager.</param> - public ScheduledTasksWebSocketListener(ILogger logger, ITaskManager taskManager) - : base(logger) + public ScheduledTasksWebSocketListener(ILogger logger, ITaskManager taskManager, ITimerFactory timerFactory) + : base(logger, timerFactory) { TaskManager = taskManager; @@ -84,7 +82,7 @@ namespace MediaBrowser.Api.ScheduledTasks { TaskManager.TaskExecuting -= TaskManager_TaskExecuting; TaskManager.TaskCompleted -= TaskManager_TaskCompleted; - + base.Dispose(dispose); } } diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs index 8f68569b7a..b90a718529 100644 --- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs @@ -6,6 +6,7 @@ using MediaBrowser.Model.Session; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api.Session { @@ -31,10 +32,8 @@ namespace MediaBrowser.Api.Session /// <summary> /// Initializes a new instance of the <see cref="SessionInfoWebSocketListener"/> class. /// </summary> - /// <param name="logger">The logger.</param> - /// <param name="sessionManager">The session manager.</param> - public SessionInfoWebSocketListener(ILogger logger, ISessionManager sessionManager) - : base(logger) + public SessionInfoWebSocketListener(ILogger logger, ISessionManager sessionManager, ITimerFactory timerFactory) + : base(logger, timerFactory) { _sessionManager = sessionManager; diff --git a/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs b/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs index 61a26d160a..ac9749a6dc 100644 --- a/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs +++ b/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs @@ -1,11 +1,11 @@ -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Sync; +using MediaBrowser.Controller.Sync; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Sync; using System; using System.Linq; using System.Threading.Tasks; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api.Sync { @@ -26,8 +26,8 @@ namespace MediaBrowser.Api.Sync private readonly ISyncManager _syncManager; private string _jobId; - public SyncJobWebSocketListener(ILogger logger, ISyncManager syncManager) - : base(logger) + public SyncJobWebSocketListener(ILogger logger, ISyncManager syncManager, ITimerFactory timerFactory) + : base(logger, timerFactory) { _syncManager = syncManager; _syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled; diff --git a/MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs b/MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs index 906a52209a..5f9d1ff0ee 100644 --- a/MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs +++ b/MediaBrowser.Api/Sync/SyncJobsWebSocketListener.cs @@ -1,9 +1,9 @@ -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Sync; +using MediaBrowser.Controller.Sync; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Sync; using System.Collections.Generic; using System.Threading.Tasks; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api.Sync { @@ -25,8 +25,8 @@ namespace MediaBrowser.Api.Sync private string _userId; private string _targetId; - public SyncJobsWebSocketListener(ILogger logger, ISyncManager syncManager) - : base(logger) + public SyncJobsWebSocketListener(ILogger logger, ISyncManager syncManager, ITimerFactory timerFactory) + : base(logger, timerFactory) { _syncManager = syncManager; _syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled; diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs index aaf9a33479..c641695dd8 100644 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs @@ -1,9 +1,9 @@ -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Activity; +using MediaBrowser.Model.Activity; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using System.Collections.Generic; using System.Threading.Tasks; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api.System { @@ -26,8 +26,7 @@ namespace MediaBrowser.Api.System /// </summary> private readonly IActivityManager _activityManager; - public ActivityLogWebSocketListener(ILogger logger, IActivityManager activityManager) - : base(logger) + public ActivityLogWebSocketListener(ILogger logger, ITimerFactory timerFactory, IActivityManager activityManager) : base(logger, timerFactory) { _activityManager = activityManager; _activityManager.EntryCreated += _activityManager_EntryCreated; diff --git a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs index a53bfac276..8d74cc66c0 100644 --- a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs +++ b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; using System.Threading.Tasks; +using MediaBrowser.Model.Threading; namespace MediaBrowser.Api.System { @@ -28,10 +29,8 @@ namespace MediaBrowser.Api.System /// <summary> /// Initializes a new instance of the <see cref="SystemInfoWebSocketListener" /> class. /// </summary> - /// <param name="logger">The logger.</param> - /// <param name="appHost">The app host.</param> - public SystemInfoWebSocketListener(ILogger logger, IServerApplicationHost appHost) - : base(logger) + public SystemInfoWebSocketListener(ILogger logger, IServerApplicationHost appHost, ITimerFactory timerFactory) + : base(logger, timerFactory) { _appHost = appHost; } diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index d67c1b47f4..bdae670e15 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -126,7 +126,7 @@ namespace MediaBrowser.Api.System .Where(i => string.Equals(i.Extension, ".txt", StringComparison.OrdinalIgnoreCase)) .ToList(); } - catch (DirectoryNotFoundException) + catch (IOException) { files = new List<FileSystemMetadata>(); } diff --git a/MediaBrowser.Api/project.json b/MediaBrowser.Api/project.json new file mode 100644 index 0000000000..fbbe9eaf32 --- /dev/null +++ b/MediaBrowser.Api/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 |
