소스 검색

use stream id's to close streams

Luke Pulverenti 10 년 전
부모
커밋
ca0c0bdcb9

+ 22 - 5
MediaBrowser.Api/ApiEntryPoint.cs

@@ -132,6 +132,7 @@ namespace MediaBrowser.Api
         /// Called when [transcode beginning].
         /// </summary>
         /// <param name="path">The path.</param>
+        /// <param name="streamId">The stream identifier.</param>
         /// <param name="transcodingJobId">The transcoding job identifier.</param>
         /// <param name="type">The type.</param>
         /// <param name="process">The process.</param>
@@ -140,6 +141,7 @@ namespace MediaBrowser.Api
         /// <param name="cancellationTokenSource">The cancellation token source.</param>
         /// <returns>TranscodingJob.</returns>
         public TranscodingJob OnTranscodeBeginning(string path,
+            string streamId,
             string transcodingJobId,
             TranscodingJobType type,
             Process process,
@@ -157,7 +159,8 @@ namespace MediaBrowser.Api
                     ActiveRequestCount = 1,
                     DeviceId = deviceId,
                     CancellationTokenSource = cancellationTokenSource,
-                    Id = transcodingJobId
+                    Id = transcodingJobId,
+                    StreamId = streamId
                 };
 
                 _activeTranscodingJobs.Add(job);
@@ -316,17 +319,26 @@ namespace MediaBrowser.Api
         /// Kills the single transcoding job.
         /// </summary>
         /// <param name="deviceId">The device id.</param>
+        /// <param name="streamId">The stream identifier.</param>
         /// <param name="deleteFiles">The delete files.</param>
         /// <returns>Task.</returns>
-        /// <exception cref="ArgumentNullException">deviceId</exception>
-        internal void KillTranscodingJobs(string deviceId, Func<string, bool> deleteFiles)
+        internal void KillTranscodingJobs(string deviceId, string streamId, Func<string, bool> deleteFiles)
         {
             if (string.IsNullOrEmpty(deviceId))
             {
                 throw new ArgumentNullException("deviceId");
             }
 
-            KillTranscodingJobs(j => string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase), deleteFiles);
+            KillTranscodingJobs(j =>
+            {
+                if (string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase))
+                {
+                    return string.IsNullOrWhiteSpace(streamId) || string.Equals(streamId, j.StreamId, StringComparison.OrdinalIgnoreCase);
+                }
+
+                return false;
+
+            }, deleteFiles);
         }
 
         /// <summary>
@@ -335,7 +347,7 @@ namespace MediaBrowser.Api
         /// <param name="killJob">The kill job.</param>
         /// <param name="deleteFiles">The delete files.</param>
         /// <returns>Task.</returns>
-        internal void KillTranscodingJobs(Func<TranscodingJob, bool> killJob, Func<string, bool> deleteFiles)
+        private void KillTranscodingJobs(Func<TranscodingJob, bool> killJob, Func<string, bool> deleteFiles)
         {
             var jobs = new List<TranscodingJob>();
 
@@ -516,6 +528,11 @@ namespace MediaBrowser.Api
     /// </summary>
     public class TranscodingJob
     {
+        /// <summary>
+        /// Gets or sets the stream identifier.
+        /// </summary>
+        /// <value>The stream identifier.</value>
+        public string StreamId { get; set; }
         /// <summary>
         /// Gets or sets the path.
         /// </summary>

+ 3 - 2
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -134,7 +134,7 @@ namespace MediaBrowser.Api.Playback
             var data = GetCommandLineArguments("dummy\\dummy", "dummyTranscodingId", state, false);
 
             data += "-" + (state.Request.DeviceId ?? string.Empty);
-            data += "-" + (state.Request.ClientTime ?? string.Empty);
+            data += "-" + (state.Request.StreamId ?? state.Request.ClientTime ?? string.Empty);
 
             var dataHash = data.GetMD5().ToString("N");
 
@@ -1054,6 +1054,7 @@ namespace MediaBrowser.Api.Playback
             }
 
             var transcodingJob = ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath,
+                state.Request.StreamId ?? state.Request.ClientTime,
                 transcodingId,
                 TranscodingJobType,
                 process,
@@ -1523,7 +1524,7 @@ namespace MediaBrowser.Api.Playback
                 }
                 else if (i == 16)
                 {
-                    request.ClientTime = val;
+                    request.StreamId = val;
                 }
                 else if (i == 17)
                 {

+ 1 - 6
MediaBrowser.Api/Playback/Dash/MpegDashService.cs

@@ -162,7 +162,7 @@ namespace MediaBrowser.Api.Playback.Dash
                             // If the playlist doesn't already exist, startup ffmpeg
                             try
                             {
-                                KillTranscodingJobs(request.DeviceId, playlistPath);
+                                ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.StreamId, p => false);
 
                                 if (currentTranscodingIndex.HasValue)
                                 {
@@ -204,11 +204,6 @@ namespace MediaBrowser.Api.Playback.Dash
             return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job ?? ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType), cancellationToken).ConfigureAwait(false);
         }
 
-        private void KillTranscodingJobs(string deviceId, string playlistPath)
-        {
-            ApiEntryPoint.Instance.KillTranscodingJobs(j => j.Type == TranscodingJobType && string.Equals(j.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase), p => !string.Equals(p, playlistPath, StringComparison.OrdinalIgnoreCase));
-        }
-
         private long GetPositionTicks(StreamState state, int requestedIndex)
         {
             if (requestedIndex <= 0)

+ 1 - 1
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -136,7 +136,7 @@ namespace MediaBrowser.Api.Playback.Hls
                         // If the playlist doesn't already exist, startup ffmpeg
                         try
                         {
-                            ApiEntryPoint.Instance.KillTranscodingJobs(j => j.Type == TranscodingJobType && string.Equals(j.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase), p => !string.Equals(p, playlistPath, StringComparison.OrdinalIgnoreCase));
+                            ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.StreamId ?? request.ClientTime, p => false);
 
                             if (currentTranscodingIndex.HasValue)
                             {

+ 4 - 1
MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs

@@ -47,6 +47,9 @@ namespace MediaBrowser.Api.Playback.Hls
     {
         [ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
         public string DeviceId { get; set; }
+
+        [ApiMember(Name = "StreamId", Description = "The stream id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
+        public string StreamId { get; set; }
     }
 
     public class HlsSegmentService : BaseApiService
@@ -69,7 +72,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
         public void Delete(StopEncodingProcess request)
         {
-            ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, path => true);
+            ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.StreamId, path => true);
         }
 
         /// <summary>

+ 2 - 1
MediaBrowser.Api/Playback/MediaInfoService.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Library;
+using System;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dto;

+ 1 - 0
MediaBrowser.Api/Playback/StreamRequest.cs

@@ -71,6 +71,7 @@ namespace MediaBrowser.Api.Playback
 
         public string Params { get; set; }
         public string ClientTime { get; set; }
+        public string StreamId { get; set; }
 
         public string TranscodingJobId { get; set; }
     }

+ 55 - 29
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Common;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Channels;
@@ -24,7 +23,6 @@ using MediaBrowser.Model.Serialization;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -747,8 +745,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 programs = programs.Where(p => p.IsMovie == query.IsMovie.Value);
             }
 
-            var serviceName = ActiveService.Name;
-
             var programList = programs.ToList();
 
             var genres = programList.SelectMany(i => i.Genres)
@@ -757,7 +753,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
 
             programs = programList.OrderBy(i => i.HasImage(ImageType.Primary) ? 0 : 1)
-                .ThenByDescending(i => GetRecommendationScore(i, user.Id, serviceName, genres))
+                .ThenByDescending(i => GetRecommendationScore(i, user.Id, genres))
                 .ThenBy(i => i.StartDate);
 
             if (query.Limit.HasValue)
@@ -807,7 +803,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return result;
         }
 
-        private int GetRecommendationScore(LiveTvProgram program, Guid userId, string serviceName, Dictionary<string, Genre> genres)
+        private int GetRecommendationScore(LiveTvProgram program, Guid userId, Dictionary<string, Genre> genres)
         {
             var score = 0;
 
@@ -821,7 +817,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 score++;
             }
 
-            var internalChannelId = _tvDtoService.GetInternalChannelId(serviceName, program.ExternalChannelId);
+            var internalChannelId = _tvDtoService.GetInternalChannelId(program.ServiceName, program.ExternalChannelId);
             var channel = GetInternalChannel(internalChannelId);
 
             var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey());
@@ -879,11 +875,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         private async Task AddRecordingInfo(IEnumerable<ProgramInfoDto> programs, CancellationToken cancellationToken)
         {
-            var timers = await ActiveService.GetTimersAsync(cancellationToken).ConfigureAwait(false);
-            var timerList = timers.ToList();
+            var timers = new Dictionary<string, List<TimerInfo>>();
 
             foreach (var program in programs)
             {
+                List<TimerInfo> timerList;
+                if (!timers.TryGetValue(program.ServiceName, out timerList))
+                {
+                    var tempTimers = await GetService(program.ServiceName).GetTimersAsync(cancellationToken).ConfigureAwait(false);
+                    timers[program.ServiceName] = timerList = tempTimers.ToList();
+                }
+
                 var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, program.ExternalId, StringComparison.OrdinalIgnoreCase));
 
                 if (timer != null)
@@ -922,15 +924,43 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         private async Task RefreshChannelsInternal(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            // Avoid implicitly captured closure
-            var service = ActiveService;
+            var numComplete = 0;
+            double progressPerService = _services.Count == 0
+                ? 0
+                : 1 / _services.Count;
 
-            if (service == null)
+            foreach (var service in _services)
             {
-                progress.Report(100);
-                return;
+                cancellationToken.ThrowIfCancellationRequested();
+
+                try
+                {
+                    var innerProgress = new ActionableProgress<double>();
+                    innerProgress.RegisterAction(p => progress.Report(p * progressPerService));
+
+                    await RefreshChannelsInternal(service, innerProgress, cancellationToken).ConfigureAwait(false);
+                }
+                catch (OperationCanceledException)
+                {
+                    throw;
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("Error refreshing channels for service", ex);
+                }
+
+                numComplete++;
+                double percent = numComplete;
+                percent /= _services.Count;
+
+                progress.Report(100 * percent);
             }
 
+            progress.Report(100);
+        }
+
+        private async Task RefreshChannelsInternal(ILiveTvService service, IProgress<double> progress, CancellationToken cancellationToken)
+        {
             progress.Report(10);
 
             var allChannels = await GetChannels(service, cancellationToken).ConfigureAwait(false);
@@ -1192,16 +1222,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken)
         {
-            var service = ActiveService;
-
-            if (service == null)
-            {
-                return new QueryResult<RecordingInfoDto>
-                {
-                    Items = new RecordingInfoDto[] { }
-                };
-            }
-
             var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
 
             var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false);
@@ -1209,6 +1229,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             var returnArray = internalResult.Items.Cast<ILiveTvRecording>()
                 .Select(i =>
                 {
+                    var service = GetService(i);
+
                     var channel = string.IsNullOrEmpty(i.RecordingInfo.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, i.RecordingInfo.ChannelId));
                     return _tvDtoService.GetRecordingInfoDto(i, channel, service, user);
                 })
@@ -1413,8 +1435,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return program;
         }
 
-        private async Task<SeriesTimerInfo> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null)
+        private async Task<Tuple<SeriesTimerInfo,ILiveTvService>> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null)
         {
+            var service = program != null && !string.IsNullOrWhiteSpace(program.ServiceName) ?
+                GetService(program) :
+                _services.FirstOrDefault();
+
             ProgramInfo programInfo = null;
 
             if (program != null)
@@ -1448,18 +1474,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 };
             }
 
-            var info = await ActiveService.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
+            var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
 
             info.Id = null;
 
-            return info;
+            return new Tuple<SeriesTimerInfo, ILiveTvService>(info, service);
         }
 
         public async Task<SeriesTimerInfoDto> GetNewTimerDefaults(CancellationToken cancellationToken)
         {
             var info = await GetNewTimerDefaultsInternal(cancellationToken).ConfigureAwait(false);
 
-            var obj = _tvDtoService.GetSeriesTimerInfoDto(info, ActiveService, null);
+            var obj = _tvDtoService.GetSeriesTimerInfoDto(info.Item1, info.Item2, null);
 
             return obj;
         }
@@ -1470,7 +1496,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             var programDto = await GetProgram(programId, cancellationToken).ConfigureAwait(false);
 
             var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false);
-            var info = _tvDtoService.GetSeriesTimerInfoDto(defaults, ActiveService, null);
+            var info = _tvDtoService.GetSeriesTimerInfoDto(defaults.Item1, defaults.Item2, null);
 
             info.Days = new List<DayOfWeek>
             {