mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
support channel folders
This commit is contained in:
parent
c3f2021cad
commit
8aadbf3513
@ -8,6 +8,8 @@ namespace MediaBrowser.Controller.Channels
|
|||||||
{
|
{
|
||||||
public string ExternalId { get; set; }
|
public string ExternalId { get; set; }
|
||||||
|
|
||||||
|
public string ChannelId { get; set; }
|
||||||
|
|
||||||
public ChannelItemType ChannelItemType { get; set; }
|
public ChannelItemType ChannelItemType { get; set; }
|
||||||
|
|
||||||
public bool IsInfiniteStream { get; set; }
|
public bool IsInfiniteStream { get; set; }
|
||||||
|
@ -7,6 +7,8 @@ namespace MediaBrowser.Controller.Channels
|
|||||||
{
|
{
|
||||||
public string ExternalId { get; set; }
|
public string ExternalId { get; set; }
|
||||||
|
|
||||||
|
public string ChannelId { get; set; }
|
||||||
|
|
||||||
public ChannelItemType ChannelItemType { get; set; }
|
public ChannelItemType ChannelItemType { get; set; }
|
||||||
|
|
||||||
public string OriginalImageUrl { get; set; }
|
public string OriginalImageUrl { get; set; }
|
||||||
|
30
MediaBrowser.Controller/Channels/ChannelInfo.cs
Normal file
30
MediaBrowser.Controller/Channels/ChannelInfo.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.Channels
|
||||||
|
{
|
||||||
|
public class ChannelInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the home page URL.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The home page URL.</value>
|
||||||
|
public string HomePageUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this instance can search.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if this instance can search; otherwise, <c>false</c>.</value>
|
||||||
|
public bool CanSearch { get; set; }
|
||||||
|
|
||||||
|
public List<ChannelMediaType> MediaTypes { get; set; }
|
||||||
|
|
||||||
|
public List<ChannelMediaContentType> ContentTypes { get; set; }
|
||||||
|
|
||||||
|
public ChannelInfo()
|
||||||
|
{
|
||||||
|
MediaTypes = new List<ChannelMediaType>();
|
||||||
|
ContentTypes = new List<ChannelMediaContentType>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -88,6 +88,16 @@ namespace MediaBrowser.Controller.Channels
|
|||||||
|
|
||||||
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
|
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
|
||||||
|
|
||||||
|
public string Container { get; set; }
|
||||||
|
public string AudioCodec { get; set; }
|
||||||
|
public string VideoCodec { get; set; }
|
||||||
|
|
||||||
|
public int? AudioBitrate { get; set; }
|
||||||
|
public int? VideoBitrate { get; set; }
|
||||||
|
public int? Width { get; set; }
|
||||||
|
public int? Height { get; set; }
|
||||||
|
public int? AudioChannels { get; set; }
|
||||||
|
|
||||||
public ChannelMediaInfo()
|
public ChannelMediaInfo()
|
||||||
{
|
{
|
||||||
RequiredHttpHeaders = new Dictionary<string, string>();
|
RequiredHttpHeaders = new Dictionary<string, string>();
|
||||||
|
@ -10,6 +10,8 @@ namespace MediaBrowser.Controller.Channels
|
|||||||
{
|
{
|
||||||
public string ExternalId { get; set; }
|
public string ExternalId { get; set; }
|
||||||
|
|
||||||
|
public string ChannelId { get; set; }
|
||||||
|
|
||||||
public ChannelItemType ChannelItemType { get; set; }
|
public ChannelItemType ChannelItemType { get; set; }
|
||||||
|
|
||||||
public bool IsInfiniteStream { get; set; }
|
public bool IsInfiniteStream { get; set; }
|
||||||
|
@ -66,31 +66,6 @@ namespace MediaBrowser.Controller.Channels
|
|||||||
IEnumerable<IChannel> GetChannels();
|
IEnumerable<IChannel> GetChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChannelInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the home page URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The home page URL.</value>
|
|
||||||
public string HomePageUrl { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance can search.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance can search; otherwise, <c>false</c>.</value>
|
|
||||||
public bool CanSearch { get; set; }
|
|
||||||
|
|
||||||
public List<ChannelMediaType> MediaTypes { get; set; }
|
|
||||||
|
|
||||||
public List<ChannelMediaContentType> ContentTypes { get; set; }
|
|
||||||
|
|
||||||
public ChannelInfo()
|
|
||||||
{
|
|
||||||
MediaTypes = new List<ChannelMediaType>();
|
|
||||||
ContentTypes = new List<ChannelMediaContentType>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ChannelSearchInfo
|
public class ChannelSearchInfo
|
||||||
{
|
{
|
||||||
public string SearchTerm { get; set; }
|
public string SearchTerm { get; set; }
|
||||||
|
@ -4,6 +4,8 @@ namespace MediaBrowser.Controller.Channels
|
|||||||
{
|
{
|
||||||
public interface IChannelItem : IHasImages
|
public interface IChannelItem : IHasImages
|
||||||
{
|
{
|
||||||
|
string ChannelId { get; set; }
|
||||||
|
|
||||||
string ExternalId { get; set; }
|
string ExternalId { get; set; }
|
||||||
|
|
||||||
ChannelItemType ChannelItemType { get; set; }
|
ChannelItemType ChannelItemType { get; set; }
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
<Link>Properties\SharedVersion.cs</Link>
|
<Link>Properties\SharedVersion.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Channels\ChannelCategoryItem.cs" />
|
<Compile Include="Channels\ChannelCategoryItem.cs" />
|
||||||
|
<Compile Include="Channels\ChannelInfo.cs" />
|
||||||
<Compile Include="Channels\ChannelItemInfo.cs" />
|
<Compile Include="Channels\ChannelItemInfo.cs" />
|
||||||
<Compile Include="Channels\IChannel.cs" />
|
<Compile Include="Channels\IChannel.cs" />
|
||||||
<Compile Include="Channels\IChannelManager.cs" />
|
<Compile Include="Channels\IChannelManager.cs" />
|
||||||
|
@ -215,6 +215,9 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\Entities\ChapterInfo.cs">
|
<Compile Include="..\MediaBrowser.Model\Entities\ChapterInfo.cs">
|
||||||
<Link>Entities\ChapterInfo.cs</Link>
|
<Link>Entities\ChapterInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MediaBrowser.Model\Entities\CollectionType.cs">
|
||||||
|
<Link>Entities\CollectionType.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Entities\DisplayPreferences.cs">
|
<Compile Include="..\MediaBrowser.Model\Entities\DisplayPreferences.cs">
|
||||||
<Link>Entities\DisplayPreferences.cs</Link>
|
<Link>Entities\DisplayPreferences.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -350,6 +353,9 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\MediaInfo\BlurayDiscInfo.cs">
|
<Compile Include="..\MediaBrowser.Model\MediaInfo\BlurayDiscInfo.cs">
|
||||||
<Link>MediaInfo\BlurayDiscInfo.cs</Link>
|
<Link>MediaInfo\BlurayDiscInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MediaBrowser.Model\MediaInfo\Constants.cs">
|
||||||
|
<Link>MediaInfo\Constants.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\MediaInfo\IBlurayExaminer.cs">
|
<Compile Include="..\MediaBrowser.Model\MediaInfo\IBlurayExaminer.cs">
|
||||||
<Link>MediaInfo\IBlurayExaminer.cs</Link>
|
<Link>MediaInfo\IBlurayExaminer.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -202,6 +202,9 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\Entities\ChapterInfo.cs">
|
<Compile Include="..\MediaBrowser.Model\Entities\ChapterInfo.cs">
|
||||||
<Link>Entities\ChapterInfo.cs</Link>
|
<Link>Entities\ChapterInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MediaBrowser.Model\Entities\CollectionType.cs">
|
||||||
|
<Link>Entities\CollectionType.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Entities\DisplayPreferences.cs">
|
<Compile Include="..\MediaBrowser.Model\Entities\DisplayPreferences.cs">
|
||||||
<Link>Entities\DisplayPreferences.cs</Link>
|
<Link>Entities\DisplayPreferences.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -337,6 +340,9 @@
|
|||||||
<Compile Include="..\MediaBrowser.Model\MediaInfo\BlurayDiscInfo.cs">
|
<Compile Include="..\MediaBrowser.Model\MediaInfo\BlurayDiscInfo.cs">
|
||||||
<Link>MediaInfo\BlurayDiscInfo.cs</Link>
|
<Link>MediaInfo\BlurayDiscInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MediaBrowser.Model\MediaInfo\Constants.cs">
|
||||||
|
<Link>MediaInfo\Constants.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\MediaInfo\IBlurayExaminer.cs">
|
<Compile Include="..\MediaBrowser.Model\MediaInfo\IBlurayExaminer.cs">
|
||||||
<Link>MediaInfo\IBlurayExaminer.cs</Link>
|
<Link>MediaInfo\IBlurayExaminer.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -110,6 +110,7 @@
|
|||||||
<Compile Include="LiveTv\SeriesTimerInfoDto.cs" />
|
<Compile Include="LiveTv\SeriesTimerInfoDto.cs" />
|
||||||
<Compile Include="LiveTv\TimerInfoDto.cs" />
|
<Compile Include="LiveTv\TimerInfoDto.cs" />
|
||||||
<Compile Include="Logging\NullLogger.cs" />
|
<Compile Include="Logging\NullLogger.cs" />
|
||||||
|
<Compile Include="MediaInfo\Constants.cs" />
|
||||||
<Compile Include="News\NewsItem.cs" />
|
<Compile Include="News\NewsItem.cs" />
|
||||||
<Compile Include="Providers\ExternalIdInfo.cs" />
|
<Compile Include="Providers\ExternalIdInfo.cs" />
|
||||||
<Compile Include="Providers\ImageProviderInfo.cs" />
|
<Compile Include="Providers\ImageProviderInfo.cs" />
|
||||||
|
24
MediaBrowser.Model/MediaInfo/Constants.cs
Normal file
24
MediaBrowser.Model/MediaInfo/Constants.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
namespace MediaBrowser.Model.MediaInfo
|
||||||
|
{
|
||||||
|
public class Container
|
||||||
|
{
|
||||||
|
public string MP4 = "MP4";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AudioCodec
|
||||||
|
{
|
||||||
|
public string AAC = "AAC";
|
||||||
|
public string MP3 = "MP3";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VideoCodec
|
||||||
|
{
|
||||||
|
public string H263 = "H263";
|
||||||
|
public string H264 = "H264";
|
||||||
|
public string H265 = "H265";
|
||||||
|
public string MPEG4 = "MPEG4";
|
||||||
|
public string MSMPEG4 = "MSMPEG4";
|
||||||
|
public string VC1 = "VC1";
|
||||||
|
}
|
||||||
|
}
|
@ -220,14 +220,28 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(new Guid(query.UserId));
|
: _userManager.GetUserById(new Guid(query.UserId));
|
||||||
|
|
||||||
var id = new Guid(query.ChannelId);
|
var queryChannelId = query.ChannelId;
|
||||||
var channel = _channelEntities.First(i => i.Id == id);
|
var channels = string.IsNullOrWhiteSpace(queryChannelId)
|
||||||
var channelProvider = GetChannelProvider(channel);
|
? _channelEntities
|
||||||
|
: _channelEntities.Where(i => i.Id == new Guid(queryChannelId));
|
||||||
|
|
||||||
var items = await GetChannelItems(channelProvider, user, query.CategoryId, cancellationToken)
|
var itemTasks = channels.Select(async channel =>
|
||||||
.ConfigureAwait(false);
|
{
|
||||||
|
var channelProvider = GetChannelProvider(channel);
|
||||||
|
|
||||||
return await GetReturnItems(items, user, query, cancellationToken).ConfigureAwait(false);
|
var items = await GetChannelItems(channelProvider, user, query.CategoryId, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
var channelId = channel.Id.ToString("N");
|
||||||
|
|
||||||
|
var tasks = items.Select(i => GetChannelItemEntity(i, channelId, cancellationToken));
|
||||||
|
|
||||||
|
return await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
var results = await Task.WhenAll(itemTasks).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return await GetReturnItems(results.SelectMany(i => i), user, query, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
|
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
|
||||||
@ -316,22 +330,13 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
return Path.Combine(_config.ApplicationPaths.CachePath, channelId, categoryKey, user.Id.ToString("N") + ".json");
|
return Path.Combine(_config.ApplicationPaths.CachePath, channelId, categoryKey, user.Id.ToString("N") + ".json");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<QueryResult<BaseItemDto>> GetReturnItems(IEnumerable<ChannelItemInfo> items, User user, ChannelItemQuery query, CancellationToken cancellationToken)
|
private async Task<QueryResult<BaseItemDto>> GetReturnItems(IEnumerable<BaseItem> items, User user, ChannelItemQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Get everything
|
items = ApplyFilters(items, query.Filters, user);
|
||||||
var fields = Enum.GetNames(typeof(ItemFields))
|
|
||||||
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var tasks = items.Select(i => GetChannelItemEntity(i, cancellationToken));
|
items = _libraryManager.Sort(items, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending);
|
||||||
|
|
||||||
IEnumerable<BaseItem> entities = await Task.WhenAll(tasks).ConfigureAwait(false);
|
var all = items.ToList();
|
||||||
|
|
||||||
entities = ApplyFilters(entities, query.Filters, user);
|
|
||||||
|
|
||||||
entities = _libraryManager.Sort(entities, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending);
|
|
||||||
|
|
||||||
var all = entities.ToList();
|
|
||||||
var totalCount = all.Count;
|
var totalCount = all.Count;
|
||||||
|
|
||||||
if (query.StartIndex.HasValue)
|
if (query.StartIndex.HasValue)
|
||||||
@ -345,6 +350,11 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
|
|
||||||
await RefreshIfNeeded(all, cancellationToken).ConfigureAwait(false);
|
await RefreshIfNeeded(all, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Get everything
|
||||||
|
var fields = Enum.GetNames(typeof(ItemFields))
|
||||||
|
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var returnItemArray = all.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
|
var returnItemArray = all.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
@ -358,10 +368,10 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
private string GetIdToHash(string externalId)
|
private string GetIdToHash(string externalId)
|
||||||
{
|
{
|
||||||
// Increment this as needed to force new downloads
|
// Increment this as needed to force new downloads
|
||||||
return externalId + "3";
|
return externalId + "4";
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<BaseItem> GetChannelItemEntity(ChannelItemInfo info, CancellationToken cancellationToken)
|
private async Task<BaseItem> GetChannelItemEntity(ChannelItemInfo info, string internalChannnelId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
BaseItem item;
|
BaseItem item;
|
||||||
Guid id;
|
Guid id;
|
||||||
@ -434,6 +444,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
|
|
||||||
channelItem.OriginalImageUrl = info.ImageUrl;
|
channelItem.OriginalImageUrl = info.ImageUrl;
|
||||||
channelItem.ExternalId = info.Id;
|
channelItem.ExternalId = info.Id;
|
||||||
|
channelItem.ChannelId = internalChannnelId;
|
||||||
channelItem.ChannelItemType = info.Type;
|
channelItem.ChannelItemType = info.Type;
|
||||||
|
|
||||||
var channelMediaItem = item as IChannelMediaItem;
|
var channelMediaItem = item as IChannelMediaItem;
|
||||||
|
@ -381,7 +381,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||||||
{
|
{
|
||||||
firstMovie.IsMultiPart = true;
|
firstMovie.IsMultiPart = true;
|
||||||
|
|
||||||
_logger.Info("Multi-part video found: " + firstMovie.Path);
|
_logger.Debug("Multi-part video found: " + firstMovie.Path);
|
||||||
|
|
||||||
return firstMovie;
|
return firstMovie;
|
||||||
}
|
}
|
||||||
@ -411,7 +411,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||||||
{
|
{
|
||||||
firstMovie.HasLocalAlternateVersions = true;
|
firstMovie.HasLocalAlternateVersions = true;
|
||||||
|
|
||||||
_logger.Info("Multi-version video found: " + firstMovie.Path);
|
_logger.Debug("Multi-version video found: " + firstMovie.Path);
|
||||||
|
|
||||||
return firstMovie;
|
return firstMovie;
|
||||||
}
|
}
|
||||||
|
@ -229,6 +229,9 @@
|
|||||||
<Content Include="dashboard-ui\css\images\items\folders\music.png">
|
<Content Include="dashboard-ui\css\images\items\folders\music.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="dashboard-ui\css\images\items\folders\musicvideos.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="dashboard-ui\css\images\items\folders\photos.png">
|
<Content Include="dashboard-ui\css\images\items\folders\photos.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user