From 0ec38a9d40a015af87b19cf345e0dfb1e433b45d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 12 Mar 2015 21:55:22 -0400 Subject: [PATCH] adjust audio direct play checks --- .../Session/ISessionManager.cs | 6 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 131 ++++++++++-------- .../Manager/ProviderUtils.cs | 2 +- .../MediaInfo/FFProbeAudioInfo.cs | 13 +- .../HttpServer/Security/SessionContext.cs | 2 +- .../Session/SessionManager.cs | 24 +++- .../Session/SessionWebSocketListener.cs | 3 +- 7 files changed, 115 insertions(+), 66 deletions(-) diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 234a823460..bddc035e08 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -283,18 +283,20 @@ namespace MediaBrowser.Controller.Session /// Gets the session by authentication token. /// /// The token. + /// The device identifier. /// The remote endpoint. /// SessionInfo. - Task GetSessionByAuthenticationToken(string token, string remoteEndpoint); + Task GetSessionByAuthenticationToken(string token, string deviceId, string remoteEndpoint); /// /// Gets the session by authentication token. /// /// The information. + /// The device identifier. /// The remote endpoint. /// The application version. /// Task<SessionInfo>. - Task GetSessionByAuthenticationToken(AuthenticationInfo info, string remoteEndpoint, string appVersion); + Task GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion); /// /// Logouts the specified access token. diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 126b218e82..07c7ecd8bc 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -138,72 +138,60 @@ namespace MediaBrowser.Model.Dlna DeviceProfile = options.Profile }; - int? maxBitrateSetting = options.GetMaxBitrate(); + List directPlayMethods = GetAudioDirectPlayMethods(item, options); - MediaStream audioStream = item.DefaultAudioStream; - - // Honor the max bitrate setting - if (IsAudioEligibleForDirectPlay(item, maxBitrateSetting)) + if (directPlayMethods.Count > 0) { - DirectPlayProfile directPlay = null; - foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles) + MediaStream audioStream = item.DefaultAudioStream; + + string audioCodec = audioStream == null ? null : audioStream.Codec; + + // Make sure audio codec profiles are satisfied + if (!string.IsNullOrEmpty(audioCodec)) { - if (i.Type == playlistItem.MediaType && IsAudioDirectPlaySupported(i, item, audioStream)) + ConditionProcessor conditionProcessor = new ConditionProcessor(); + + List conditions = new List(); + foreach (CodecProfile i in options.Profile.CodecProfiles) { - directPlay = i; - break; + if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec)) + { + foreach (ProfileCondition c in i.Conditions) + { + conditions.Add(c); + } + } } - } - if (directPlay != null) - { - string audioCodec = audioStream == null ? null : audioStream.Codec; + int? audioChannels = audioStream.Channels; + int? audioBitrate = audioStream.BitRate; - // Make sure audio codec profiles are satisfied - if (!string.IsNullOrEmpty(audioCodec)) + bool all = true; + foreach (ProfileCondition c in conditions) { - ConditionProcessor conditionProcessor = new ConditionProcessor(); - - List conditions = new List(); - foreach (CodecProfile i in options.Profile.CodecProfiles) + if (!conditionProcessor.IsAudioConditionSatisfied(c, audioChannels, audioBitrate)) { - if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec)) - { - foreach (ProfileCondition c in i.Conditions) - { - conditions.Add(c); - } - } + all = false; + break; + } + } + + if (all) + { + if (item.Protocol == MediaProtocol.File && + directPlayMethods.Contains(PlayMethod.DirectPlay) && + _localPlayer.CanAccessFile(item.Path)) + { + playlistItem.PlayMethod = PlayMethod.DirectPlay; + } + else if (directPlayMethods.Contains(PlayMethod.DirectStream)) + { + playlistItem.PlayMethod = PlayMethod.DirectStream; } - int? audioChannels = audioStream.Channels; - int? audioBitrate = audioStream.BitRate; + playlistItem.Container = item.Container; - bool all = true; - foreach (ProfileCondition c in conditions) - { - if (!conditionProcessor.IsAudioConditionSatisfied(c, audioChannels, audioBitrate)) - { - all = false; - break; - } - } - - if (all) - { - if (item.Protocol == MediaProtocol.File && _localPlayer.CanAccessFile(item.Path)) - { - playlistItem.PlayMethod = PlayMethod.DirectPlay; - } - else - { - playlistItem.PlayMethod = PlayMethod.DirectStream; - } - - playlistItem.Container = item.Container; - - return playlistItem; - } + return playlistItem; } } } @@ -272,6 +260,41 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } + private List GetAudioDirectPlayMethods(MediaSourceInfo item, AudioOptions options) + { + MediaStream audioStream = item.DefaultAudioStream; + + DirectPlayProfile directPlayProfile = null; + foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles) + { + if (i.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(i, item, audioStream)) + { + directPlayProfile = i; + break; + } + } + + List playMethods = new List(); + + if (directPlayProfile != null) + { + // While options takes the network and other factors into account. Only applies to direct stream + if (IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate())) + { + playMethods.Add(PlayMethod.DirectStream); + } + + // The profile describes what the device supports + // If device requirements are satisfied then allow both direct stream and direct play + if (IsAudioEligibleForDirectPlay(item, options.Profile.MaxStaticBitrate)) + { + playMethods.Add(PlayMethod.DirectPlay); + } + } + + return playMethods; + } + private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options) { StreamInfo playlistItem = new StreamInfo diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index 155cd208f3..aa92cc2802 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -252,7 +252,7 @@ namespace MediaBrowser.Providers.Manager if (sourceHasAlbumArtist != null && targetHasAlbumArtist != null) { - if (replaceData || targetHasAlbumArtist.AlbumArtists.Count > 0) + if (replaceData || targetHasAlbumArtist.AlbumArtists.Count == 0) { targetHasAlbumArtist.AlbumArtists = sourceHasAlbumArtist.AlbumArtists; } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index 39f138c5bc..26d00d5444 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -210,7 +210,15 @@ namespace MediaBrowser.Providers.MediaInfo } } - var albumArtist = FFProbeHelpers.GetDictionaryValue(tags, "albumartist") ?? FFProbeHelpers.GetDictionaryValue(tags, "album artist") ?? FFProbeHelpers.GetDictionaryValue(tags, "album_artist"); + var albumArtist = FFProbeHelpers.GetDictionaryValue(tags, "albumartist"); + if (string.IsNullOrWhiteSpace(albumArtist)) + { + albumArtist = FFProbeHelpers.GetDictionaryValue(tags, "album artist"); + } + if (string.IsNullOrWhiteSpace(albumArtist)) + { + albumArtist = FFProbeHelpers.GetDictionaryValue(tags, "album_artist"); + } if (string.IsNullOrWhiteSpace(albumArtist)) { @@ -277,8 +285,7 @@ namespace MediaBrowser.Providers.MediaInfo return value.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries) .Select(i => i.Trim()) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .FirstOrDefault(); + .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); } private readonly char[] _nameDelimiters = { '/', '|', ';', '\\' }; diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs index 0557f7528d..1bbe9893b8 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security if (!string.IsNullOrWhiteSpace(authorization.Token)) { var auth = GetTokenInfo(requestContext); - return _sessionManager.GetSessionByAuthenticationToken(auth, requestContext.RemoteIp, authorization.Version); + return _sessionManager.GetSessionByAuthenticationToken(auth, authorization.DeviceId, requestContext.RemoteIp, authorization.Version); } var session = _sessionManager.GetSession(authorization.DeviceId, authorization.Client, authorization.Version); diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 2e28862e9e..7c6ab2af64 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1639,7 +1639,7 @@ namespace MediaBrowser.Server.Implementations.Session string.Equals(i.Client, client)); } - public Task GetSessionByAuthenticationToken(AuthenticationInfo info, string remoteEndpoint, string appVersion) + public Task GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion) { if (info == null) { @@ -1654,10 +1654,26 @@ namespace MediaBrowser.Server.Implementations.Session ? "1" : appVersion; - return GetSessionInfo(info.AppName, appVersion, info.DeviceId, info.DeviceName, remoteEndpoint, user); + var deviceName = info.DeviceName; + + if (!string.IsNullOrWhiteSpace(deviceId)) + { + // Replace the info from the token with more recent info + var device = _deviceManager.GetDevice(deviceId); + if (device != null) + { + deviceName = device.Name; + } + } + else + { + deviceId = info.DeviceId; + } + + return GetSessionInfo(info.AppName, appVersion, deviceId, deviceName, remoteEndpoint, user); } - public Task GetSessionByAuthenticationToken(string token, string remoteEndpoint) + public Task GetSessionByAuthenticationToken(string token, string deviceId, string remoteEndpoint) { var result = _authRepo.Get(new AuthenticationInfoQuery { @@ -1676,7 +1692,7 @@ namespace MediaBrowser.Server.Implementations.Session return null; } - return GetSessionByAuthenticationToken(info, remoteEndpoint, null); + return GetSessionByAuthenticationToken(info, deviceId, remoteEndpoint, null); } public Task SendMessageToUserSessions(string userId, string name, T data, diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index 7cbff9768d..dda4c2b90f 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -103,7 +103,8 @@ namespace MediaBrowser.Server.Implementations.Session { return Task.FromResult(null); } - return _sessionManager.GetSessionByAuthenticationToken(token, remoteEndpoint); + var deviceId = queryString["deviceId"]; + return _sessionManager.GetSessionByAuthenticationToken(token, deviceId, remoteEndpoint); } public void Dispose()