Browse Source

Merge pull request #1649 from MediaBrowser/dev

Dev
Luke 9 years ago
parent
commit
fd72bdab5c

+ 4 - 4
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -288,11 +288,9 @@ namespace MediaBrowser.Api.Playback
         {
         {
             if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
             if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
             {
             {
-                // It's currently failing on live tv
-                if (state.RunTimeTicks.HasValue)
-                {
+                
                     return "h264_qsv";
                     return "h264_qsv";
-                }
+               
             }
             }
 
 
             return "libx264";
             return "libx264";
@@ -440,6 +438,8 @@ namespace MediaBrowser.Api.Playback
                             param += " -level " + state.VideoRequest.Level;
                             param += " -level " + state.VideoRequest.Level;
                             break;
                             break;
                     }
                     }
+
+                    return param;
                 }
                 }
                 else
                 else
                 {
                 {

+ 3 - 4
MediaBrowser.Api/Playback/Hls/VideoHlsService.cs

@@ -86,11 +86,10 @@ namespace MediaBrowser.Api.Playback.Hls
             // See if we can save come cpu cycles by avoiding encoding
             // See if we can save come cpu cycles by avoiding encoding
             if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
             if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
             {
             {
-                return state.VideoStream != null && IsH264(state.VideoStream) ?
-                    args + " -bsf:v h264_mp4toannexb" :
-                    args;
+                // if h264_mp4toannexb is ever added, do not use it for live tv
+                return args;
             }
             }
-            
+
             var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
             var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
                 state.SegmentLength.ToString(UsCulture));
                 state.SegmentLength.ToString(UsCulture));
 
 

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

@@ -227,7 +227,7 @@ namespace MediaBrowser.Api.Playback
                 SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId);
                 SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId);
             }
             }
 
 
-            SortMediaSources(result);
+            SortMediaSources(result, maxBitrate);
         }
         }
 
 
         private void SetDeviceSpecificData(BaseItem item,
         private void SetDeviceSpecificData(BaseItem item,
@@ -375,7 +375,7 @@ namespace MediaBrowser.Api.Playback
             }
             }
         }
         }
 
 
-        private void SortMediaSources(PlaybackInfoResponse result)
+        private void SortMediaSources(PlaybackInfoResponse result, int? maxBitrate)
         {
         {
             var originalList = result.MediaSources.ToList();
             var originalList = result.MediaSources.ToList();
 
 
@@ -409,6 +409,23 @@ namespace MediaBrowser.Api.Playback
                         return 1;
                         return 1;
                 }
                 }
 
 
+            }).ThenBy(i =>
+            {
+                if (maxBitrate.HasValue)
+                {
+                    if (i.Bitrate.HasValue)
+                    {
+                        if (i.Bitrate.Value <= maxBitrate.Value)
+                        {
+                            return 0;
+                        }
+
+                        return 2;
+                    }
+                }
+
+                return 1;
+
             }).ThenBy(originalList.IndexOf)
             }).ThenBy(originalList.IndexOf)
             .ToList();
             .ToList();
         }
         }

+ 18 - 0
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -1348,6 +1348,24 @@ namespace MediaBrowser.Controller.Entities
             return LocalizationManager.GetRatingLevel(rating);
             return LocalizationManager.GetRatingLevel(rating);
         }
         }
 
 
+        public List<string> GetInheritedTags()
+        {
+            var list = new List<string>();
+            list.AddRange(Tags);
+
+            foreach (var parent in GetParents())
+            {
+                list.AddRange(parent.Tags);
+            }
+
+            foreach (var parent in LibraryManager.GetCollectionFolders(this))
+            {
+                list.AddRange(parent.Tags);
+            }
+
+            return list.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
+        }
+
         private bool IsVisibleViaTags(User user)
         private bool IsVisibleViaTags(User user)
         {
         {
             var hasTags = this as IHasTags;
             var hasTags = this as IHasTags;

+ 3 - 1
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -33,6 +33,7 @@ namespace MediaBrowser.Controller.Entities
         public string[] IncludeItemTypes { get; set; }
         public string[] IncludeItemTypes { get; set; }
         public string[] ExcludeItemTypes { get; set; }
         public string[] ExcludeItemTypes { get; set; }
         public string[] ExcludeTags { get; set; }
         public string[] ExcludeTags { get; set; }
+        public string[] ExcludeInheritedTags { get; set; }
         public string[] Genres { get; set; }
         public string[] Genres { get; set; }
 
 
         public bool? IsMissing { get; set; }
         public bool? IsMissing { get; set; }
@@ -157,6 +158,7 @@ namespace MediaBrowser.Controller.Entities
             AncestorIds = new string[] { };
             AncestorIds = new string[] { };
             TopParentIds = new string[] { };
             TopParentIds = new string[] { };
             ExcludeTags = new string[] { };
             ExcludeTags = new string[] { };
+            ExcludeInheritedTags = new string[] { };
             LocationTypes = new LocationType[] { };
             LocationTypes = new LocationType[] { };
             ExcludeLocationTypes = new LocationType[] { };
             ExcludeLocationTypes = new LocationType[] { };
             PresetViews = new string[] { };
             PresetViews = new string[] { };
@@ -181,7 +183,7 @@ namespace MediaBrowser.Controller.Entities
                     BlockUnratedItems = policy.BlockUnratedItems;
                     BlockUnratedItems = policy.BlockUnratedItems;
                 }
                 }
 
 
-                ExcludeTags = policy.BlockedTags;
+                ExcludeInheritedTags = policy.BlockedTags;
 
 
                 User = user;
                 User = user;
             }
             }

+ 5 - 5
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna
                 stream.DeviceProfileId = options.Profile.Id;
                 stream.DeviceProfileId = options.Profile.Id;
             }
             }
 
 
-            return GetOptimalStream(streams);
+            return GetOptimalStream(streams, options.GetMaxBitrate());
         }
         }
 
 
         public StreamInfo BuildVideoItem(VideoOptions options)
         public StreamInfo BuildVideoItem(VideoOptions options)
@@ -88,12 +88,12 @@ namespace MediaBrowser.Model.Dlna
                 stream.DeviceProfileId = options.Profile.Id;
                 stream.DeviceProfileId = options.Profile.Id;
             }
             }
 
 
-            return GetOptimalStream(streams);
+            return GetOptimalStream(streams, options.GetMaxBitrate());
         }
         }
 
 
-        private StreamInfo GetOptimalStream(List<StreamInfo> streams)
+        private StreamInfo GetOptimalStream(List<StreamInfo> streams, int? maxBitrate)
         {
         {
-            streams = StreamInfoSorter.SortMediaSources(streams);
+            streams = StreamInfoSorter.SortMediaSources(streams, maxBitrate);
 
 
             foreach (StreamInfo stream in streams)
             foreach (StreamInfo stream in streams)
             {
             {
@@ -424,7 +424,7 @@ namespace MediaBrowser.Model.Dlna
                 playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
                 playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
                 playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
                 playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
 
 
-                // TODO: We should probably preserve the full list and sent it tp the server that way
+                // TODO: We should probably preserve the full list and sent it to the server that way
                 string[] supportedAudioCodecs = transcodingProfile.AudioCodec.Split(',');
                 string[] supportedAudioCodecs = transcodingProfile.AudioCodec.Split(',');
                 string inputAudioCodec = audioStream == null ? null : audioStream.Codec;
                 string inputAudioCodec = audioStream == null ? null : audioStream.Codec;
                 foreach (string supportedAudioCodec in supportedAudioCodecs)
                 foreach (string supportedAudioCodec in supportedAudioCodecs)

+ 18 - 1
MediaBrowser.Model/Dlna/StreamInfoSorter.cs

@@ -7,7 +7,7 @@ namespace MediaBrowser.Model.Dlna
 {
 {
     public class StreamInfoSorter
     public class StreamInfoSorter
     {
     {
-        public static List<StreamInfo> SortMediaSources(List<StreamInfo> streams)
+        public static List<StreamInfo> SortMediaSources(List<StreamInfo> streams, int? maxBitrate)
         {
         {
             return streams.OrderBy(i =>
             return streams.OrderBy(i =>
             {
             {
@@ -41,6 +41,23 @@ namespace MediaBrowser.Model.Dlna
                         return 1;
                         return 1;
                 }
                 }
 
 
+            }).ThenBy(i =>
+            {
+                if (maxBitrate.HasValue)
+                {
+                    if (i.MediaSource.Bitrate.HasValue)
+                    {
+                        if (i.MediaSource.Bitrate.Value <= maxBitrate.Value)
+                        {
+                            return 0;
+                        }
+
+                        return 2;
+                    }
+                }
+
+                return 1;
+
             }).ToList();
             }).ToList();
         }
         }
     }
     }

+ 3 - 1
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -246,6 +246,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             string audioCodec = "ac3";
             string audioCodec = "ac3";
 
 
             int? videoBitrate = null;
             int? videoBitrate = null;
+            int? audioBitrate = null;
 
 
             if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase))
             if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase))
             {
             {
@@ -306,6 +307,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                     audioCodec = channel.AudioCodec;
                     audioCodec = channel.AudioCodec;
 
 
                     videoBitrate = (channel.IsHD ?? true) ? 15000000 : 2000000;
                     videoBitrate = (channel.IsHD ?? true) ? 15000000 : 2000000;
+                    audioBitrate = (channel.IsHD ?? true) ? 448000 : 192000;
                 }
                 }
             }
             }
 
 
@@ -346,7 +348,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                                 // Set the index to -1 because we don't know the exact index of the audio stream within the container
                                 // Set the index to -1 because we don't know the exact index of the audio stream within the container
                                 Index = -1,
                                 Index = -1,
                                 Codec = audioCodec,
                                 Codec = audioCodec,
-                                BitRate = 192000
+                                BitRate = audioBitrate
                             }
                             }
                         },
                         },
                 RequiresOpening = false,
                 RequiresOpening = false,

+ 123 - 6
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -78,8 +78,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _saveAncestorCommand;
         private IDbCommand _saveAncestorCommand;
 
 
         private IDbCommand _updateInheritedRatingCommand;
         private IDbCommand _updateInheritedRatingCommand;
+        private IDbCommand _updateInheritedTagsCommand;
 
 
-        private const int LatestSchemaVersion = 58;
+        private const int LatestSchemaVersion = 61;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -135,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                                 "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
                                 "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
                                 "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
                                 "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
                                 "create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)",
                                 "create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)",
-                                
+
                                 "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
                                 "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
                                 "create index if not exists idxPeopleItemId on People(ItemId)",
                                 "create index if not exists idxPeopleItemId on People(ItemId)",
                                 "create index if not exists idxPeopleName on People(Name)",
                                 "create index if not exists idxPeopleName on People(Name)",
@@ -224,6 +225,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
             _connection.AddColumn(Logger, "TypedBaseItems", "CriticRating", "Float");
             _connection.AddColumn(Logger, "TypedBaseItems", "CriticRating", "Float");
             _connection.AddColumn(Logger, "TypedBaseItems", "CriticRatingSummary", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "CriticRatingSummary", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME");
             _connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME");
+            _connection.AddColumn(Logger, "TypedBaseItems", "InheritedTags", "Text");
 
 
             PrepareStatements();
             PrepareStatements();
 
 
@@ -402,7 +404,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 "guid",
                 "guid",
                 "type",
                 "type",
                 "data",
                 "data",
-				"Path",
+                "Path",
                 "StartDate",
                 "StartDate",
                 "EndDate",
                 "EndDate",
                 "ChannelId",
                 "ChannelId",
@@ -462,7 +464,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 "TrailerTypes",
                 "TrailerTypes",
                 "CriticRating",
                 "CriticRating",
                 "CriticRatingSummary",
                 "CriticRatingSummary",
-                "DateModifiedDuringLastRefresh"
+                "DateModifiedDuringLastRefresh",
+                "InheritedTags"
             };
             };
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -540,8 +543,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             _updateInheritedRatingCommand = _connection.CreateCommand();
             _updateInheritedRatingCommand = _connection.CreateCommand();
             _updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid";
             _updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid";
-            _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue");
             _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@Guid");
             _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@Guid");
+            _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue");
+
+            _updateInheritedTagsCommand = _connection.CreateCommand();
+            _updateInheritedTagsCommand.CommandText = "Update TypedBaseItems set InheritedTags=@InheritedTags where Guid=@Guid";
+            _updateInheritedTagsCommand.Parameters.Add(_updateInheritedTagsCommand, "@Guid");
+            _updateInheritedTagsCommand.Parameters.Add(_updateInheritedTagsCommand, "@InheritedTags");
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -715,7 +723,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
                     _saveItemCommand.GetParameter(index++).Value = item.ServiceName;
                     _saveItemCommand.GetParameter(index++).Value = item.ServiceName;
 
 
-                    _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray());
+                    if (item.Tags.Count > 0)
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray());
+                    }
+                    else
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = null;
+                    }
+
                     _saveItemCommand.GetParameter(index++).Value = item.IsFolder;
                     _saveItemCommand.GetParameter(index++).Value = item.IsFolder;
 
 
                     _saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString();
                     _saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString();
@@ -765,6 +781,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
                         _saveItemCommand.GetParameter(index++).Value = item.DateModifiedDuringLastRefresh.Value;
                         _saveItemCommand.GetParameter(index++).Value = item.DateModifiedDuringLastRefresh.Value;
                     }
                     }
 
 
+                    var inheritedTags = item.GetInheritedTags();
+                    if (inheritedTags.Count > 0)
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = string.Join("|", inheritedTags.ToArray());
+                    }
+                    else
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = null;
+                    }
+
                     _saveItemCommand.Transaction = transaction;
                     _saveItemCommand.Transaction = transaction;
 
 
                     _saveItemCommand.ExecuteNonQuery();
                     _saveItemCommand.ExecuteNonQuery();
@@ -2165,6 +2191,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 excludeTagIndex++;
                 excludeTagIndex++;
             }
             }
 
 
+            excludeTagIndex = 0;
+            foreach (var excludeTag in query.ExcludeInheritedTags)
+            {
+                whereClauses.Add("InheritedTags not like @excludeInheritedTag" + excludeTagIndex);
+                cmd.Parameters.Add(cmd, "@excludeInheritedTag" + excludeTagIndex, DbType.String).Value = "%" + excludeTag + "%";
+                excludeTagIndex++;
+            }
+
             if (addPaging)
             if (addPaging)
             {
             {
                 if (query.StartIndex.HasValue && query.StartIndex.Value > 0)
                 if (query.StartIndex.HasValue && query.StartIndex.Value > 0)
@@ -2224,6 +2258,88 @@ namespace MediaBrowser.Server.Implementations.Persistence
         };
         };
 
 
         public async Task UpdateInheritedValues(CancellationToken cancellationToken)
         public async Task UpdateInheritedValues(CancellationToken cancellationToken)
+        {
+            await UpdateInheritedParentalRating(cancellationToken).ConfigureAwait(false);
+            await UpdateInheritedTags(cancellationToken).ConfigureAwait(false);
+        }
+
+        private async Task UpdateInheritedTags(CancellationToken cancellationToken)
+        {
+            var newValues = new List<Tuple<Guid, string>>();
+
+            using (var cmd = _connection.CreateCommand())
+            {
+                cmd.CommandText = "select Guid,InheritedTags,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer where NewInheritedTags <> InheritedTags";
+
+                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
+                {
+                    while (reader.Read())
+                    {
+                        var id = reader.GetGuid(0);
+                        string value = reader.IsDBNull(2) ? null : reader.GetString(2);
+
+                        newValues.Add(new Tuple<Guid, string>(id, value));
+                    }
+                }
+            }
+
+            Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count);
+            if (newValues.Count == 0)
+            {
+                return;
+            }
+
+            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+            IDbTransaction transaction = null;
+
+            try
+            {
+                transaction = _connection.BeginTransaction();
+                
+                foreach (var item in newValues)
+                {
+                    _updateInheritedTagsCommand.GetParameter(0).Value = item.Item1;
+                    _updateInheritedTagsCommand.GetParameter(1).Value = item.Item2;
+
+                    _updateInheritedTagsCommand.Transaction = transaction;
+                    _updateInheritedTagsCommand.ExecuteNonQuery();
+                }
+
+                transaction.Commit();
+            }
+            catch (OperationCanceledException)
+            {
+                if (transaction != null)
+                {
+                    transaction.Rollback();
+                }
+
+                throw;
+            }
+            catch (Exception e)
+            {
+                Logger.ErrorException("Error running query:", e);
+
+                if (transaction != null)
+                {
+                    transaction.Rollback();
+                }
+
+                throw;
+            }
+            finally
+            {
+                if (transaction != null)
+                {
+                    transaction.Dispose();
+                }
+
+                WriteLock.Release();
+            }
+        }
+
+        private async Task UpdateInheritedParentalRating(CancellationToken cancellationToken)
         {
         {
             var newValues = new List<Tuple<Guid, int>>();
             var newValues = new List<Tuple<Guid, int>>();
 
 
@@ -2243,6 +2359,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 }
                 }
             }
             }
 
 
+            Logger.Debug("UpdateInheritedParentalRatings - {0} rows", newValues.Count);
             if (newValues.Count == 0)
             if (newValues.Count == 0)
             {
             {
                 return;
                 return;