diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 1fc3dcd72..82f32efa2 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -635,6 +635,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV existingTimer.Status == RecordingStatus.Completed) { existingTimer.Status = RecordingStatus.New; + existingTimer.IsManual = true; _timerProvider.Update(existingTimer); return Task.FromResult(existingTimer.Id); } @@ -663,6 +664,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV RecordingHelper.CopyProgramInfoToTimerInfo(programInfo, timer); } + timer.IsManual = true; _timerProvider.Add(timer); return Task.FromResult(timer.Id); } @@ -758,6 +760,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV existingTimer.PostPaddingSeconds = updatedTimer.PostPaddingSeconds; existingTimer.IsPostPaddingRequired = updatedTimer.IsPostPaddingRequired; existingTimer.IsPrePaddingRequired = updatedTimer.IsPrePaddingRequired; + + _timerProvider.Update(existingTimer); } return Task.FromResult(true); @@ -2203,6 +2207,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private bool ShouldCancelTimerForSeriesTimer(SeriesTimerInfo seriesTimer, TimerInfo timer) { + if (timer.IsManual) + { + return false; + } + if (!seriesTimer.RecordAnyTime) { if (Math.Abs(seriesTimer.StartDate.TimeOfDay.Ticks - timer.StartDate.TimeOfDay.Ticks) >= TimeSpan.FromMinutes(5).Ticks) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index a20fb67b2..8051b7848 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -954,8 +954,11 @@ namespace Emby.Server.Implementations.Session { var session = GetSessionToRemoteControl(sessionId); - var controllingSession = GetSession(controllingSessionId); - AssertCanControl(session, controllingSession); + if (!string.IsNullOrWhiteSpace(controllingSessionId)) + { + var controllingSession = GetSession(controllingSessionId); + AssertCanControl(session, controllingSession); + } return session.SessionController.SendGeneralCommand(command, cancellationToken); } @@ -1042,11 +1045,14 @@ namespace Emby.Server.Implementations.Session } } - var controllingSession = GetSession(controllingSessionId); - AssertCanControl(session, controllingSession); - if (controllingSession.UserId.HasValue) + if (!string.IsNullOrWhiteSpace(controllingSessionId)) { - command.ControllingUserId = controllingSession.UserId.Value.ToString("N"); + var controllingSession = GetSession(controllingSessionId); + AssertCanControl(session, controllingSession); + if (controllingSession.UserId.HasValue) + { + command.ControllingUserId = controllingSession.UserId.Value.ToString("N"); + } } await session.SessionController.SendPlayCommand(command, cancellationToken).ConfigureAwait(false); @@ -1136,11 +1142,14 @@ namespace Emby.Server.Implementations.Session { var session = GetSessionToRemoteControl(sessionId); - var controllingSession = GetSession(controllingSessionId); - AssertCanControl(session, controllingSession); - if (controllingSession.UserId.HasValue) + if (!string.IsNullOrWhiteSpace(controllingSessionId)) { - command.ControllingUserId = controllingSession.UserId.Value.ToString("N"); + var controllingSession = GetSession(controllingSessionId); + AssertCanControl(session, controllingSession); + if (controllingSession.UserId.HasValue) + { + command.ControllingUserId = controllingSession.UserId.Value.ToString("N"); + } } return session.SessionController.SendPlaystateCommand(command, cancellationToken); diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 80885271c..ed8449b83 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Api.Playback SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate, request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex, - request.SubtitleStreamIndex, request.MaxAudioChannels, request.PlaySessionId, request.UserId); + request.SubtitleStreamIndex, request.MaxAudioChannels, request.PlaySessionId, request.UserId, true, true, true); } else { @@ -169,7 +169,7 @@ namespace MediaBrowser.Api.Playback { var mediaSourceId = request.MediaSourceId; - SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId); + SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId, request.EnableDirectPlay, request.EnableDirectStream, request.EnableTranscoding); } return info; @@ -251,13 +251,16 @@ namespace MediaBrowser.Api.Playback int? audioStreamIndex, int? subtitleStreamIndex, int? maxAudioChannels, - string userId) + string userId, + bool enableDirectPlay, + bool enableDirectStream, + bool enableTranscoding) { var item = _libraryManager.GetItemById(itemId); foreach (var mediaSource in result.MediaSources) { - SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, maxAudioChannels, result.PlaySessionId, userId); + SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, maxAudioChannels, result.PlaySessionId, userId, enableDirectPlay, enableDirectStream, enableTranscoding); } SortMediaSources(result, maxBitrate); @@ -274,7 +277,10 @@ namespace MediaBrowser.Api.Playback int? subtitleStreamIndex, int? maxAudioChannels, string playSessionId, - string userId) + string userId, + bool enableDirectPlay, + bool enableDirectStream, + bool enableTranscoding) { var streamBuilder = new StreamBuilder(_mediaEncoder, Logger); @@ -297,6 +303,19 @@ namespace MediaBrowser.Api.Playback var user = _userManager.GetUserById(userId); + if (!enableDirectPlay) + { + mediaSource.SupportsDirectPlay = false; + } + if (!enableDirectStream) + { + mediaSource.SupportsDirectStream = false; + } + if (!enableTranscoding) + { + mediaSource.SupportsTranscoding = false; + } + if (mediaSource.SupportsDirectPlay) { var supportsDirectStream = mediaSource.SupportsDirectStream; diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs index ea12db7f9..0b94c85fa 100644 --- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs @@ -88,6 +88,8 @@ namespace MediaBrowser.Controller.LiveTv /// true if this instance is post padding required; otherwise, false. public bool IsPostPaddingRequired { get; set; } + public bool IsManual { get; set; } + /// /// Gets or sets the priority. /// diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs index fc4714be3..57a2254b0 100644 --- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs +++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs @@ -23,5 +23,16 @@ namespace MediaBrowser.Model.MediaInfo public string LiveStreamId { get; set; } public DeviceProfile DeviceProfile { get; set; } + + public bool EnableDirectPlay { get; set; } + public bool EnableDirectStream { get; set; } + public bool EnableTranscoding { get; set; } + + public PlaybackInfoRequest() + { + EnableDirectPlay = true; + EnableDirectStream = true; + EnableTranscoding = true; + } } } diff --git a/SharedVersion.cs b/SharedVersion.cs index ef83fd78c..7d9fa0d70 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.1.110")] +[assembly: AssemblyVersion("3.2.1.111")]