浏览代码

Merge pull request #2563 from MediaBrowser/dev

Dev
Luke 8 年之前
父节点
当前提交
26c1a8c017

+ 11 - 12
Emby.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1015,29 +1015,28 @@ namespace Emby.Server.Implementations.LiveTv
                 }
             }
 
-            IEnumerable<LiveTvProgram> programs = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>();
+            var programList = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>().ToList();
+            var totalCount = programList.Count;
 
-            var programList = programs.ToList();
+            IOrderedEnumerable<LiveTvProgram> orderedPrograms = programList.OrderBy(i => i.StartDate.Date);
 
-            var factorChannelWatchCount = (query.IsAiring ?? false) || (query.IsKids ?? false) || (query.IsSports ?? false) || (query.IsMovie ?? false) || (query.IsNews ?? false) || (query.IsSeries ?? false);
+            if (query.IsAiring ?? false)
+            {
+                orderedPrograms = orderedPrograms
+                    .ThenByDescending(i => GetRecommendationScore(i, user.Id, true));
+            }
 
-            programs = programList.OrderBy(i => i.StartDate.Date)
-                .ThenByDescending(i => GetRecommendationScore(i, user.Id, factorChannelWatchCount))
-                .ThenBy(i => i.StartDate);
+            IEnumerable<LiveTvProgram> programs = orderedPrograms;
 
             if (query.Limit.HasValue)
             {
                 programs = programs.Take(query.Limit.Value);
             }
 
-            programList = programs.ToList();
-
-            var returnArray = programList.ToArray();
-
             var result = new QueryResult<LiveTvProgram>
             {
-                Items = returnArray,
-                TotalRecordCount = returnArray.Length
+                Items = programs.ToArray(),
+                TotalRecordCount = totalCount
             };
 
             return result;

+ 31 - 12
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -164,12 +164,14 @@ namespace MediaBrowser.Api.Playback.Hls
             if (FileSystem.FileExists(segmentPath))
             {
                 job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
-                return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false);
+                return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, requestedIndex, job, cancellationToken).ConfigureAwait(false);
             }
 
             var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(playlistPath);
             await transcodingLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
             var released = false;
+            var startTranscoding = false;
+
             try
             {
                 if (FileSystem.FileExists(segmentPath))
@@ -177,12 +179,10 @@ namespace MediaBrowser.Api.Playback.Hls
                     job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
                     transcodingLock.Release();
                     released = true;
-                    return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false);
+                    return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, requestedIndex, job, cancellationToken).ConfigureAwait(false);
                 }
                 else
                 {
-                    var startTranscoding = false;
-
                     var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath, segmentExtension);
                     var segmentGapRequiringTranscodingChange = 24 / state.SegmentLength;
 
@@ -251,7 +251,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
             Logger.Info("returning {0}", segmentPath);
             job = job ?? ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
-            return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false);
+            return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, requestedIndex, job, cancellationToken).ConfigureAwait(false);
         }
 
         private const int BufferSize = 81920;
@@ -422,18 +422,33 @@ namespace MediaBrowser.Api.Playback.Hls
             return Path.Combine(folder, filename + index.ToString(UsCulture) + GetSegmentFileExtension(state.Request));
         }
 
-        private async Task<object> GetSegmentResult(StreamState state, string playlistPath,
+        private async Task<object> GetSegmentResult(StreamState state, 
+            string playlistPath,
             string segmentPath,
+            string segmentExtension,
             int segmentIndex,
             TranscodingJob transcodingJob,
             CancellationToken cancellationToken)
         {
+            var segmentFileExists = FileSystem.FileExists(segmentPath);
+
             // If all transcoding has completed, just return immediately
-            if (transcodingJob != null && transcodingJob.HasExited && FileSystem.FileExists(segmentPath))
+            if (transcodingJob != null && transcodingJob.HasExited && segmentFileExists)
             {
                 return await GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob).ConfigureAwait(false);
             }
 
+            if (segmentFileExists)
+            {
+                var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath, segmentExtension);
+
+                // If requested segment is less than transcoding position, we can't transcode backwards, so assume it's ready
+                if (segmentIndex < currentTranscodingIndex)
+                {
+                    return await GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob).ConfigureAwait(false);
+                }
+            }
+
             var segmentFilename = Path.GetFileName(segmentPath);
 
             while (!cancellationToken.IsCancellationRequested)
@@ -449,7 +464,11 @@ namespace MediaBrowser.Api.Playback.Hls
                             // If it appears in the playlist, it's done
                             if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1)
                             {
-                                if (FileSystem.FileExists(segmentPath))
+                                if (!segmentFileExists)
+                                {
+                                    segmentFileExists = FileSystem.FileExists(segmentPath);
+                                }
+                                if (segmentFileExists)
                                 {
                                     return await GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob).ConfigureAwait(false);
                                 }
@@ -536,12 +555,12 @@ namespace MediaBrowser.Api.Playback.Hls
 
             var subtitleGroup = subtitleStreams.Count > 0 &&
                 request is GetMasterHlsVideoPlaylist &&
-                (state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Hls || state.VideoRequest.EnableSubtitlesInManifest) ?
+                (state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Hls || state.VideoRequest.EnableSubtitlesInManifest) ?
                 "subs" :
                 null;
 
             // If we're burning in subtitles then don't add additional subs to the manifest
-            if (state.SubtitleStream != null && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode)
+            if (state.SubtitleStream != null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
             {
                 subtitleGroup = null;
             }
@@ -583,7 +602,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
         private void AddSubtitles(StreamState state, IEnumerable<MediaStream> subtitles, StringBuilder builder)
         {
-            var selectedIndex = state.SubtitleStream == null || state.VideoRequest.SubtitleMethod != SubtitleDeliveryMethod.Hls ? (int?)null : state.SubtitleStream.Index;
+            var selectedIndex = state.SubtitleStream == null || state.SubtitleDeliveryMethod != SubtitleDeliveryMethod.Hls ? (int?)null : state.SubtitleStream.Index;
 
             foreach (var stream in subtitles)
             {
@@ -843,7 +862,7 @@ namespace MediaBrowser.Api.Playback.Hls
                 var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
                     state.SegmentLength.ToString(UsCulture));
 
-                var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
+                var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
 
                 var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
 

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

@@ -96,7 +96,7 @@ namespace MediaBrowser.Api.Playback.Hls
             var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
                 state.SegmentLength.ToString(UsCulture));
 
-            var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
+            var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
 
             var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
             args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultH264Preset()) + keyFrameArg;

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

@@ -37,7 +37,6 @@ namespace MediaBrowser.Api.Playback
 
         public string Params { get; set; }
         public string PlaySessionId { get; set; }
-        public string LiveStreamId { get; set; }
         public string Tag { get; set; }
         public string SegmentContainer { get; set; }
 

+ 24 - 17
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -377,7 +377,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
             var arg = string.Format("-i {0}", GetInputPathArgument(state));
 
-            if (state.SubtitleStream != null && request.SubtitleMethod == SubtitleDeliveryMethod.Encode)
+            if (state.SubtitleStream != null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
             {
                 if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
                 {
@@ -410,7 +410,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             {
                 if (GetVideoEncoder(state, encodingOptions).IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1)
                 {
-                    var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && request.SubtitleMethod == SubtitleDeliveryMethod.Encode;
+                    var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
                     var hwOutputFormat = "vaapi";
 
                     if (hasGraphicalSubs)
@@ -782,7 +782,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             // Can't stream copy if we're burning in subtitles
             if (request.SubtitleStreamIndex.HasValue)
             {
-                if (request.SubtitleMethod == SubtitleDeliveryMethod.Encode)
+                if (state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
                 {
                     return false;
                 }
@@ -1042,7 +1042,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
             var pts = string.Empty;
 
-            if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.BaseRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode && !state.CopyTimestamps)
+            if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode && !state.CopyTimestamps)
             {
                 var seconds = TimeSpan.FromTicks(state.StartTimeTicks ?? 0).TotalSeconds;
 
@@ -1205,7 +1205,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 args += " -map -0:a";
             }
 
-            var subtitleMethod = state.BaseRequest.SubtitleMethod;
+            var subtitleMethod = state.SubtitleDeliveryMethod;
             if (state.SubtitleStream == null || subtitleMethod == SubtitleDeliveryMethod.Hls)
             {
                 args += " -map -0:s";
@@ -1421,7 +1421,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
             var output = string.Empty;
 
-            if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && request.SubtitleMethod == SubtitleDeliveryMethod.Encode)
+            if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
             {
                 var subParam = GetTextSubtitleParam(state);
 
@@ -1696,6 +1696,8 @@ namespace MediaBrowser.Controller.MediaEncoding
                 }
 
                 EnforceResolutionLimit(state);
+
+                NormalizeSubtitleEmbed(state);
             }
             else
             {
@@ -1705,6 +1707,21 @@ namespace MediaBrowser.Controller.MediaEncoding
             state.MediaSource = mediaSource;
         }
 
+        private void NormalizeSubtitleEmbed(EncodingJobInfo state)
+        {
+            if (state.SubtitleStream == null || state.SubtitleDeliveryMethod != SubtitleDeliveryMethod.Embed)
+            {
+                return ;
+            }
+
+            // This is tricky to remux in, after converting to dvdsub it's not positioned correctly
+            // Therefore, let's just burn it in
+            if (string.Equals(state.SubtitleStream.Codec, "DVBSUB", StringComparison.OrdinalIgnoreCase))
+            {
+                state.SubtitleDeliveryMethod = SubtitleDeliveryMethod.Encode;
+            }
+        }
+
         /// <summary>
         /// Gets the name of the output video codec
         /// </summary>
@@ -1810,16 +1827,6 @@ namespace MediaBrowser.Controller.MediaEncoding
                 codec = format;
             }
 
-            // Muxing in dvbsub via either copy or -codec dvbsub does not seem to work
-            // It doesn't throw any errors but vlc on android will not render them
-            // They will need to be converted to an alternative format
-            // TODO: This is incorrectly assuming that dvdsub will be supported by the player
-            // The api will need to be expanded to accomodate this.
-            if (string.Equals(state.SubtitleStream.Codec, "DVBSUB", StringComparison.OrdinalIgnoreCase))
-            {
-                codec = "dvdsub";
-            }
-
             var args = " -codec:s:0 " + codec;
 
             args += " -disposition:s:0 default";
@@ -1894,7 +1901,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
             args += keyFrameArg;
 
-            var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.BaseRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
+            var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
 
             var hasCopyTs = false;
             // Add resolution params, if specified

+ 1 - 0
MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs

@@ -192,6 +192,7 @@ namespace MediaBrowser.Controller.MediaEncoding
         public int? TranscodingMaxAudioChannels { get; set; }
         public int? CpuCoreLimit { get; set; }
         public string OutputContainer { get; set; }
+        public string LiveStreamId { get; set; }
 
         /// <summary>
         /// Gets or sets the video codec.

+ 1 - 1
MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs

@@ -350,7 +350,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false);
             }
 
-            if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.LiveStreamId))
+            if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.Options.LiveStreamId))
             {
                 var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest
                 {

+ 1 - 2
MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs

@@ -38,7 +38,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
         public bool EstimateContentLength { get; set; }
         public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
         public long? EncodingDurationTicks { get; set; }
-        public string LiveStreamId { get; set; }
 
         public string ItemType { get; set; }
 
@@ -94,7 +93,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
         private async void DisposeLiveStream()
         {
-            if (MediaSource.RequiresClosing)
+            if (MediaSource.RequiresClosing && string.IsNullOrWhiteSpace(Options.LiveStreamId) && !string.IsNullOrWhiteSpace(MediaSource.LiveStreamId))
             {
                 try
                 {

+ 1 - 1
SharedVersion.cs

@@ -1,3 +1,3 @@
 using System.Reflection;
 
-[assembly: AssemblyVersion("3.2.10.4")]
+[assembly: AssemblyVersion("3.2.10.5")]