diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 90a6b368d1..a2ed1d7722 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Plugins; +using System.IO; +using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; @@ -187,37 +188,11 @@ namespace MediaBrowser.Api } } - /// - /// Called when [transcoding finished]. - /// - /// The path. - /// The type. - public void OnTranscodingFinished(string path, TranscodingJobType type) - { - lock (_activeTranscodingJobs) - { - var job = _activeTranscodingJobs.FirstOrDefault(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); - - if (job == null) - { - return; - } - - _activeTranscodingJobs.Remove(job); - - if (job.KillTimer != null) - { - job.KillTimer.Dispose(); - job.KillTimer = null; - } - } - } - /// /// Called when [transcode kill timer stopped]. /// /// The state. - private void OnTranscodeKillTimerStopped(object state) + private async void OnTranscodeKillTimerStopped(object state) { var job = (TranscodingJob)state; @@ -253,31 +228,110 @@ namespace MediaBrowser.Api Logger.ErrorException("Error determining if ffmpeg process has exited for {0}", ex, job.Path); } - if (hasExited) + if (!hasExited) { - return; + try + { + Logger.Info("Killing ffmpeg process for {0}", job.Path); + + process.Kill(); + + // Need to wait because killing is asynchronous + process.WaitForExit(5000); + } + catch (Win32Exception ex) + { + Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } + catch (InvalidOperationException ex) + { + Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } + catch (NotSupportedException ex) + { + Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } } + // Determine if it exited successfully + var hasExitedSuccessfully = false; + try { - Logger.Info("Killing ffmpeg process for {0}", job.Path); - - process.Kill(); + hasExitedSuccessfully = process.ExitCode == 0; } - catch (Win32Exception ex) + catch (InvalidOperationException) { - Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } - catch (InvalidOperationException ex) + catch (NotSupportedException) { - Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + } - catch (NotSupportedException ex) + + // Dispose the process + process.Dispose(); + + // If it didn't complete successfully cleanup the partial files + if (!hasExitedSuccessfully) { - Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path); + Logger.Info("Deleting partial stream file(s) {0}", job.Path); + + await Task.Delay(1000).ConfigureAwait(false); + + try + { + if (job.Type == TranscodingJobType.Progressive) + { + DeleteProgressivePartialStreamFiles(job.Path); + } + else + { + DeleteHlsPartialStreamFiles(job.Path); + } + } + catch (IOException ex) + { + Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, job.Path); + } } } + /// + /// Deletes the progressive partial stream files. + /// + /// The output file path. + private void DeleteProgressivePartialStreamFiles(string outputFilePath) + { + File.Delete(outputFilePath); + } + + /// + /// Deletes the HLS partial stream files. + /// + /// The output file path. + private void DeleteHlsPartialStreamFiles(string outputFilePath) + { + var directory = Path.GetDirectoryName(outputFilePath); + var name = Path.GetFileNameWithoutExtension(outputFilePath); + + var filesToDelete = Directory.EnumerateFiles(directory) + .Where(f => f.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1) + .ToList(); + + foreach (var file in filesToDelete) + { + try + { + Logger.Info("Deleting HLS file {0}", file); + File.Delete(file); + } + catch (IOException ex) + { + Logger.ErrorException("Error deleting HLS file {0}", ex, file); + } + } + } } /// diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index e119b940fe..4886af9163 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -674,7 +674,7 @@ namespace MediaBrowser.Api.Playback /// /// The process. /// The state. - protected async void OnFfMpegProcessExited(Process process, StreamState state) + protected void OnFfMpegProcessExited(Process process, StreamState state) { if (state.IsoMount != null) { @@ -686,49 +686,16 @@ namespace MediaBrowser.Api.Playback state.LogFileStream.Dispose(); - int? exitCode = null; - try { - exitCode = process.ExitCode; - Logger.Info("FFMpeg exited with code {0} for {1}", exitCode.Value, outputFilePath); + Logger.Info("FFMpeg exited with code {0} for {1}", process.ExitCode, outputFilePath); } catch { Logger.Info("FFMpeg exited with an error for {0}", outputFilePath); } - - process.Dispose(); - - ApiEntryPoint.Instance.OnTranscodingFinished(outputFilePath, TranscodingJobType); - - if (!exitCode.HasValue || exitCode.Value != 0) - { - Logger.Info("Deleting partial stream file(s) {0}", outputFilePath); - - await Task.Delay(1000).ConfigureAwait(false); - - try - { - DeletePartialStreamFiles(outputFilePath); - } - catch (IOException ex) - { - Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, outputFilePath); - } - } - else - { - Logger.Info("FFMpeg completed and exited normally for {0}", outputFilePath); - } } - /// - /// Deletes the partial stream files. - /// - /// The output file path. - protected abstract void DeletePartialStreamFiles(string outputFilePath); - /// /// Gets the state. /// diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index a4fc6600a8..985288e6f4 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -207,32 +207,5 @@ namespace MediaBrowser.Api.Playback.Hls segmentOutputPath ).Trim(); } - - /// - /// Deletes the partial stream files. - /// - /// The output file path. - protected override void DeletePartialStreamFiles(string outputFilePath) - { - var directory = Path.GetDirectoryName(outputFilePath); - var name = Path.GetFileNameWithoutExtension(outputFilePath); - - var filesToDelete = Directory.EnumerateFiles(directory) - .Where(f => f.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1) - .ToList(); - - foreach (var file in filesToDelete) - { - try - { - Logger.Info("Deleting HLS file {0}", file); - File.Delete(file); - } - catch (IOException ex) - { - Logger.ErrorException("Error deleting HLS file {0}", ex, file); - } - } - } } } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index ab1fb4f903..cd8423c3dc 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -357,14 +357,5 @@ namespace MediaBrowser.Api.Playback.Progressive return result; } - - /// - /// Deletes the partial stream files. - /// - /// The output file path. - protected override void DeletePartialStreamFiles(string outputFilePath) - { - File.Delete(outputFilePath); - } } }