Merge pull request #1649 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-04-14 22:42:29 -04:00
commit fd72bdab5c
9 changed files with 196 additions and 24 deletions

View File

@ -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
{ {

View File

@ -86,9 +86,8 @@ 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) ? // if h264_mp4toannexb is ever added, do not use it for live tv
args + " -bsf:v h264_mp4toannexb" : return args;
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})\"",

View File

@ -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();
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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)

View File

@ -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();
} }
} }

View File

@ -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,

View File

@ -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.
@ -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();
@ -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;
if (item.Tags.Count > 0)
{
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); _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;