commit
5fb3149422
|
@ -109,8 +109,7 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(GameSystem).Name }
|
IncludeItemTypes = new[] { typeof(GameSystem).Name }
|
||||||
};
|
};
|
||||||
var parentIds = new string[] { } ;
|
var gameSystems = _libraryManager.GetItemList(query)
|
||||||
var gameSystems = _libraryManager.GetItemList(query, parentIds)
|
|
||||||
.Cast<GameSystem>()
|
.Cast<GameSystem>()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
@ -130,8 +129,7 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(Game).Name }
|
IncludeItemTypes = new[] { typeof(Game).Name }
|
||||||
};
|
};
|
||||||
var parentIds = new string[] { };
|
var games = _libraryManager.GetItemList(query)
|
||||||
var games = _libraryManager.GetItemList(query, parentIds)
|
|
||||||
.Cast<Game>()
|
.Cast<Game>()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
|
|
@ -519,14 +519,6 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
public string ProviderName { get; set; }
|
public string ProviderName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TunerChannelMapping
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Number { get; set; }
|
|
||||||
public string ProviderChannelNumber { get; set; }
|
|
||||||
public string ProviderChannelName { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("/LiveTv/Registration", "GET")]
|
[Route("/LiveTv/Registration", "GET")]
|
||||||
[Authenticated]
|
[Authenticated]
|
||||||
public class GetLiveTvRegistrationInfo : IReturn<MBRegistrationRecord>
|
public class GetLiveTvRegistrationInfo : IReturn<MBRegistrationRecord>
|
||||||
|
@ -595,36 +587,7 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
|
|
||||||
public async Task<object> Post(SetChannelMapping request)
|
public async Task<object> Post(SetChannelMapping request)
|
||||||
{
|
{
|
||||||
var config = GetConfiguration();
|
return await _liveTvManager.SetChannelMapping(request.ProviderId, request.TunerChannelNumber, request.ProviderChannelNumber).ConfigureAwait(false);
|
||||||
|
|
||||||
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(request.ProviderId, i.Id, StringComparison.OrdinalIgnoreCase));
|
|
||||||
listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, request.TunerChannelNumber, StringComparison.OrdinalIgnoreCase)).ToArray();
|
|
||||||
|
|
||||||
if (!string.Equals(request.TunerChannelNumber, request.ProviderChannelNumber, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
var list = listingsProviderInfo.ChannelMappings.ToList();
|
|
||||||
list.Add(new NameValuePair
|
|
||||||
{
|
|
||||||
Name = request.TunerChannelNumber,
|
|
||||||
Value = request.ProviderChannelNumber
|
|
||||||
});
|
|
||||||
listingsProviderInfo.ChannelMappings = list.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateConfiguration(config);
|
|
||||||
|
|
||||||
var tunerChannels = await _liveTvManager.GetChannelsForListingsProvider(request.ProviderId, CancellationToken.None)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var providerChannels = await _liveTvManager.GetChannelsFromListingsProviderData(request.ProviderId, CancellationToken.None)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var mappings = listingsProviderInfo.ChannelMappings.ToList();
|
|
||||||
|
|
||||||
var tunerChannelMappings =
|
|
||||||
tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList();
|
|
||||||
|
|
||||||
return tunerChannelMappings.First(i => string.Equals(i.Number, request.TunerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<object> Get(GetChannelMappingOptions request)
|
public async Task<object> Get(GetChannelMappingOptions request)
|
||||||
|
@ -645,7 +608,7 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
|
|
||||||
var result = new ChannelMappingOptions
|
var result = new ChannelMappingOptions
|
||||||
{
|
{
|
||||||
TunerChannels = tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(),
|
TunerChannels = tunerChannels.Select(i => _liveTvManager.GetTunerChannelMapping(i, mappings, providerChannels)).ToList(),
|
||||||
|
|
||||||
ProviderChannels = providerChannels.Select(i => new NameIdPair
|
ProviderChannels = providerChannels.Select(i => new NameIdPair
|
||||||
{
|
{
|
||||||
|
@ -662,33 +625,6 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
return ToOptimizedResult(result);
|
return ToOptimizedResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List<NameValuePair> mappings, List<ChannelInfo> providerChannels)
|
|
||||||
{
|
|
||||||
var result = new TunerChannelMapping
|
|
||||||
{
|
|
||||||
Name = channel.Number + " " + channel.Name,
|
|
||||||
Number = channel.Number
|
|
||||||
};
|
|
||||||
|
|
||||||
var mapping = mappings.FirstOrDefault(i => string.Equals(i.Name, channel.Number, StringComparison.OrdinalIgnoreCase));
|
|
||||||
var providerChannelNumber = channel.Number;
|
|
||||||
|
|
||||||
if (mapping != null)
|
|
||||||
{
|
|
||||||
providerChannelNumber = mapping.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var providerChannel = providerChannels.FirstOrDefault(i => string.Equals(i.Number, providerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
|
||||||
|
|
||||||
if (providerChannel != null)
|
|
||||||
{
|
|
||||||
result.ProviderChannelNumber = providerChannel.Number;
|
|
||||||
result.ProviderChannelName = providerChannel.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Get(GetSatIniMappings request)
|
public object Get(GetSatIniMappings request)
|
||||||
{
|
{
|
||||||
return ToOptimizedResult(_liveTvManager.GetSatIniMappings());
|
return ToOptimizedResult(_liveTvManager.GetSatIniMappings());
|
||||||
|
@ -730,11 +666,7 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
|
|
||||||
public void Delete(DeleteListingProvider request)
|
public void Delete(DeleteListingProvider request)
|
||||||
{
|
{
|
||||||
var config = GetConfiguration();
|
_liveTvManager.DeleteListingsProvider(request.Id);
|
||||||
|
|
||||||
config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(request.Id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList();
|
|
||||||
|
|
||||||
_config.SaveConfiguration("livetv", config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<object> Post(AddTunerHost request)
|
public async Task<object> Post(AddTunerHost request)
|
||||||
|
|
|
@ -177,7 +177,8 @@ namespace MediaBrowser.Api.Movies
|
||||||
{
|
{
|
||||||
var categories = new List<RecommendationDto>();
|
var categories = new List<RecommendationDto>();
|
||||||
|
|
||||||
var parentIds = string.IsNullOrWhiteSpace(parentId) ? new string[] { } : new[] { parentId };
|
var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? (Guid?)null : new Guid(parentId);
|
||||||
|
|
||||||
var query = new InternalItemsQuery(user)
|
var query = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[]
|
IncludeItemTypes = new[]
|
||||||
|
@ -189,10 +190,12 @@ namespace MediaBrowser.Api.Movies
|
||||||
// IsMovie = true
|
// IsMovie = true
|
||||||
SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random },
|
SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random },
|
||||||
SortOrder = SortOrder.Descending,
|
SortOrder = SortOrder.Descending,
|
||||||
Limit = 7
|
Limit = 7,
|
||||||
|
ParentId = parentIdGuid,
|
||||||
|
Recursive = true
|
||||||
};
|
};
|
||||||
|
|
||||||
var recentlyPlayedMovies = _libraryManager.GetItemList(query, parentIds).ToList();
|
var recentlyPlayedMovies = _libraryManager.GetItemList(query).ToList();
|
||||||
|
|
||||||
var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
|
@ -208,9 +211,11 @@ namespace MediaBrowser.Api.Movies
|
||||||
Limit = 10,
|
Limit = 10,
|
||||||
IsFavoriteOrLiked = true,
|
IsFavoriteOrLiked = true,
|
||||||
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(),
|
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(),
|
||||||
EnableGroupByMetadataKey = true
|
EnableGroupByMetadataKey = true,
|
||||||
|
ParentId = parentIdGuid,
|
||||||
|
Recursive = true
|
||||||
|
|
||||||
}, parentIds).ToList();
|
}).ToList();
|
||||||
|
|
||||||
var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList();
|
var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList();
|
||||||
// Get recently played directors
|
// Get recently played directors
|
||||||
|
|
|
@ -286,11 +286,19 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
protected string GetH264Encoder(StreamState state)
|
protected string GetH264Encoder(StreamState state)
|
||||||
{
|
{
|
||||||
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
|
||||||
return "h264_qsv";
|
return "h264_qsv";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return "libnvenc";
|
||||||
|
}
|
||||||
|
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return "h264_omx";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "libx264";
|
return "libx264";
|
||||||
|
@ -395,15 +403,18 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(state.VideoRequest.Profile))
|
if (!string.IsNullOrEmpty(state.VideoRequest.Profile))
|
||||||
{
|
{
|
||||||
param += " -profile:v " + state.VideoRequest.Profile;
|
if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// not supported by h264_omx
|
||||||
|
param += " -profile:v " + state.VideoRequest.Profile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(state.VideoRequest.Level))
|
if (!string.IsNullOrEmpty(state.VideoRequest.Level))
|
||||||
{
|
{
|
||||||
var h264Encoder = GetH264Encoder(state);
|
|
||||||
|
|
||||||
// h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
|
// h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
|
||||||
if (String.Equals(h264Encoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) || String.Equals(h264Encoder, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
switch (state.VideoRequest.Level)
|
switch (state.VideoRequest.Level)
|
||||||
{
|
{
|
||||||
|
@ -438,16 +449,21 @@ namespace MediaBrowser.Api.Playback
|
||||||
param += " -level " + state.VideoRequest.Level;
|
param += " -level " + state.VideoRequest.Level;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return param;
|
|
||||||
}
|
}
|
||||||
else
|
else if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
param += " -level " + state.VideoRequest.Level;
|
param += " -level " + state.VideoRequest.Level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "-pix_fmt yuv420p " + param;
|
if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
!string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
!string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
param = "-pix_fmt yuv420p " + param;
|
||||||
|
}
|
||||||
|
|
||||||
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string GetAudioFilterParam(StreamState state, bool isHls)
|
protected string GetAudioFilterParam(StreamState state, bool isHls)
|
||||||
|
@ -563,14 +579,6 @@ namespace MediaBrowser.Api.Playback
|
||||||
filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam));
|
filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (filters.Count > 1)
|
|
||||||
{
|
|
||||||
//filters[filters.Count - 1] += ":flags=fast_bilinear";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var output = string.Empty;
|
var output = string.Empty;
|
||||||
|
|
||||||
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode)
|
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode)
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace MediaBrowser.Api
|
||||||
config.EnableStandaloneMusicKeys = true;
|
config.EnableStandaloneMusicKeys = true;
|
||||||
config.EnableCaseSensitiveItemIds = true;
|
config.EnableCaseSensitiveItemIds = true;
|
||||||
config.EnableFolderView = true;
|
config.EnableFolderView = true;
|
||||||
config.SchemaVersion = 96;
|
config.SchemaVersion = 97;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Post(UpdateStartupConfiguration request)
|
public void Post(UpdateStartupConfiguration request)
|
||||||
|
|
|
@ -317,7 +317,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1);
|
var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1);
|
||||||
|
|
||||||
var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId };
|
var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId);
|
||||||
|
|
||||||
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
|
@ -326,9 +326,10 @@ namespace MediaBrowser.Api
|
||||||
SortOrder = SortOrder.Ascending,
|
SortOrder = SortOrder.Ascending,
|
||||||
MinPremiereDate = minPremiereDate,
|
MinPremiereDate = minPremiereDate,
|
||||||
StartIndex = request.StartIndex,
|
StartIndex = request.StartIndex,
|
||||||
Limit = request.Limit
|
Limit = request.Limit,
|
||||||
|
ParentId = parentIdGuid
|
||||||
|
|
||||||
}, parentIds).ToList();
|
}).ToList();
|
||||||
|
|
||||||
var options = GetDtoOptions(request);
|
var options = GetDtoOptions(request);
|
||||||
|
|
||||||
|
|
|
@ -128,11 +128,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
||||||
|
|
||||||
private void AddIpv4Option(HttpWebRequest request, HttpRequestOptions options)
|
private void AddIpv4Option(HttpWebRequest request, HttpRequestOptions options)
|
||||||
{
|
{
|
||||||
if (!options.PreferIpv4)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.ServicePoint.BindIPEndPointDelegate = (servicePount, remoteEndPoint, retryCount) =>
|
request.ServicePoint.BindIPEndPointDelegate = (servicePount, remoteEndPoint, retryCount) =>
|
||||||
{
|
{
|
||||||
if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork)
|
if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork)
|
||||||
|
@ -150,7 +145,10 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
||||||
|
|
||||||
if (httpWebRequest != null)
|
if (httpWebRequest != null)
|
||||||
{
|
{
|
||||||
AddIpv4Option(httpWebRequest, options);
|
if (options.PreferIpv4)
|
||||||
|
{
|
||||||
|
AddIpv4Option(httpWebRequest, options);
|
||||||
|
}
|
||||||
|
|
||||||
AddRequestHeaders(httpWebRequest, options);
|
AddRequestHeaders(httpWebRequest, options);
|
||||||
|
|
||||||
|
|
|
@ -2175,7 +2175,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (GetParent() is AggregateFolder || this is BasePluginFolder)
|
if (GetParent() is AggregateFolder || this is BasePluginFolder || this is Channel)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,7 +550,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
query.Limit = GetSpecialItemsLimit();
|
query.Limit = GetSpecialItemsLimit();
|
||||||
query.IncludeItemTypes = new[] { typeof(Movie).Name };
|
query.IncludeItemTypes = new[] { typeof(Movie).Name };
|
||||||
|
|
||||||
return _libraryManager.GetItemsResult(query);
|
return ConvertToResult(_libraryManager.GetItemList(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
|
private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
|
||||||
|
@ -564,7 +564,17 @@ namespace MediaBrowser.Controller.Entities
|
||||||
query.Limit = GetSpecialItemsLimit();
|
query.Limit = GetSpecialItemsLimit();
|
||||||
query.IncludeItemTypes = new[] { typeof(Movie).Name };
|
query.IncludeItemTypes = new[] { typeof(Movie).Name };
|
||||||
|
|
||||||
return _libraryManager.GetItemsResult(query);
|
return ConvertToResult(_libraryManager.GetItemList(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryResult<BaseItem> ConvertToResult(IEnumerable<BaseItem> items)
|
||||||
|
{
|
||||||
|
var arr = items.ToArray();
|
||||||
|
return new QueryResult<BaseItem>
|
||||||
|
{
|
||||||
|
Items = arr,
|
||||||
|
TotalRecordCount = arr.Length
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<QueryResult<BaseItem>> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
|
private async Task<QueryResult<BaseItem>> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
|
||||||
|
@ -667,7 +677,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
query.IncludeItemTypes = new[] { typeof(Episode).Name };
|
query.IncludeItemTypes = new[] { typeof(Episode).Name };
|
||||||
query.ExcludeLocationTypes = new[] { LocationType.Virtual };
|
query.ExcludeLocationTypes = new[] { LocationType.Virtual };
|
||||||
|
|
||||||
return _libraryManager.GetItemsResult(query);
|
return ConvertToResult(_libraryManager.GetItemList(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
|
private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
|
||||||
|
@ -696,7 +706,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
query.Limit = GetSpecialItemsLimit();
|
query.Limit = GetSpecialItemsLimit();
|
||||||
query.IncludeItemTypes = new[] { typeof(Episode).Name };
|
query.IncludeItemTypes = new[] { typeof(Episode).Name };
|
||||||
|
|
||||||
return _libraryManager.GetItemsResult(query);
|
return ConvertToResult(_libraryManager.GetItemList(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryResult<BaseItem> GetTvSeries(Folder parent, User user, InternalItemsQuery query)
|
private QueryResult<BaseItem> GetTvSeries(Folder parent, User user, InternalItemsQuery query)
|
||||||
|
|
|
@ -345,6 +345,13 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <param name="validateListings">if set to <c>true</c> [validate listings].</param>
|
/// <param name="validateListings">if set to <c>true</c> [validate listings].</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings);
|
Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings);
|
||||||
|
|
||||||
|
void DeleteListingsProvider(string id);
|
||||||
|
|
||||||
|
Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber);
|
||||||
|
|
||||||
|
TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List<NameValuePair> mappings, List<ChannelInfo> providerChannels);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the lineups.
|
/// Gets the lineups.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
16
MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs
Normal file
16
MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.LiveTv
|
||||||
|
{
|
||||||
|
public class TunerChannelMapping
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Number { get; set; }
|
||||||
|
public string ProviderChannelNumber { get; set; }
|
||||||
|
public string ProviderChannelName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -220,6 +220,7 @@
|
||||||
<Compile Include="LiveTv\SeriesTimerInfo.cs" />
|
<Compile Include="LiveTv\SeriesTimerInfo.cs" />
|
||||||
<Compile Include="LiveTv\TimerEventInfo.cs" />
|
<Compile Include="LiveTv\TimerEventInfo.cs" />
|
||||||
<Compile Include="LiveTv\TimerInfo.cs" />
|
<Compile Include="LiveTv\TimerInfo.cs" />
|
||||||
|
<Compile Include="LiveTv\TunerChannelMapping.cs" />
|
||||||
<Compile Include="Localization\ILocalizationManager.cs" />
|
<Compile Include="Localization\ILocalizationManager.cs" />
|
||||||
<Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />
|
<Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />
|
||||||
<Compile Include="MediaEncoding\EncodingJobOptions.cs" />
|
<Compile Include="MediaEncoding\EncodingJobOptions.cs" />
|
||||||
|
|
|
@ -377,7 +377,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
if (MediaEncoder.SupportsDecoder("h264_qsv"))
|
if (MediaEncoder.SupportsDecoder("h264_qsv"))
|
||||||
{
|
{
|
||||||
// Seeing stalls and failures with decoding. Not worth it compared to encoding.
|
// Seeing stalls and failures with decoding. Not worth it compared to encoding.
|
||||||
//return "-c:v h264_qsv ";
|
return "-c:v h264_qsv ";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "mpeg2video":
|
case "mpeg2video":
|
||||||
|
@ -672,17 +672,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(state.Options.Profile))
|
if (!string.IsNullOrEmpty(state.Options.Profile))
|
||||||
{
|
{
|
||||||
param += " -profile:v " + state.Options.Profile;
|
if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// not supported by h264_omx
|
||||||
|
param += " -profile:v " + state.Options.Profile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var levelString = state.Options.Level.HasValue ? state.Options.Level.Value.ToString(CultureInfo.InvariantCulture) : null;
|
var levelString = state.Options.Level.HasValue ? state.Options.Level.Value.ToString(CultureInfo.InvariantCulture) : null;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(levelString))
|
if (!string.IsNullOrEmpty(levelString))
|
||||||
{
|
{
|
||||||
var h264Encoder = EncodingJobFactory.GetH264Encoder(state, GetEncodingOptions());
|
|
||||||
|
|
||||||
// h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
|
// h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
|
||||||
if (String.Equals(h264Encoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) || String.Equals(h264Encoder, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
switch (levelString)
|
switch (levelString)
|
||||||
{
|
{
|
||||||
|
@ -718,13 +721,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
param += " -level " + levelString;
|
param += " -level " + levelString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "-pix_fmt yuv420p " + param;
|
if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
!string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
!string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
param = "-pix_fmt yuv420p " + param;
|
||||||
|
}
|
||||||
|
|
||||||
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string GetVideoBitrateParam(EncodingJob state, string videoCodec)
|
protected string GetVideoBitrateParam(EncodingJob state, string videoCodec)
|
||||||
|
|
|
@ -27,17 +27,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return new Tuple<List<string>, List<string>>(decoders, encoders);
|
return new Tuple<List<string>, List<string>>(decoders, encoders);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> GetDecoders(string ffmpegPath)
|
private List<string> GetDecoders(string encoderAppPath)
|
||||||
{
|
{
|
||||||
string output = string.Empty;
|
string output = string.Empty;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
output = GetFFMpegOutput(ffmpegPath, "-decoders");
|
output = GetProcessOutput(encoderAppPath, "-decoders");
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
//_logger.Debug("ffmpeg decoder query result: {0}", output ?? string.Empty);
|
|
||||||
|
|
||||||
var found = new List<string>();
|
var found = new List<string>();
|
||||||
var required = new[]
|
var required = new[]
|
||||||
|
@ -51,12 +50,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
{
|
{
|
||||||
var srch = " " + codec + " ";
|
var srch = " " + codec + " ";
|
||||||
|
|
||||||
if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1)
|
if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
{
|
|
||||||
_logger.Warn("ffmpeg is missing decoder " + codec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
_logger.Info("Decoder available: " + codec);
|
||||||
found.Add(codec);
|
found.Add(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,17 +60,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> GetEncoders(string ffmpegPath)
|
private List<string> GetEncoders(string encoderAppPath)
|
||||||
{
|
{
|
||||||
string output = null;
|
string output = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
output = GetFFMpegOutput(ffmpegPath, "-encoders");
|
output = GetProcessOutput(encoderAppPath, "-encoders");
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
//_logger.Debug("ffmpeg encoder query result: {0}", output ?? string.Empty);
|
|
||||||
|
|
||||||
var found = new List<string>();
|
var found = new List<string>();
|
||||||
var required = new[]
|
var required = new[]
|
||||||
|
@ -89,19 +84,18 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
"libmp3lame",
|
"libmp3lame",
|
||||||
"libopus",
|
"libopus",
|
||||||
//"libvorbis",
|
//"libvorbis",
|
||||||
"srt"
|
"srt",
|
||||||
|
"libnvenc",
|
||||||
|
"h264_qsv"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var codec in required)
|
foreach (var codec in required)
|
||||||
{
|
{
|
||||||
var srch = " " + codec + " ";
|
var srch = " " + codec + " ";
|
||||||
|
|
||||||
if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1)
|
if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
{
|
|
||||||
_logger.Warn("ffmpeg is missing encoder " + codec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
_logger.Info("Encoder available: " + codec);
|
||||||
found.Add(codec);
|
found.Add(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +103,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetFFMpegOutput(string path, string arguments)
|
private string GetProcessOutput(string path, string arguments)
|
||||||
{
|
{
|
||||||
var process = new Process
|
var process = new Process
|
||||||
{
|
{
|
||||||
|
@ -147,7 +141,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
}
|
}
|
||||||
catch (Exception ex1)
|
catch (Exception ex1)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error killing ffmpeg", ex1);
|
_logger.ErrorException("Error killing process", ex1);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -556,13 +556,19 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
internal static string GetH264Encoder(EncodingJob state, EncodingOptions options)
|
internal static string GetH264Encoder(EncodingJob state, EncodingOptions options)
|
||||||
{
|
{
|
||||||
if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(options.HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// It's currently failing on live tv
|
return "h264_qsv";
|
||||||
if (state.RunTimeTicks.HasValue)
|
}
|
||||||
{
|
|
||||||
return "h264_qsv";
|
if (string.Equals(options.HardwareAccelerationType, "libnvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
}
|
{
|
||||||
|
return "libnvenc";
|
||||||
|
}
|
||||||
|
if (string.Equals(options.HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return "h264_omx";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "libx264";
|
return "libx264";
|
||||||
|
|
|
@ -192,6 +192,7 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
public int MigrationVersion { get; set; }
|
public int MigrationVersion { get; set; }
|
||||||
public int SchemaVersion { get; set; }
|
public int SchemaVersion { get; set; }
|
||||||
|
public int SqliteCachePages { get; set; }
|
||||||
|
|
||||||
public bool DownloadImagesInAdvance { get; set; }
|
public bool DownloadImagesInAdvance { get; set; }
|
||||||
|
|
||||||
|
@ -211,6 +212,7 @@ namespace MediaBrowser.Model.Configuration
|
||||||
{
|
{
|
||||||
LocalNetworkAddresses = new string[] { };
|
LocalNetworkAddresses = new string[] { };
|
||||||
Migrations = new string[] { };
|
Migrations = new string[] { };
|
||||||
|
SqliteCachePages = 10000;
|
||||||
|
|
||||||
EnableCustomPathSubFolders = true;
|
EnableCustomPathSubFolders = true;
|
||||||
EnableLocalizedGuids = true;
|
EnableLocalizedGuids = true;
|
||||||
|
|
|
@ -1277,6 +1277,16 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
|
|
||||||
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query)
|
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
|
if (query.Recursive && query.ParentId.HasValue)
|
||||||
|
{
|
||||||
|
var parent = GetItemById(query.ParentId.Value);
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
|
||||||
|
query.ParentId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (query.User != null)
|
if (query.User != null)
|
||||||
{
|
{
|
||||||
AddUserToQuery(query, query.User);
|
AddUserToQuery(query, query.User);
|
||||||
|
@ -1285,6 +1295,23 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
return ItemRepository.GetItemList(query);
|
return ItemRepository.GetItemList(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, IEnumerable<string> parentIds)
|
||||||
|
{
|
||||||
|
var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList();
|
||||||
|
|
||||||
|
SetTopParentIdsOrAncestors(query, parents);
|
||||||
|
|
||||||
|
if (query.AncestorIds.Length == 0 && query.TopParentIds.Length == 0)
|
||||||
|
{
|
||||||
|
if (query.User != null)
|
||||||
|
{
|
||||||
|
AddUserToQuery(query, query.User);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ItemRepository.GetItemList(query);
|
||||||
|
}
|
||||||
|
|
||||||
public QueryResult<BaseItem> QueryItems(InternalItemsQuery query)
|
public QueryResult<BaseItem> QueryItems(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query.User != null)
|
if (query.User != null)
|
||||||
|
@ -1406,15 +1433,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
return ItemRepository.GetAlbumArtists(query);
|
return ItemRepository.GetAlbumArtists(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, IEnumerable<string> parentIds)
|
|
||||||
{
|
|
||||||
var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList();
|
|
||||||
|
|
||||||
SetTopParentIdsOrAncestors(query, parents);
|
|
||||||
|
|
||||||
return ItemRepository.GetItemList(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query)
|
public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query.Recursive && query.ParentId.HasValue)
|
if (query.Recursive && query.ParentId.HasValue)
|
||||||
|
@ -1443,15 +1461,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query, IEnumerable<string> parentIds)
|
|
||||||
{
|
|
||||||
var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList();
|
|
||||||
|
|
||||||
SetTopParentIdsOrAncestors(query, parents);
|
|
||||||
|
|
||||||
return GetItemsResult(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetTopParentIdsOrAncestors(InternalItemsQuery query, List<BaseItem> parents)
|
private void SetTopParentIdsOrAncestors(InternalItemsQuery query, List<BaseItem> parents)
|
||||||
{
|
{
|
||||||
if (parents.All(i =>
|
if (parents.All(i =>
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
|
|
||||||
Genres = genreList.ToArray()
|
Genres = genreList.ToArray()
|
||||||
|
|
||||||
}, new string[] { });
|
});
|
||||||
|
|
||||||
var genresDictionary = genreList.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
var genresDictionary = genreList.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
Limit = query.Limit,
|
Limit = query.Limit,
|
||||||
IncludeItemsByName = true
|
IncludeItemsByName = true
|
||||||
|
|
||||||
}, new string[] { });
|
});
|
||||||
|
|
||||||
// Add search hints based on item name
|
// Add search hints based on item name
|
||||||
hints.AddRange(mediaItems.Where(IncludeInSearch).Select(item =>
|
hints.AddRange(mediaItems.Where(IncludeInSearch).Select(item =>
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Common.Security;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
{
|
||||||
|
public class EmbyTVRegistration : IRequiresRegistration
|
||||||
|
{
|
||||||
|
private readonly ISecurityManager _securityManager;
|
||||||
|
|
||||||
|
public static EmbyTVRegistration Instance;
|
||||||
|
|
||||||
|
public EmbyTVRegistration(ISecurityManager securityManager)
|
||||||
|
{
|
||||||
|
_securityManager = securityManager;
|
||||||
|
Instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool? _isXmlTvEnabled;
|
||||||
|
|
||||||
|
public Task LoadRegistrationInfoAsync()
|
||||||
|
{
|
||||||
|
_isXmlTvEnabled = null;
|
||||||
|
return Task.FromResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> EnableXmlTv()
|
||||||
|
{
|
||||||
|
if (!_isXmlTvEnabled.HasValue)
|
||||||
|
{
|
||||||
|
var info = await _securityManager.GetRegistrationStatus("xmltv").ConfigureAwait(false);
|
||||||
|
_isXmlTvEnabled = info.IsValid;
|
||||||
|
}
|
||||||
|
return _isXmlTvEnabled.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -103,6 +103,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
if (!await EmbyTV.EmbyTVRegistration.Instance.EnableXmlTv().ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
var length = endDateUtc - startDateUtc;
|
||||||
|
if (length.TotalDays > 1)
|
||||||
|
{
|
||||||
|
endDateUtc = startDateUtc.AddDays(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
|
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
|
||||||
var reader = new XmlTvReader(path, GetLanguage(), null);
|
var reader = new XmlTvReader(path, GetLanguage(), null);
|
||||||
|
|
||||||
|
|
|
@ -1462,7 +1462,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
internalQuery.ChannelIds = new[] { query.ChannelId };
|
internalQuery.ChannelIds = new[] { query.ChannelId };
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryResult = _libraryManager.GetItemList(internalQuery, new string[] { });
|
var queryResult = _libraryManager.GetItemList(internalQuery);
|
||||||
IEnumerable<ILiveTvRecording> recordings = queryResult.Cast<ILiveTvRecording>();
|
IEnumerable<ILiveTvRecording> recordings = queryResult.Cast<ILiveTvRecording>();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(query.Id))
|
if (!string.IsNullOrWhiteSpace(query.Id))
|
||||||
|
@ -1936,7 +1936,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
SortBy = new[] { "StartDate" },
|
SortBy = new[] { "StartDate" },
|
||||||
TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Result.Id.ToString("N") }
|
TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Result.Id.ToString("N") }
|
||||||
|
|
||||||
}, new string[] { }).ToList();
|
}).ToList();
|
||||||
|
|
||||||
foreach (var tuple in tuples)
|
foreach (var tuple in tuples)
|
||||||
{
|
{
|
||||||
|
@ -2526,6 +2526,79 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteListingsProvider(string id)
|
||||||
|
{
|
||||||
|
var config = GetConfiguration();
|
||||||
|
|
||||||
|
config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||||
|
|
||||||
|
_config.SaveConfiguration("livetv", config);
|
||||||
|
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber)
|
||||||
|
{
|
||||||
|
var config = GetConfiguration();
|
||||||
|
|
||||||
|
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(providerId, i.Id, StringComparison.OrdinalIgnoreCase));
|
||||||
|
listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, tunerChannelNumber, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||||
|
|
||||||
|
if (!string.Equals(tunerChannelNumber, providerChannelNumber, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var list = listingsProviderInfo.ChannelMappings.ToList();
|
||||||
|
list.Add(new NameValuePair
|
||||||
|
{
|
||||||
|
Name = tunerChannelNumber,
|
||||||
|
Value = providerChannelNumber
|
||||||
|
});
|
||||||
|
listingsProviderInfo.ChannelMappings = list.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
_config.SaveConfiguration("livetv", config);
|
||||||
|
|
||||||
|
var tunerChannels = await GetChannelsForListingsProvider(providerId, CancellationToken.None)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
var providerChannels = await GetChannelsFromListingsProviderData(providerId, CancellationToken.None)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
var mappings = listingsProviderInfo.ChannelMappings.ToList();
|
||||||
|
|
||||||
|
var tunerChannelMappings =
|
||||||
|
tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList();
|
||||||
|
|
||||||
|
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
||||||
|
|
||||||
|
return tunerChannelMappings.First(i => string.Equals(i.Number, tunerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List<NameValuePair> mappings, List<ChannelInfo> providerChannels)
|
||||||
|
{
|
||||||
|
var result = new TunerChannelMapping
|
||||||
|
{
|
||||||
|
Name = channel.Number + " " + channel.Name,
|
||||||
|
Number = channel.Number
|
||||||
|
};
|
||||||
|
|
||||||
|
var mapping = mappings.FirstOrDefault(i => string.Equals(i.Name, channel.Number, StringComparison.OrdinalIgnoreCase));
|
||||||
|
var providerChannelNumber = channel.Number;
|
||||||
|
|
||||||
|
if (mapping != null)
|
||||||
|
{
|
||||||
|
providerChannelNumber = mapping.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var providerChannel = providerChannels.FirstOrDefault(i => string.Equals(i.Number, providerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (providerChannel != null)
|
||||||
|
{
|
||||||
|
result.ProviderChannelNumber = providerChannel.Number;
|
||||||
|
result.ProviderChannelName = providerChannel.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public Task<List<NameIdPair>> GetLineups(string providerType, string providerId, string country, string location)
|
public Task<List<NameIdPair>> GetLineups(string providerType, string providerId, string country, string location)
|
||||||
{
|
{
|
||||||
var config = GetConfiguration();
|
var config = GetConfiguration();
|
||||||
|
|
|
@ -226,6 +226,7 @@
|
||||||
<Compile Include="LiveTv\ChannelImageProvider.cs" />
|
<Compile Include="LiveTv\ChannelImageProvider.cs" />
|
||||||
<Compile Include="LiveTv\EmbyTV\DirectRecorder.cs" />
|
<Compile Include="LiveTv\EmbyTV\DirectRecorder.cs" />
|
||||||
<Compile Include="LiveTv\EmbyTV\EmbyTV.cs" />
|
<Compile Include="LiveTv\EmbyTV\EmbyTV.cs" />
|
||||||
|
<Compile Include="LiveTv\EmbyTV\EmbyTVRegistration.cs" />
|
||||||
<Compile Include="LiveTv\EmbyTV\EncodedRecorder.cs" />
|
<Compile Include="LiveTv\EmbyTV\EncodedRecorder.cs" />
|
||||||
<Compile Include="LiveTv\EmbyTV\EntryPoint.cs" />
|
<Compile Include="LiveTv\EmbyTV\EntryPoint.cs" />
|
||||||
<Compile Include="LiveTv\EmbyTV\IRecorder.cs" />
|
<Compile Include="LiveTv\EmbyTV\IRecorder.cs" />
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
private IDbCommand _updateInheritedRatingCommand;
|
private IDbCommand _updateInheritedRatingCommand;
|
||||||
private IDbCommand _updateInheritedTagsCommand;
|
private IDbCommand _updateInheritedTagsCommand;
|
||||||
|
|
||||||
public const int LatestSchemaVersion = 96;
|
public const int LatestSchemaVersion = 97;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
||||||
|
@ -123,7 +123,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
|
|
||||||
protected override async Task<IDbConnection> CreateConnection(bool isReadOnly = false)
|
protected override async Task<IDbConnection> CreateConnection(bool isReadOnly = false)
|
||||||
{
|
{
|
||||||
var connection = await DbConnector.Connect(DbFilePath, false, false, 10000).ConfigureAwait(false);
|
var connection = await DbConnector.Connect(DbFilePath, false, false, _config.Configuration.SqliteCachePages).ConfigureAwait(false);
|
||||||
|
|
||||||
connection.RunQueries(new[]
|
connection.RunQueries(new[]
|
||||||
{
|
{
|
||||||
|
|
|
@ -524,18 +524,6 @@ namespace MediaBrowser.WebDashboard.Api
|
||||||
|
|
||||||
await DumpFile(filename, Path.Combine(destination, filename), mode, culture, appVersion).ConfigureAwait(false);
|
await DumpFile(filename, Path.Combine(destination, filename), mode, culture, appVersion).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var excludeFiles = new List<string>();
|
|
||||||
|
|
||||||
if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
excludeFiles.Add("supporterkey.html");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var file in excludeFiles)
|
|
||||||
{
|
|
||||||
_fileSystem.DeleteFile(Path.Combine(destination, file));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DumpFile(string resourceVirtualPath, string destinationFilePath, string mode, string culture, string appVersion)
|
private async Task DumpFile(string resourceVirtualPath, string destinationFilePath, string mode, string culture, string appVersion)
|
||||||
|
|
|
@ -258,7 +258,6 @@ namespace MediaBrowser.WebDashboard.Api
|
||||||
|
|
||||||
if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
html = ModifyForCordova(html);
|
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrWhiteSpace(path) && !string.Equals(path, "index.html", StringComparison.OrdinalIgnoreCase))
|
else if (!string.IsNullOrWhiteSpace(path) && !string.Equals(path, "index.html", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -339,41 +338,6 @@ namespace MediaBrowser.WebDashboard.Api
|
||||||
return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
|
return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ModifyForCordova(string html)
|
|
||||||
{
|
|
||||||
// Replace CORDOVA_REPLACE_SUPPORTER_SUBMIT_START
|
|
||||||
html = ReplaceBetween(html, "<!--CORDOVA_REPLACE_SUPPORTER_SUBMIT_START-->", "<!--CORDOVA_REPLACE_SUPPORTER_SUBMIT_END-->", "<i class=\"fa fa-check\"></i><span>${ButtonPurchase}</span>");
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ReplaceBetween(string html, string startToken, string endToken, string newHtml)
|
|
||||||
{
|
|
||||||
var start = html.IndexOf(startToken, StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
if (start == -1)
|
|
||||||
{
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
var end = html.IndexOf(endToken, start, StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
if (end == -1)
|
|
||||||
{
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
string result = html.Substring(start, end - start);
|
|
||||||
html = html.Replace(result, newHtml);
|
|
||||||
|
|
||||||
return ReplaceBetween(html, startToken, endToken, newHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetLocalizationToken(string phrase)
|
|
||||||
{
|
|
||||||
return "${" + phrase + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the meta tags.
|
/// Gets the meta tags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -224,9 +224,6 @@
|
||||||
<Content Include="dashboard-ui\components\metadataeditor\metadataeditor.template.html">
|
<Content Include="dashboard-ui\components\metadataeditor\metadataeditor.template.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="dashboard-ui\devices\ie\ie.css">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="dashboard-ui\css\images\ani_equalizer_black.gif">
|
<Content Include="dashboard-ui\css\images\ani_equalizer_black.gif">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -269,9 +266,6 @@
|
||||||
<Content Include="dashboard-ui\components\imageeditor\imageeditor.template.html">
|
<Content Include="dashboard-ui\components\imageeditor\imageeditor.template.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="dashboard-ui\devices\ie\ie.js">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="dashboard-ui\favorites.html">
|
<Content Include="dashboard-ui\favorites.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -482,9 +476,6 @@
|
||||||
<Content Include="dashboard-ui\forgotpasswordpin.html">
|
<Content Include="dashboard-ui\forgotpasswordpin.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="dashboard-ui\kids.html">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="dashboard-ui\livetvitems.html">
|
<Content Include="dashboard-ui\livetvitems.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -506,9 +497,6 @@
|
||||||
<Content Include="dashboard-ui\scripts\forgotpasswordpin.js">
|
<Content Include="dashboard-ui\scripts\forgotpasswordpin.js">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="dashboard-ui\scripts\kids.js">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="dashboard-ui\scripts\livetvcomponents.js">
|
<Content Include="dashboard-ui\scripts\livetvcomponents.js">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user