From 4f7e8fee24ead08d114f41e9fd9c1c7b4dd55359 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 10 Apr 2015 10:01:16 -0400 Subject: [PATCH] improve ffmpeg cleanup --- MediaBrowser.Controller/Entities/BaseItem.cs | 8 +- .../Encoder/MediaEncoder.cs | 133 +++++++++++------- MediaBrowser.Model/Dto/BaseItemDto.cs | 1 + MediaBrowser.Model/Users/UserPolicy.cs | 3 + .../Connect/ConnectManager.cs | 2 +- .../Library/LibraryManager.cs | 2 +- .../Localization/JavaScript/javascript.json | 1 + .../Localization/Server/server.json | 8 +- README.md | 2 +- 9 files changed, 96 insertions(+), 64 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 27bd09ec7..f8384ea1c 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1161,12 +1161,10 @@ namespace MediaBrowser.Controller.Entities return true; } - var locations = user.RootFolder - .GetChildren(user, true) - .OfType() - .SelectMany(i => i.PhysicalLocations); + var folders = user.RootFolder.GetChildren(user, true).Select(i => i.Id).ToList(); + var itemCollectionFolders = LibraryManager.GetCollectionFolders(this).Select(i => i.Id).ToList(); - return locations.Any(l => FileSystem.ContainsSubPath(l, topParent.Path)); + return itemCollectionFolders.Any(folders.Contains); } /// diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index be636c0ba..7bcf60fd9 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; @@ -74,6 +75,8 @@ namespace MediaBrowser.MediaEncoding.Encoder protected readonly Func SubtitleEncoder; protected readonly Func MediaSourceManager; + private List _runningProcesses = new List(); + public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func subtitleEncoder, Func mediaSourceManager) { _logger = logger; @@ -192,7 +195,7 @@ namespace MediaBrowser.MediaEncoding.Encoder try { - process.Start(); + StartProcess(process); } catch (Exception ex) { @@ -375,7 +378,7 @@ namespace MediaBrowser.MediaEncoding.Encoder await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - process.Start(); + StartProcess(process); var memoryStream = new MemoryStream(); @@ -391,18 +394,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (!ranToCompletion) { - try - { - _logger.Info("Killing ffmpeg process"); - - process.StandardInput.WriteLine("q"); - - process.WaitForExit(1000); - } - catch (Exception ex) - { - _logger.ErrorException("Error killing process", ex); - } + StopProcess(process, 1000, false); } resourcePool.Release(); @@ -426,31 +418,6 @@ namespace MediaBrowser.MediaEncoding.Encoder return memoryStream; } - public Task EncodeImage(ImageEncodingOptions options, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - _videoImageResourcePool.Dispose(); - } - } - public string GetTimeParameter(long ticks) { var time = TimeSpan.FromTicks(ticks); @@ -519,7 +486,7 @@ namespace MediaBrowser.MediaEncoding.Encoder try { - process.Start(); + StartProcess(process); // Need to give ffmpeg enough time to make all the thumbnails, which could be a while, // but we still need to detect if the process hangs. @@ -543,18 +510,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (!ranToCompletion) { - try - { - _logger.Info("Killing ffmpeg process"); - - process.StandardInput.WriteLine("q"); - - process.WaitForExit(1000); - } - catch (Exception ex) - { - _logger.ErrorException("Error killing process", ex); - } + StopProcess(process, 1000, false); } } finally @@ -615,5 +571,78 @@ namespace MediaBrowser.MediaEncoding.Encoder return job.OutputFilePath; } + + private void StartProcess(Process process) + { + process.Start(); + + lock (_runningProcesses) + { + _runningProcesses.Add(process); + } + } + private void StopProcess(Process process, int waitTimeMs, bool enableForceKill) + { + try + { + _logger.Info("Killing ffmpeg process"); + + process.StandardInput.WriteLine("q"); + + if (!process.WaitForExit(1000)) + { + if (enableForceKill) + { + process.Kill(); + } + } + } + catch (Exception ex) + { + _logger.ErrorException("Error killing process", ex); + } + finally + { + lock (_runningProcesses) + { + _runningProcesses.Remove(process); + } + } + } + + private void StopProcesses() + { + List proceses; + lock (_runningProcesses) + { + proceses = _runningProcesses.ToList(); + } + + foreach (var process in proceses) + { + StopProcess(process, 500, true); + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + _videoImageResourcePool.Dispose(); + StopProcesses(); + } + } } } diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index c49a1f77e..d984fe89e 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -63,6 +63,7 @@ namespace MediaBrowser.Model.Dto public string PreferredMetadataCountryCode { get; set; } public string AwardSummary { get; set; } + public string ShareUrl { get; set; } public float? Metascore { get; set; } diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index d7c894587..05c1b9de5 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -62,6 +62,8 @@ namespace MediaBrowser.Model.Users public bool EnableAllFolders { get; set; } public int InvalidLoginAttemptCount { get; set; } + + public bool EnablePublicSharing { get; set; } public UserPolicy() { @@ -94,6 +96,7 @@ namespace MediaBrowser.Model.Users EnableAllDevices = true; EnableContentDownloading = true; + EnablePublicSharing = true; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index b1b6cd899..2d39f760e 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -517,7 +517,7 @@ namespace MediaBrowser.Server.Implementations.Connect if (!connectUser.IsActive) { - throw new ArgumentException("The Emby account has been disabled."); + throw new ArgumentException("The Emby account is not active. Please ensure the account has been activated by following the instructions within the email confirmation."); } connectUserId = connectUser.Id; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 2e28f1a94..02c16d0d4 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1513,7 +1513,7 @@ namespace MediaBrowser.Server.Implementations.Library return GetUserRootFolder().Children .OfType() - .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path)); + .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path, StringComparer.OrdinalIgnoreCase)); } public string GetContentType(BaseItem item) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 4c6689bc6..49ca737fe 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -40,6 +40,7 @@ "TitleLiveTV": "Live TV", "TitleSync": "Sync", "ButtonDonate": "Donate", + "HeaderMyMedia": "My Media", "TitleNotifications": "Notifications", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "MessageErrorLoadingSupporterInfo": "There was an error loading supporter information. Please try again later.", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index cb65b3a4d..a686cface 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -552,7 +552,7 @@ "LabelPublicHttpsPort": "Public https port number:", "LabelPublicHttpsPortHelp": "The public port number that should be mapped to the local https port.", "LabelEnableHttps": "Report https as external address", - "LabelEnableHttpsHelp": "If enabled, the server will report an https url to clients as it's external address. This may break clients that do not yet support https.", + "LabelEnableHttpsHelp": "If enabled, the server will report an https url to clients as it's external address.", "LabelHttpsPort": "Local https port number:", "LabelHttpsPortHelp": "The tcp port number that Emby's https server should bind to.", "LabelWebSocketPortNumber": "Web socket port number:", @@ -896,9 +896,9 @@ "LabelHomePageSection2": "Home page section 2:", "LabelHomePageSection3": "Home page section 3:", "LabelHomePageSection4": "Home page section 4:", - "OptionMyViewsButtons": "My views (buttons)", - "OptionMyViews": "My views", - "OptionMyViewsSmall": "My views (small)", + "OptionMyMediaButtons": "My media (buttons)", + "OptionMyMedia": "My media", + "OptionMyMediaSmall": "My media (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", diff --git a/README.md b/README.md index f024d1e2a..d5cdcf06f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ We have several client apps released and in production: - [iPad](https://itunes.apple.com/us/app/media-browser-client/id879475585 "iPad") - [iPhone](https://itunes.apple.com/us/app/media-browser-for-ios/id705058087?mt=8 "iPhone") - [Media Portal](http://www.team-mediaportal.com/ "Media Portal") -- [Roku](http://www.roku.com/channels/#!details/44191/media-browser-for-roku "Roku") +- [Roku](https://www.roku.com/channels#!details/44191/emby "Roku") - Windows 7/8 Desktop - Windows Media Center - [Windows Phone](http://www.windowsphone.com/s?appid=f4971ed9-f651-4bf6-84bb-94fd98613b86 "Windows Phone")