From 1bb287ccff73901b48fc089bca68f510ede9e5be Mon Sep 17 00:00:00 2001 From: nfnty Date: Thu, 21 Apr 2016 08:02:23 +0200 Subject: [PATCH 1/3] Dlna: Stop SSDP if disabled, Fixes #1578 --- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 49 ++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 37584f006f..5e8be1c4c7 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -39,6 +39,7 @@ namespace MediaBrowser.Dlna.Main private readonly IDeviceDiscovery _deviceDiscovery; private readonly List _registeredServerIds = new List(); + private bool _ssdpHandlerStarted; private bool _dlnaServerStarted; public DlnaEntryPoint(IServerConfigurationManager config, @@ -75,12 +76,22 @@ namespace MediaBrowser.Dlna.Main public void Run() { - StartSsdpHandler(); ReloadComponents(); + _config.ConfigurationUpdated += _config_ConfigurationUpdated; _config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated; } + private bool _lastEnableUPnP; + void _config_ConfigurationUpdated(object sender, EventArgs e) + { + if (_lastEnableUPnP != _config.Configuration.EnableUPnP) + { + ReloadComponents(); + } + _lastEnableUPnP = _config.Configuration.EnableUPnP; + } + void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) { if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase)) @@ -91,10 +102,24 @@ namespace MediaBrowser.Dlna.Main private void ReloadComponents() { - var isServerStarted = _dlnaServerStarted; - var options = _config.GetDlnaConfiguration(); + if (!options.EnableServer && !options.EnablePlayTo && !_config.Configuration.EnableUPnP) + { + if (_ssdpHandlerStarted) + { + StopSsdpHandler(); + } + return; + } + + if (!_ssdpHandlerStarted) + { + StartSsdpHandler(); + } + + var isServerStarted = _dlnaServerStarted; + if (options.EnableServer && !isServerStarted) { StartDlnaServer(); @@ -123,6 +148,8 @@ namespace MediaBrowser.Dlna.Main _ssdpHandler.Start(); ((DeviceDiscovery)_deviceDiscovery).Start(_ssdpHandler); + + _ssdpHandlerStarted = true; } catch (Exception ex) { @@ -130,6 +157,22 @@ namespace MediaBrowser.Dlna.Main } } + private void StopSsdpHandler() + { + try + { + ((DeviceDiscovery)_deviceDiscovery).Dispose(); + + _ssdpHandler.Dispose(); + + _ssdpHandlerStarted = false; + } + catch (Exception ex) + { + _logger.ErrorException("Error stopping ssdp handlers", ex); + } + } + public void StartDlnaServer() { try From 4d66f6dc6c1f0067479ce4845441ce713981c4fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 14 May 2016 12:06:01 -0400 Subject: [PATCH 2/3] auto-organize fixes --- .../Library/FileOrganizationService.cs | 2 - MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 45 +++++++++++++++---- .../FileOrganization/EpisodeFileOrganizer.cs | 5 +++ .../FileOrganizationService.cs | 10 ++--- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs index 849e9cf0db..0ed08a8607 100644 --- a/MediaBrowser.Api/Library/FileOrganizationService.cs +++ b/MediaBrowser.Api/Library/FileOrganizationService.cs @@ -119,8 +119,6 @@ namespace MediaBrowser.Api.Library { private readonly IFileOrganizationService _iFileOrganizationService; - /// The _json serializer - /// private readonly IJsonSerializer _jsonSerializer; public FileOrganizationService(IFileOrganizationService iFileOrganizationService, IJsonSerializer jsonSerializer) diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index dfec8baaae..a2e9cd60e7 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -85,14 +85,14 @@ namespace MediaBrowser.Dlna.Main _config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated; } - private bool _lastEnableUPnP; + private bool _lastEnableUpnP; void _config_ConfigurationUpdated(object sender, EventArgs e) { - if (_lastEnableUPnP != _config.Configuration.EnableUPnP) + if (_lastEnableUpnP != _config.Configuration.EnableUPnP) { ReloadComponents(); } - _lastEnableUPnP = _config.Configuration.EnableUPnP; + _lastEnableUpnP = _config.Configuration.EnableUPnP; } void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) @@ -111,7 +111,10 @@ namespace MediaBrowser.Dlna.Main { if (_ssdpHandlerStarted) { - StopSsdpHandler(); + // Sat/ip live tv depends on device discovery, as well as hd homerun detection + // In order to allow this to be disabled, we need a modular way of knowing if there are + // any parts of the system that are dependant on it + // DisposeSsdpHandler(); } return; } @@ -149,10 +152,9 @@ namespace MediaBrowser.Dlna.Main try { _ssdpHandler.Start(); - - ((DeviceDiscovery)_deviceDiscovery).Start(_ssdpHandler); - _ssdpHandlerStarted = true; + + StartDeviceDiscovery(); } catch (Exception ex) { @@ -160,8 +162,34 @@ namespace MediaBrowser.Dlna.Main } } - private void StopSsdpHandler() + private void StartDeviceDiscovery() { + try + { + ((DeviceDiscovery)_deviceDiscovery).Start(_ssdpHandler); + } + catch (Exception ex) + { + _logger.ErrorException("Error starting device discovery", ex); + } + } + + private void DisposeDeviceDiscovery() + { + try + { + ((DeviceDiscovery)_deviceDiscovery).Dispose(); + } + catch (Exception ex) + { + _logger.ErrorException("Error stopping device discovery", ex); + } + } + + private void DisposeSsdpHandler() + { + DisposeDeviceDiscovery(); + try { ((DeviceDiscovery)_deviceDiscovery).Dispose(); @@ -277,6 +305,7 @@ namespace MediaBrowser.Dlna.Main { DisposeDlnaServer(); DisposePlayToManager(); + DisposeSsdpHandler(); } public void DisposeDlnaServer() diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index f402a0a33b..83801b3e76 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -356,6 +356,11 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private void SaveSmartMatchString(string matchString, Series series, AutoOrganizeOptions options) { + if (string.IsNullOrEmpty(matchString) || matchString.Length < 3) + { + return; + } + SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.ItemName, series.Name, StringComparison.OrdinalIgnoreCase)); if (info == null) diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index 0e8a606122..60d515e120 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return _repo.Delete(resultId); } - private AutoOrganizeOptions GetAutoOrganizeptions() + private AutoOrganizeOptions GetAutoOrganizeOptions() { return _config.GetAutoOrganizeOptions(); } @@ -112,7 +112,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); - await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeptions(), true, CancellationToken.None) + await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeOptions(), true, CancellationToken.None) .ConfigureAwait(false); } @@ -126,7 +126,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); - await organizer.OrganizeWithCorrection(request, GetAutoOrganizeptions(), CancellationToken.None).ConfigureAwait(false); + await organizer.OrganizeWithCorrection(request, GetAutoOrganizeOptions(), CancellationToken.None).ConfigureAwait(false); } public QueryResult GetSmartMatchInfos(FileOrganizationResultQuery query) @@ -136,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization throw new ArgumentNullException("query"); } - var options = GetAutoOrganizeptions(); + var options = GetAutoOrganizeOptions(); var items = options.SmartMatchInfos.Skip(query.StartIndex ?? 0).Take(query.Limit ?? Int32.MaxValue).ToArray(); @@ -159,7 +159,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization throw new ArgumentNullException("matchString"); } - var options = GetAutoOrganizeptions(); + var options = GetAutoOrganizeOptions(); SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.ItemName, itemName)); From ff980dc42c4ebc31151a3dd4bc4d8dac738fd801 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 14 May 2016 14:02:06 -0400 Subject: [PATCH 3/3] add DisplayTitle to media streams --- .../Playback/BaseStreamingService.cs | 2 +- .../Encoder/BaseEncoder.cs | 2 +- .../Probing/ProbeResultNormalizer.cs | 16 ++++ MediaBrowser.Model/Entities/MediaStream.cs | 89 ++++++++++++++++++- .../Persistence/MediaStreamColumns.cs | 32 +++++++ .../Persistence/SqliteItemRepository.cs | 11 ++- 6 files changed, 147 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 792e468429..0f58a9db82 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -460,7 +460,7 @@ namespace MediaBrowser.Api.Playback // Boost volume to 200% when downsampling from 6ch to 2ch if (channels.HasValue && channels.Value <= 2) { - if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5) + if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5 && !ApiEntryPoint.Instance.GetEncodingOptions().DownMixAudioBoost.Equals(1)) { volParam = ",volume=" + ApiEntryPoint.Instance.GetEncodingOptions().DownMixAudioBoost.ToString(UsCulture); } diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 0ea48fab62..d551d5c8c0 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -1008,7 +1008,7 @@ namespace MediaBrowser.MediaEncoding.Encoder // Boost volume to 200% when downsampling from 6ch to 2ch if (channels.HasValue && channels.Value <= 2) { - if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5) + if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5 && !GetEncodingOptions().DownMixAudioBoost.Equals(1)) { volParam = ",volume=" + GetEncodingOptions().DownMixAudioBoost.ToString(UsCulture); } diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index c7c001cee7..1a95bdf9d7 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -432,6 +432,7 @@ namespace MediaBrowser.MediaEncoding.Probing { stream.Language = GetDictionaryValue(streamInfo.tags, "language"); stream.Comment = GetDictionaryValue(streamInfo.tags, "comment"); + stream.Title = GetDictionaryValue(streamInfo.tags, "title"); } if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase)) @@ -540,9 +541,24 @@ namespace MediaBrowser.MediaEncoding.Probing stream.IsForced = string.Equals(isForced, "1", StringComparison.OrdinalIgnoreCase); } + NormalizeStreamTitle(stream); + return stream; } + private void NormalizeStreamTitle(MediaStream stream) + { + if (string.Equals(stream.Title, "sdh", StringComparison.OrdinalIgnoreCase)) + { + stream.Title = null; + } + + if (stream.Type == MediaStreamType.EmbeddedImage) + { + stream.Title = null; + } + } + /// /// Gets a string from an FFProbeResult tags dictionary /// diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 25252956b2..9b814c5ccc 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Model.Dlna; +using System; +using System.Collections.Generic; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Extensions; using System.Diagnostics; @@ -34,6 +36,91 @@ namespace MediaBrowser.Model.Entities /// The comment. public string Comment { get; set; } + public string Title { get; set; } + + public string DisplayTitle + { + get + { + if (!string.IsNullOrEmpty(Title)) + { + return Title; + } + + if (Type == MediaStreamType.Audio) + { + List attributes = new List(); + + if (!string.IsNullOrEmpty(Language)) + { + attributes.Add(Language); + } + if (!string.IsNullOrEmpty(Codec) && !StringHelper.EqualsIgnoreCase(Codec, "dca")) + { + attributes.Add(Codec); + } + if (!string.IsNullOrEmpty(Profile) && !StringHelper.EqualsIgnoreCase(Profile, "lc")) + { + attributes.Add(Profile); + } + + if (Channels.HasValue) + { + attributes.Add(StringHelper.ToStringCultureInvariant(Channels.Value) + " ch"); + } + + string name = string.Join(" ", attributes.ToArray()); + + if (IsDefault) + { + name += " (D)"; + } + + return name; + } + + if (Type == MediaStreamType.Subtitle) + { + List attributes = new List(); + + if (!string.IsNullOrEmpty(Language)) + { + attributes.Add(Language); + } + if (!string.IsNullOrEmpty(Codec)) + { + attributes.Add(Codec); + } + + string name = string.Join(" ", attributes.ToArray()); + + if (IsDefault) + { + name += " (D)"; + } + + if (IsForced) + { + name += " (F)"; + } + + if (IsExternal) + { + name += " (EXT)"; + } + + return name; + } + + if (Type == MediaStreamType.Video) + { + + } + + return null; + } + } + public string NalLengthSize { get; set; } /// diff --git a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs b/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs index 76682c63b8..948e99cb82 100644 --- a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs +++ b/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs @@ -27,6 +27,7 @@ namespace MediaBrowser.Server.Implementations.Persistence AddCommentColumn(); AddNalColumn(); AddIsAvcColumn(); + AddTitleColumn(); } private void AddIsAvcColumn() @@ -60,6 +61,37 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.RunQueries(new[] { builder.ToString() }, _logger); } + private void AddTitleColumn() + { + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "PRAGMA table_info(mediastreams)"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + if (!reader.IsDBNull(1)) + { + var name = reader.GetString(1); + + if (string.Equals(name, "Title", StringComparison.OrdinalIgnoreCase)) + { + return; + } + } + } + } + } + + var builder = new StringBuilder(); + + builder.AppendLine("alter table mediastreams"); + builder.AppendLine("add column Title TEXT"); + + _connection.RunQueries(new[] { builder.ToString() }, _logger); + } + private void AddNalColumn() { using (var cmd = _connection.CreateCommand()) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 308ca90e0a..8f7119b4ab 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -120,7 +120,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); var createMediaStreamsTableCommand - = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, PRIMARY KEY (ItemId, StreamIndex))"; + = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; string[] queries = { @@ -386,7 +386,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "CodecTag", "Comment", "NalLengthSize", - "IsAvc" + "IsAvc", + "Title" }; /// @@ -3403,6 +3404,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveStreamCommand.GetParameter(index++).Value = stream.Comment; _saveStreamCommand.GetParameter(index++).Value = stream.NalLengthSize; _saveStreamCommand.GetParameter(index++).Value = stream.IsAVC; + _saveStreamCommand.GetParameter(index++).Value = stream.Title; _saveStreamCommand.Transaction = transaction; _saveStreamCommand.ExecuteNonQuery(); @@ -3571,6 +3573,11 @@ namespace MediaBrowser.Server.Implementations.Persistence item.IsAVC = reader.GetBoolean(28); } + if (!reader.IsDBNull(29)) + { + item.Title = reader.GetString(29); + } + return item; }