add new guide settings

This commit is contained in:
Luke Pulverenti 2016-09-30 02:50:06 -04:00
parent dcfda6d777
commit 6a7fabc3bd
14 changed files with 256 additions and 166 deletions

View file

@ -104,6 +104,26 @@ namespace MediaBrowser.Api.LiveTv
[ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? EnableUserData { get; set; } public bool? EnableUserData { get; set; }
public string SortBy { get; set; }
public SortOrder? SortOrder { get; set; }
/// <summary>
/// Gets the order by.
/// </summary>
/// <returns>IEnumerable{ItemSortBy}.</returns>
public string[] GetOrderBy()
{
var val = SortBy;
if (string.IsNullOrEmpty(val))
{
return new string[] { };
}
return val.Split(',');
}
public GetChannels() public GetChannels()
{ {
AddCurrentProgram = true; AddCurrentProgram = true;
@ -650,6 +670,8 @@ namespace MediaBrowser.Api.LiveTv
{ {
public string Id { get; set; } public string Id { get; set; }
public string Container { get; set; } public string Container { get; set; }
public long T { get; set; }
public long S { get; set; }
} }
public class LiveTvService : BaseApiService public class LiveTvService : BaseApiService
@ -681,9 +703,35 @@ namespace MediaBrowser.Api.LiveTv
outputHeaders["Content-Type"] = MimeTypes.GetMimeType(filePath); outputHeaders["Content-Type"] = MimeTypes.GetMimeType(filePath);
long startPosition = 0;
if (request.T > 0)
{
var now = DateTime.UtcNow;
var totalTicks = now.Ticks - request.S;
if (totalTicks > 0)
{
double requestedOffset = request.T;
requestedOffset = Math.Max(0, requestedOffset - TimeSpan.FromSeconds(10).Ticks);
var pct = requestedOffset / totalTicks;
Logger.Info("Live stream offset pct {0}", pct);
var bytes = new FileInfo(filePath).Length;
Logger.Info("Live stream total bytes {0}", bytes);
startPosition = Convert.ToInt64(pct * bytes);
}
}
Logger.Info("Live stream starting byte position {0}", startPosition);
var streamSource = new ProgressiveFileCopier(_fileSystem, filePath, outputHeaders, null, Logger, CancellationToken.None) var streamSource = new ProgressiveFileCopier(_fileSystem, filePath, outputHeaders, null, Logger, CancellationToken.None)
{ {
AllowEndOfFile = false AllowEndOfFile = false,
StartPosition = startPosition
}; };
return ResultFactory.GetAsyncStreamWriter(streamSource); return ResultFactory.GetAsyncStreamWriter(streamSource);
@ -848,6 +896,8 @@ namespace MediaBrowser.Api.LiveTv
IsNews = request.IsNews, IsNews = request.IsNews,
IsKids = request.IsKids, IsKids = request.IsKids,
IsSports = request.IsSports, IsSports = request.IsSports,
SortBy = request.GetOrderBy(),
SortOrder = request.SortOrder ?? SortOrder.Ascending,
AddCurrentProgram = request.AddCurrentProgram AddCurrentProgram = request.AddCurrentProgram
}, CancellationToken.None).ConfigureAwait(false); }, CancellationToken.None).ConfigureAwait(false);

View file

@ -2602,6 +2602,7 @@ namespace MediaBrowser.Api.Playback
inputModifier += " " + GetFastSeekCommandLineParameter(state.Request); inputModifier += " " + GetFastSeekCommandLineParameter(state.Request);
inputModifier = inputModifier.Trim(); inputModifier = inputModifier.Trim();
//inputModifier += " -fflags +genpts+ignidx+igndts";
if (state.VideoRequest != null && genPts) if (state.VideoRequest != null && genPts)
{ {
inputModifier += " -fflags +genpts"; inputModifier += " -fflags +genpts";

View file

@ -151,6 +151,8 @@ namespace MediaBrowser.Controller.Entities
public Dictionary<string, string> ExcludeProviderIds { get; set; } public Dictionary<string, string> ExcludeProviderIds { get; set; }
public bool EnableGroupByMetadataKey { get; set; } public bool EnableGroupByMetadataKey { get; set; }
public List<Tuple<string, SortOrder>> OrderBy { get; set; }
public InternalItemsQuery() public InternalItemsQuery()
{ {
GroupByPresentationUniqueKey = true; GroupByPresentationUniqueKey = true;
@ -193,6 +195,7 @@ namespace MediaBrowser.Controller.Entities
TrailerTypes = new TrailerType[] { }; TrailerTypes = new TrailerType[] { };
AirDays = new DayOfWeek[] { }; AirDays = new DayOfWeek[] { };
SeriesStatuses = new SeriesStatus[] { }; SeriesStatuses = new SeriesStatus[] { };
OrderBy = new List<Tuple<string, SortOrder>>();
} }
public InternalItemsQuery(User user) public InternalItemsQuery(User user)

View file

@ -13,11 +13,13 @@ namespace MediaBrowser.Controller.LiveTv
public int ConsumerCount { get; set; } public int ConsumerCount { get; set; }
public ITunerHost TunerHost { get; set; } public ITunerHost TunerHost { get; set; }
public string OriginalStreamId { get; set; } public string OriginalStreamId { get; set; }
public bool EnableStreamSharing { get; set; }
public LiveStream(MediaSourceInfo mediaSource) public LiveStream(MediaSourceInfo mediaSource)
{ {
OriginalMediaSource = mediaSource; OriginalMediaSource = mediaSource;
OpenedMediaSource = mediaSource; OpenedMediaSource = mediaSource;
EnableStreamSharing = true;
} }
public async Task Open(CancellationToken cancellationToken) public async Task Open(CancellationToken cancellationToken)

View file

@ -235,6 +235,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
throw new ResourceNotFoundException("ffprobe not found"); throw new ResourceNotFoundException("ffprobe not found");
} }
path = newPaths.Item1;
if (!ValidateVersion(path)) if (!ValidateVersion(path))
{ {
throw new ResourceNotFoundException("ffmpeg version 3.0 or greater is required."); throw new ResourceNotFoundException("ffmpeg version 3.0 or greater is required.");

View file

@ -215,13 +215,26 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty)); list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty));
list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty)); list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty));
if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls")) var forceStartPosition = false;
long startPositionTicks = item.StartPositionTicks;
//if (item.MediaSource.DateLiveStreamOpened.HasValue && startPositionTicks == 0)
//{
// var elapsed = DateTime.UtcNow - item.MediaSource.DateLiveStreamOpened.Value;
// elapsed -= TimeSpan.FromSeconds(20);
// if (elapsed.TotalSeconds >= 0)
// {
// startPositionTicks = elapsed.Ticks + startPositionTicks;
// forceStartPosition = true;
// }
//}
if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls") && !forceStartPosition)
{ {
list.Add(new NameValuePair("StartTimeTicks", string.Empty)); list.Add(new NameValuePair("StartTimeTicks", string.Empty));
} }
else else
{ {
list.Add(new NameValuePair("StartTimeTicks", StringHelper.ToStringCultureInvariant(item.StartPositionTicks))); list.Add(new NameValuePair("StartTimeTicks", StringHelper.ToStringCultureInvariant(startPositionTicks)));
} }
list.Add(new NameValuePair("Level", item.VideoLevel.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoLevel.Value) : string.Empty)); list.Add(new NameValuePair("Level", item.VideoLevel.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoLevel.Value) : string.Empty));

View file

@ -1,4 +1,5 @@
 using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.LiveTv namespace MediaBrowser.Model.LiveTv
{ {
/// <summary> /// <summary>
@ -85,9 +86,18 @@ namespace MediaBrowser.Model.LiveTv
public bool? IsSports { get; set; } public bool? IsSports { get; set; }
public bool? IsSeries { get; set; } public bool? IsSeries { get; set; }
public string[] SortBy { get; set; }
/// <summary>
/// The sort order to return results with
/// </summary>
/// <value>The sort order.</value>
public SortOrder? SortOrder { get; set; }
public LiveTvChannelQuery() public LiveTvChannelQuery()
{ {
EnableUserData = true; EnableUserData = true;
SortBy = new string[] { };
} }
} }
} }

View file

@ -60,7 +60,6 @@ namespace MediaBrowser.Model.LiveTv
public TunerHostInfo() public TunerHostInfo()
{ {
IsEnabled = true; IsEnabled = true;
AllowHWTranscoding = true;
} }
} }

View file

@ -483,7 +483,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
if (existingTimer != null) if (existingTimer != null)
{ {
if (existingTimer.Status == RecordingStatus.Cancelled) if (existingTimer.Status == RecordingStatus.Cancelled ||
existingTimer.Status == RecordingStatus.Completed)
{ {
existingTimer.Status = RecordingStatus.New; existingTimer.Status = RecordingStatus.New;
_timerProvider.Update(existingTimer); _timerProvider.Update(existingTimer);
@ -832,12 +833,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
return result.Item2; return result.Item2;
} }
private MediaSourceInfo CloneMediaSource(MediaSourceInfo mediaSource, int consumerId) private MediaSourceInfo CloneMediaSource(MediaSourceInfo mediaSource, int consumerId, bool enableStreamSharing)
{ {
var json = _jsonSerializer.SerializeToString(mediaSource); var json = _jsonSerializer.SerializeToString(mediaSource);
mediaSource = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json); mediaSource = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json);
mediaSource.Id = consumerId.ToString(CultureInfo.InvariantCulture) + "_" + mediaSource.Id; mediaSource.Id = Guid.NewGuid().ToString("N") + "_" + mediaSource.Id;
if (mediaSource.DateLiveStreamOpened.HasValue && enableStreamSharing)
{
var ticks = (DateTime.UtcNow - mediaSource.DateLiveStreamOpened.Value).Ticks - TimeSpan.FromSeconds(10).Ticks;
ticks = Math.Max(0, ticks);
mediaSource.Path += "?t=" + ticks.ToString(CultureInfo.InvariantCulture) + "&s=" + mediaSource.DateLiveStreamOpened.Value.Ticks.ToString(CultureInfo.InvariantCulture);
}
return mediaSource; return mediaSource;
} }
@ -850,14 +858,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
var result = _liveStreams.Values.FirstOrDefault(i => string.Equals(i.OriginalStreamId, streamId, StringComparison.OrdinalIgnoreCase)); var result = _liveStreams.Values.FirstOrDefault(i => string.Equals(i.OriginalStreamId, streamId, StringComparison.OrdinalIgnoreCase));
if (result != null) if (result != null && result.EnableStreamSharing)
{ {
//result.ConsumerCount++; result.ConsumerCount++;
//_logger.Info("Live stream {0} consumer count is now {1}", streamId, result.ConsumerCount); _logger.Info("Live stream {0} consumer count is now {1}", streamId, result.ConsumerCount);
//_liveStreamsSemaphore.Release(); var openedMediaSource = CloneMediaSource(result.OpenedMediaSource, result.ConsumerCount - 1, result.EnableStreamSharing);
//return new Tuple<LiveStream, MediaSourceInfo, ITunerHost>(result, CloneMediaSource(result.OpenedMediaSource, result.ConsumerCount - 1), result.TunerHost); _liveStreamsSemaphore.Release();
return new Tuple<LiveStream, MediaSourceInfo, ITunerHost>(result, openedMediaSource, result.TunerHost);
} }
try try
@ -868,16 +877,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{ {
result = await hostInstance.GetChannelStream(channelId, streamId, cancellationToken).ConfigureAwait(false); result = await hostInstance.GetChannelStream(channelId, streamId, cancellationToken).ConfigureAwait(false);
_liveStreams[result.OpenedMediaSource.Id] = result; var openedMediaSource = CloneMediaSource(result.OpenedMediaSource, 0, result.EnableStreamSharing);
_liveStreams[openedMediaSource.Id] = result;
result.ConsumerCount++; result.ConsumerCount++;
result.TunerHost = hostInstance; result.TunerHost = hostInstance;
result.OriginalStreamId = streamId; result.OriginalStreamId = streamId;
_logger.Info("Returning mediasource streamId {0}, mediaSource.Id {1}, mediaSource.LiveStreamId {2}", _logger.Info("Returning mediasource streamId {0}, mediaSource.Id {1}, mediaSource.LiveStreamId {2}",
streamId, result.OpenedMediaSource.Id, result.OpenedMediaSource.LiveStreamId); streamId, openedMediaSource.Id, openedMediaSource.LiveStreamId);
return new Tuple<LiveStream, MediaSourceInfo, ITunerHost>(result, CloneMediaSource(result.OpenedMediaSource, 0), hostInstance); return new Tuple<LiveStream, MediaSourceInfo, ITunerHost>(result, openedMediaSource, hostInstance);
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
@ -925,7 +936,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public async Task CloseLiveStream(string id, CancellationToken cancellationToken) public async Task CloseLiveStream(string id, CancellationToken cancellationToken)
{ {
// Ignore the consumer id // Ignore the consumer id
id = id.Substring(id.IndexOf('_') + 1); //id = id.Substring(id.IndexOf('_') + 1);
await _liveStreamsSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); await _liveStreamsSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
@ -1143,8 +1154,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
try try
{ {
var allMediaSources = var allMediaSources = await GetChannelStreamMediaSources(timer.ChannelId, CancellationToken.None).ConfigureAwait(false);
await GetChannelStreamMediaSources(timer.ChannelId, CancellationToken.None).ConfigureAwait(false);
var liveStreamInfo = await GetChannelStreamInternal(timer.ChannelId, allMediaSources[0].Id, CancellationToken.None) var liveStreamInfo = await GetChannelStreamInternal(timer.ChannelId, allMediaSources[0].Id, CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);

View file

@ -141,7 +141,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{ {
var maxBitrate = 25000000; var maxBitrate = 25000000;
videoArgs = string.Format( videoArgs = string.Format(
"-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41", "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41 -tune zerolatency",
GetOutputSizeParam(), GetOutputSizeParam(),
maxBitrate.ToString(CultureInfo.InvariantCulture)); maxBitrate.ToString(CultureInfo.InvariantCulture));
} }
@ -151,16 +151,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
} }
var durationParam = " -t " + _mediaEncoder.GetTimeParameter(duration.Ticks); var durationParam = " -t " + _mediaEncoder.GetTimeParameter(duration.Ticks);
var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\"{4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; var inputModifiers = "-fflags +genpts -async 1 -vsync -1";
var commandLineArgs = "-i \"{0}\"{4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\"";
long startTimeTicks = 0;
//if (mediaSource.DateLiveStreamOpened.HasValue)
//{
// var elapsed = DateTime.UtcNow - mediaSource.DateLiveStreamOpened.Value;
// elapsed -= TimeSpan.FromSeconds(10);
// if (elapsed.TotalSeconds >= 0)
// {
// startTimeTicks = elapsed.Ticks + startTimeTicks;
// }
//}
if (mediaSource.ReadAtNativeFramerate) if (mediaSource.ReadAtNativeFramerate)
{ {
commandLineArgs = "-re " + commandLineArgs; inputModifiers += " -re";
}
if (startTimeTicks > 0)
{
inputModifiers = "-ss " + _mediaEncoder.GetTimeParameter(startTimeTicks) + " " + inputModifiers;
} }
commandLineArgs = string.Format(commandLineArgs, inputTempFile, targetFile, videoArgs, GetAudioArgs(mediaSource), durationParam); commandLineArgs = string.Format(commandLineArgs, inputTempFile, targetFile, videoArgs, GetAudioArgs(mediaSource), durationParam);
return commandLineArgs; return inputModifiers + " " + commandLineArgs;
} }
private string GetAudioArgs(MediaSourceInfo mediaSource) private string GetAudioArgs(MediaSourceInfo mediaSource)

View file

@ -148,7 +148,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var topFolder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); var topFolder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
var channels = _libraryManager.GetItemList(new InternalItemsQuery var internalQuery = new InternalItemsQuery(user)
{ {
IsMovie = query.IsMovie, IsMovie = query.IsMovie,
IsNews = query.IsNews, IsNews = query.IsNews,
@ -156,109 +156,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv
IsSports = query.IsSports, IsSports = query.IsSports,
IsSeries = query.IsSeries, IsSeries = query.IsSeries,
IncludeItemTypes = new[] { typeof(LiveTvChannel).Name }, IncludeItemTypes = new[] { typeof(LiveTvChannel).Name },
SortBy = new[] { ItemSortBy.SortName }, SortOrder = query.SortOrder ?? SortOrder.Ascending,
TopParentIds = new[] { topFolder.Id.ToString("N") } TopParentIds = new[] { topFolder.Id.ToString("N") },
IsFavorite = query.IsFavorite,
IsLiked = query.IsLiked,
StartIndex = query.StartIndex,
Limit = query.Limit
};
}).Cast<LiveTvChannel>(); internalQuery.OrderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder ?? SortOrder.Ascending)));
if (user != null) if (query.EnableFavoriteSorting)
{ {
// Avoid implicitly captured closure internalQuery.OrderBy.Insert(0, new Tuple<string, SortOrder>(ItemSortBy.IsFavoriteOrLiked, SortOrder.Descending));
var currentUser = user;
channels = channels
.Where(i => i.IsVisible(currentUser))
.OrderBy(i =>
{
double number = 0;
if (!string.IsNullOrEmpty(i.Number))
{
double.TryParse(i.Number, out number);
}
return number;
});
if (query.IsFavorite.HasValue)
{
var val = query.IsFavorite.Value;
channels = channels
.Where(i => _userDataManager.GetUserData(user, i).IsFavorite == val);
}
if (query.IsLiked.HasValue)
{
var val = query.IsLiked.Value;
channels = channels
.Where(i =>
{
var likes = _userDataManager.GetUserData(user, i).Likes;
return likes.HasValue && likes.Value == val;
});
}
if (query.IsDisliked.HasValue)
{
var val = query.IsDisliked.Value;
channels = channels
.Where(i =>
{
var likes = _userDataManager.GetUserData(user, i).Likes;
return likes.HasValue && likes.Value != val;
});
}
} }
var enableFavoriteSorting = query.EnableFavoriteSorting; if (!internalQuery.OrderBy.Any(i => string.Equals(i.Item1, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase)))
channels = channels.OrderBy(i =>
{ {
if (enableFavoriteSorting) internalQuery.OrderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending));
{
var userData = _userDataManager.GetUserData(user, i);
if (userData.IsFavorite)
{
return 0;
}
if (userData.Likes.HasValue)
{
if (!userData.Likes.Value)
{
return 3;
}
return 1;
}
}
return 2;
});
var allChannels = channels.ToList();
IEnumerable<LiveTvChannel> allEnumerable = allChannels;
if (query.StartIndex.HasValue)
{
allEnumerable = allEnumerable.Skip(query.StartIndex.Value);
} }
if (query.Limit.HasValue) var channelResult = _libraryManager.GetItemsResult(internalQuery);
{
allEnumerable = allEnumerable.Take(query.Limit.Value);
}
var result = new QueryResult<LiveTvChannel> var result = new QueryResult<LiveTvChannel>
{ {
Items = allEnumerable.ToArray(), Items = channelResult.Items.Cast<LiveTvChannel>().ToArray(),
TotalRecordCount = allChannels.Count TotalRecordCount = channelResult.TotalRecordCount
}; };
return result; return result;

View file

@ -104,8 +104,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}); });
} }
private Dictionary<string, DiscoverResponse> _modelCache = new Dictionary<string, DiscoverResponse>();
private async Task<string> GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken) private async Task<string> GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken)
{ {
lock (_modelCache)
{
DiscoverResponse response;
if (_modelCache.TryGetValue(info.Url, out response))
{
return response.ModelNumber;
}
}
try try
{ {
using (var stream = await _httpClient.Get(new HttpRequestOptions() using (var stream = await _httpClient.Get(new HttpRequestOptions()
@ -119,6 +129,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{ {
var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream); var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
lock (_modelCache)
{
_modelCache[info.Id] = response;
}
return response.ModelNumber; return response.ModelNumber;
} }
} }
@ -126,8 +141,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{ {
if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound) if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound)
{ {
var defaultValue = "HDHR";
// HDHR4 doesn't have this api // HDHR4 doesn't have this api
return "HDHR"; lock (_modelCache)
{
_modelCache[info.Id] = new DiscoverResponse
{
ModelNumber = defaultValue
};
}
return defaultValue;
} }
throw; throw;
@ -427,18 +450,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
try try
{ {
string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); if (info.AllowHWTranscoding)
model = model ?? string.Empty;
if (info.AllowHWTranscoding && (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1))
{ {
list.Add(await GetMediaSource(info, hdhrId, "heavy").ConfigureAwait(false)); string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false);
model = model ?? string.Empty;
list.Add(await GetMediaSource(info, hdhrId, "internet540").ConfigureAwait(false)); if ((model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1))
list.Add(await GetMediaSource(info, hdhrId, "internet480").ConfigureAwait(false)); {
list.Add(await GetMediaSource(info, hdhrId, "internet360").ConfigureAwait(false)); list.Add(await GetMediaSource(info, hdhrId, "heavy").ConfigureAwait(false));
list.Add(await GetMediaSource(info, hdhrId, "internet240").ConfigureAwait(false));
list.Add(await GetMediaSource(info, hdhrId, "mobile").ConfigureAwait(false)); list.Add(await GetMediaSource(info, hdhrId, "internet540").ConfigureAwait(false));
list.Add(await GetMediaSource(info, hdhrId, "internet480").ConfigureAwait(false));
list.Add(await GetMediaSource(info, hdhrId, "internet360").ConfigureAwait(false));
list.Add(await GetMediaSource(info, hdhrId, "internet240").ConfigureAwait(false));
list.Add(await GetMediaSource(info, hdhrId, "mobile").ConfigureAwait(false));
}
} }
} }
catch catch
@ -474,6 +500,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var mediaSource = await GetMediaSource(info, hdhrId, profile).ConfigureAwait(false); var mediaSource = await GetMediaSource(info, hdhrId, profile).ConfigureAwait(false);
var liveStream = new HdHomerunLiveStream(mediaSource, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost); var liveStream = new HdHomerunLiveStream(mediaSource, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
if (info.AllowHWTranscoding)
{
var model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false);
if ((model ?? string.Empty).IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)
{
liveStream.EnableStreamSharing = !info.AllowHWTranscoding;
}
else
{
liveStream.EnableStreamSharing = true;
}
}
else
{
liveStream.EnableStreamSharing = true;
}
return liveStream; return liveStream;
} }
@ -484,6 +527,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return; return;
} }
lock (_modelCache)
{
_modelCache.Clear();
}
try try
{ {
// Test it by pulling down the lineup // Test it by pulling down the lineup

View file

@ -52,11 +52,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
StartStreamingToTempFile(output, tempFile, url, taskCompletionSource, _liveStreamCancellationTokenSource.Token); StartStreamingToTempFile(output, tempFile, url, taskCompletionSource, _liveStreamCancellationTokenSource.Token);
await taskCompletionSource.Task.ConfigureAwait(false); //OpenedMediaSource.Protocol = MediaProtocol.File;
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
OpenedMediaSource.Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveStreamFiles/" + Path.GetFileNameWithoutExtension(tempFile) + "/stream.ts"; OpenedMediaSource.Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveStreamFiles/" + Path.GetFileNameWithoutExtension(tempFile) + "/stream.ts";
OpenedMediaSource.Protocol = MediaProtocol.Http; OpenedMediaSource.Protocol = MediaProtocol.Http;
await taskCompletionSource.Task.ConfigureAwait(false);
//await Task.Delay(5000).ConfigureAwait(false);
} }
public override Task Close() public override Task Close()

View file

@ -1730,28 +1730,28 @@ namespace MediaBrowser.Server.Implementations.Persistence
return true; return true;
} }
if (query.SortBy != null && query.SortBy.Length > 0) var sortingFields = query.SortBy.ToList();
sortingFields.AddRange(query.OrderBy.Select(i => i.Item1));
if (sortingFields.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase))
{ {
if (query.SortBy.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase)) return true;
{ }
return true; if (sortingFields.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase))
} {
if (query.SortBy.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase)) return true;
{ }
return true; if (sortingFields.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase))
} {
if (query.SortBy.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase)) return true;
{ }
return true; if (sortingFields.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase))
} {
if (query.SortBy.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase)) return true;
{ }
return true; if (sortingFields.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase))
} {
if (query.SortBy.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase)) return true;
{
return true;
}
} }
if (query.IsFavoriteOrLiked.HasValue) if (query.IsFavoriteOrLiked.HasValue)
@ -2151,34 +2151,41 @@ namespace MediaBrowser.Server.Implementations.Persistence
private string GetOrderByText(InternalItemsQuery query) private string GetOrderByText(InternalItemsQuery query)
{ {
var orderBy = query.OrderBy.ToList();
var enableOrderInversion = true;
if (orderBy.Count == 0)
{
orderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder)));
}
else
{
enableOrderInversion = false;
}
if (query.SimilarTo != null) if (query.SimilarTo != null)
{ {
if (query.SortBy == null || query.SortBy.Length == 0) if (orderBy.Count == 0)
{ {
if (query.User != null) orderBy.Add(new Tuple<string, SortOrder>("SimilarityScore", SortOrder.Descending));
{ orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
query.SortBy = new[] { "SimilarityScore", ItemSortBy.Random };
}
else
{
query.SortBy = new[] { "SimilarityScore", ItemSortBy.Random };
}
query.SortOrder = SortOrder.Descending; query.SortOrder = SortOrder.Descending;
enableOrderInversion = false;
} }
} }
if (query.SortBy == null || query.SortBy.Length == 0) query.OrderBy = orderBy;
if (orderBy.Count == 0)
{ {
return string.Empty; return string.Empty;
} }
var isAscending = query.SortOrder != SortOrder.Descending; return " ORDER BY " + string.Join(",", orderBy.Select(i =>
return " ORDER BY " + string.Join(",", query.SortBy.Select(i =>
{ {
var columnMap = MapOrderByField(i, query); var columnMap = MapOrderByField(i.Item1, query);
var columnAscending = isAscending; var columnAscending = i.Item2 == SortOrder.Ascending;
if (columnMap.Item2) if (columnMap.Item2 && enableOrderInversion)
{ {
columnAscending = !columnAscending; columnAscending = !columnAscending;
} }