diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 1ce7d2db3..f6872acd2 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -864,7 +864,7 @@ namespace MediaBrowser.Api.Playback /// /// The process. /// The state. - protected void OnFfMpegProcessExited(Process process, StreamState state) + protected async void OnFfMpegProcessExited(Process process, StreamState state) { if (state.IsoMount != null) { @@ -889,6 +889,18 @@ namespace MediaBrowser.Api.Playback { Logger.Info("FFMpeg exited with an error for {0}", outputFilePath); } + + if (!string.IsNullOrEmpty(state.LiveTvStreamId)) + { + try + { + await LiveTvManager.CloseLiveStream(state.LiveTvStreamId, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.ErrorException("Error closing live tv stream", ex); + } + } } /// @@ -936,6 +948,8 @@ namespace MediaBrowser.Api.Playback { var streamInfo = await LiveTvManager.GetRecordingStream(request.Id, cancellationToken).ConfigureAwait(false); + state.LiveTvStreamId = streamInfo.Id; + if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path)) { state.MediaPath = streamInfo.Path; @@ -961,6 +975,8 @@ namespace MediaBrowser.Api.Playback var streamInfo = await LiveTvManager.GetChannelStream(request.Id, cancellationToken).ConfigureAwait(false); + state.LiveTvStreamId = streamInfo.Id; + if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path)) { state.MediaPath = streamInfo.Path; diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index f705b5e33..bf584c385 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -52,5 +52,7 @@ namespace MediaBrowser.Api.Playback public bool SendInputOverStandardInput { get; set; } public CancellationTokenSource StandardInputCancellationTokenSource { get; set; } + + public string LiveTvStreamId { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index b7acb0735..ceca14f5b 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -227,5 +227,13 @@ namespace MediaBrowser.Controller.LiveTv /// The cancellation token. /// Task{QueryResult{RecordingGroupDto}}. Task> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken); + + /// + /// Closes the live stream. + /// + /// The identifier. + /// The cancellation token. + /// Task. + Task CloseLiveStream(string id, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index d475517dc..733c9b6e5 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -122,6 +122,12 @@ namespace MediaBrowser.Model.System /// The wan address. public string WanAddress { get; set; } + /// + /// Gets or sets a value indicating whether this instance has update available. + /// + /// true if this instance has update available; otherwise, false. + public bool HasUpdateAvailable { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 96c424957..131c5c0fb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -945,5 +945,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv TotalRecordCount = groups.Count }; } + + public Task CloseLiveStream(string id, CancellationToken cancellationToken) + { + return ActiveService.CloseLiveStream(id, cancellationToken); + } } } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index c703cf18e..0e66f2caf 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -293,7 +293,7 @@ namespace MediaBrowser.ServerApplication await Task.WhenAll(itemsTask, displayPreferencesTask, userdataTask).ConfigureAwait(false); progress.Report(100); - await ((UserManager) UserManager).Initialize().ConfigureAwait(false); + await ((UserManager)UserManager).Initialize().ConfigureAwait(false); SetKernelProperties(); } @@ -628,7 +628,8 @@ namespace MediaBrowser.ServerApplication OperatingSystem = Environment.OSVersion.ToString(), CanSelfRestart = CanSelfRestart, CanSelfUpdate = CanSelfUpdate, - WanAddress = GetWanAddress() + WanAddress = GetWanAddress(), + HasUpdateAvailable = _hasUpdateAvailable }; } @@ -699,6 +700,7 @@ namespace MediaBrowser.ServerApplication } } + private bool _hasUpdateAvailable; /// /// Checks for update. /// @@ -712,6 +714,8 @@ namespace MediaBrowser.ServerApplication var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, Constants.MbServerPkgName, null, ApplicationVersion, ConfigurationManager.CommonConfiguration.SystemUpdateLevel); + _hasUpdateAvailable = version != null; + return version != null ? new CheckForUpdateResult { AvailableVersion = version.version, IsUpdateAvailable = version.version > ApplicationVersion, Package = version } : new CheckForUpdateResult { AvailableVersion = ApplicationVersion, IsUpdateAvailable = false }; } @@ -727,6 +731,8 @@ namespace MediaBrowser.ServerApplication { await InstallationManager.InstallPackage(package, progress, cancellationToken).ConfigureAwait(false); + _hasUpdateAvailable = false; + OnApplicationUpdated(package.version); }