mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-20 17:14:42 +01:00
Merge branch 'master' into authenticationdb-efcore
# Conflicts: # Jellyfin.Server.Implementations/Security/AuthorizationContext.cs # MediaBrowser.Controller/Library/IUserManager.cs # MediaBrowser.Controller/Security/IAuthenticationRepository.cs # MediaBrowser.Controller/Session/ISessionManager.cs
This commit is contained in:
@@ -17,6 +17,12 @@ namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class Channel : Folder
|
||||
{
|
||||
[JsonIgnore]
|
||||
public override bool SupportsInheritedParentImages => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override SourceType SourceType => SourceType.Channel;
|
||||
|
||||
public override bool IsVisible(User user)
|
||||
{
|
||||
var blockedChannelsPreference = user.GetPreferenceValues<Guid>(PreferenceKind.BlockedChannels);
|
||||
@@ -39,12 +45,6 @@ namespace MediaBrowser.Controller.Channels
|
||||
return base.IsVisible(user);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsInheritedParentImages => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override SourceType SourceType => SourceType.Channel;
|
||||
|
||||
protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Channels;
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace MediaBrowser.Controller.Chapters
|
||||
/// <summary>
|
||||
/// Saves the chapters.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item.</param>
|
||||
/// <param name="chapters">The set of chapters.</param>
|
||||
void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace MediaBrowser.Controller.Collections
|
||||
/// Creates the collection.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <returns>BoxSet wrapped in an awaitable task.</returns>
|
||||
Task<BoxSet> CreateCollectionAsync(CollectionCreationOptions options);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -57,6 +57,15 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <summary>
|
||||
/// Encode an image.
|
||||
/// </summary>
|
||||
/// <param name="inputPath">Input path of image.</param>
|
||||
/// <param name="dateModified">Date modified.</param>
|
||||
/// <param name="outputPath">Output path of image.</param>
|
||||
/// <param name="autoOrient">Auto-orient image.</param>
|
||||
/// <param name="orientation">Desired orientation of image.</param>
|
||||
/// <param name="quality">Quality of encoded image.</param>
|
||||
/// <param name="options">Image processing options.</param>
|
||||
/// <param name="outputFormat">Image format of output.</param>
|
||||
/// <returns>Path of encoded image.</returns>
|
||||
string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat outputFormat);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1711, CS1591
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#nullable disable
|
||||
#pragma warning disable CA1002
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Entities;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
@@ -18,32 +18,23 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Specialized folder that can have items added to it's children by external entities.
|
||||
/// Used for our RootFolder so plug-ins can add items.
|
||||
/// Used for our RootFolder so plugins can add items.
|
||||
/// </summary>
|
||||
public class AggregateFolder : Folder
|
||||
{
|
||||
private bool _requiresRefresh;
|
||||
|
||||
public AggregateFolder()
|
||||
{
|
||||
PhysicalLocationsList = Array.Empty<string>();
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool IsPhysicalRoot => true;
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
private readonly object _childIdsLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// The _virtual children.
|
||||
/// </summary>
|
||||
private readonly ConcurrentBag<BaseItem> _virtualChildren = new ConcurrentBag<BaseItem>();
|
||||
private bool _requiresRefresh;
|
||||
private Guid[] _childrenIds = null;
|
||||
|
||||
public AggregateFolder()
|
||||
{
|
||||
PhysicalLocationsList = Array.Empty<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the virtual children.
|
||||
@@ -51,19 +42,27 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <value>The virtual children.</value>
|
||||
public ConcurrentBag<BaseItem> VirtualChildren => _virtualChildren;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool IsPhysicalRoot => true;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override string[] PhysicalLocations => PhysicalLocationsList;
|
||||
|
||||
public string[] PhysicalLocationsList { get; set; }
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
|
||||
{
|
||||
return CreateResolveArgs(directoryService, true).FileSystemChildren;
|
||||
}
|
||||
|
||||
private Guid[] _childrenIds = null;
|
||||
private readonly object _childIdsLock = new object();
|
||||
|
||||
protected override List<BaseItem> LoadChildren()
|
||||
{
|
||||
lock (_childIdsLock)
|
||||
@@ -169,7 +168,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Adds the virtual child.
|
||||
/// </summary>
|
||||
/// <param name="child">The child.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentNullException">Throws if child is null.</exception>
|
||||
public void AddVirtualChild(BaseItem child)
|
||||
{
|
||||
if (child == null)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA1724, CA1826, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -25,6 +25,12 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
IHasLookupInfo<SongInfo>,
|
||||
IHasMediaSources
|
||||
{
|
||||
public Audio()
|
||||
{
|
||||
Artists = Array.Empty<string>();
|
||||
AlbumArtists = Array.Empty<string>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public IReadOnlyList<string> Artists { get; set; }
|
||||
@@ -33,17 +39,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
[JsonIgnore]
|
||||
public IReadOnlyList<string> AlbumArtists { get; set; }
|
||||
|
||||
public Audio()
|
||||
{
|
||||
Artists = Array.Empty<string>();
|
||||
AlbumArtists = Array.Empty<string>();
|
||||
}
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => true;
|
||||
|
||||
@@ -62,11 +57,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
[JsonIgnore]
|
||||
public override Folder LatestItemsIndexContainer => AlbumEntity;
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
return IsFileProtocol;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public MusicAlbum AlbumEntity => FindParent<MusicAlbum>();
|
||||
|
||||
@@ -77,6 +67,16 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
[JsonIgnore]
|
||||
public override string MediaType => Model.Entities.MediaType.Audio;
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
return IsFileProtocol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the name of the sort.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1721, CA1826, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -23,18 +23,18 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
/// </summary>
|
||||
public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<string> AlbumArtists { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<string> Artists { get; set; }
|
||||
|
||||
public MusicAlbum()
|
||||
{
|
||||
Artists = Array.Empty<string>();
|
||||
AlbumArtists = Array.Empty<string>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<string> AlbumArtists { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<string> Artists { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAddingToPlaylist => true;
|
||||
|
||||
@@ -44,6 +44,25 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
[JsonIgnore]
|
||||
public MusicArtist MusicArtist => GetMusicArtist(new DtoOptions(true));
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsCumulativeRunTimeTicks => true;
|
||||
|
||||
[JsonIgnore]
|
||||
public string AlbumArtist => AlbumArtists.FirstOrDefault();
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tracks.
|
||||
/// </summary>
|
||||
/// <value>The tracks.</value>
|
||||
[JsonIgnore]
|
||||
public IEnumerable<Audio> Tracks => GetRecursiveChildren(i => i is Audio).Cast<Audio>();
|
||||
|
||||
public MusicArtist GetMusicArtist(DtoOptions options)
|
||||
{
|
||||
var parents = GetParents();
|
||||
@@ -64,25 +83,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return null;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsCumulativeRunTimeTicks => true;
|
||||
|
||||
[JsonIgnore]
|
||||
public string AlbumArtist => AlbumArtists.FirstOrDefault();
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tracks.
|
||||
/// </summary>
|
||||
/// <value>The tracks.</value>
|
||||
[JsonIgnore]
|
||||
public IEnumerable<Audio> Tracks => GetRecursiveChildren(i => i is Audio).Cast<Audio>();
|
||||
|
||||
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
|
||||
{
|
||||
return Tracks;
|
||||
|
||||
@@ -44,6 +44,36 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself.
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
public override string ContainingFolderPath => Path;
|
||||
|
||||
[JsonIgnore]
|
||||
public override IEnumerable<BaseItem> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
return base.Children;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
@@ -65,20 +95,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override IEnumerable<BaseItem> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
return base.Children;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
return IsAccessedByName ? 0 : base.GetChildCount(user);
|
||||
@@ -113,14 +129,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself.
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
public override string ContainingFolderPath => Path;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
@@ -167,14 +175,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return info;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
@@ -208,6 +208,8 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
/// <param name="replaceAllMetadata">Option to replace metadata.</param>
|
||||
/// <returns>True if metadata changed.</returns>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetadata)
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh(replaceAllMetadata);
|
||||
|
||||
@@ -15,19 +15,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
/// </summary>
|
||||
public class MusicGenre : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAddingToPlaylist => true;
|
||||
|
||||
@@ -45,6 +32,22 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
[JsonIgnore]
|
||||
public override string ContainingFolderPath => Path;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
@@ -60,9 +63,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return true;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.GenreIds = new[] { Id };
|
||||
@@ -106,6 +106,8 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
/// <param name="replaceAllMetadata">Option to replace metadata.</param>
|
||||
/// <returns>True if metadata changed.</returns>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetadata)
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh(replaceAllMetadata);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1724, CS1591
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
@@ -771,19 +771,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
[JsonIgnore]
|
||||
public Guid ParentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent.
|
||||
/// </summary>
|
||||
/// <value>The parent.</value>
|
||||
[JsonIgnore]
|
||||
public Folder Parent
|
||||
{
|
||||
get => GetParent() as Folder;
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void SetParent(Folder parent)
|
||||
{
|
||||
ParentId = parent == null ? Guid.Empty : parent.Id;
|
||||
@@ -822,8 +809,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
foreach (var parent in GetParents())
|
||||
{
|
||||
var item = parent as T;
|
||||
if (item != null)
|
||||
if (parent is T item)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA1721, CA1819, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -165,6 +165,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public static ICollectionManager CollectionManager { get; set; }
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
if (IsRoot)
|
||||
@@ -206,9 +208,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Adds the child.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <exception cref="InvalidOperationException">Unable to add + item.Name.</exception>
|
||||
public void AddChild(BaseItem item, CancellationToken cancellationToken)
|
||||
public void AddChild(BaseItem item)
|
||||
{
|
||||
item.SetParent(this);
|
||||
|
||||
@@ -259,6 +260,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Loads our children. Validation will occur externally.
|
||||
/// We want this synchronous.
|
||||
/// </summary>
|
||||
/// <returns>Returns children.</returns>
|
||||
protected virtual List<BaseItem> LoadChildren()
|
||||
{
|
||||
// logger.LogDebug("Loading children from {0} {1} {2}", GetType().Name, Id, Path);
|
||||
@@ -643,6 +645,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Get the children of this folder from the actual file system.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
/// <param name="directoryService">The directory service to use for operation.</param>
|
||||
/// <returns>Returns set of base items.</returns>
|
||||
protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||
{
|
||||
var collectionType = LibraryManager.GetContentType(this);
|
||||
@@ -999,8 +1003,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return PostFilterAndSort(items, query, true);
|
||||
}
|
||||
|
||||
public static ICollectionManager CollectionManager { get; set; }
|
||||
|
||||
protected QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items, InternalItemsQuery query, bool enableSorting)
|
||||
{
|
||||
var user = query.User;
|
||||
@@ -1385,18 +1387,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets allowed recursive children of an item.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true)
|
||||
{
|
||||
return GetRecursiveChildren(user, null);
|
||||
}
|
||||
|
||||
public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
{
|
||||
if (user == null)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
using System;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1044, CA1819, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -12,6 +12,55 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class InternalItemsQuery
|
||||
{
|
||||
public InternalItemsQuery()
|
||||
{
|
||||
AlbumArtistIds = Array.Empty<Guid>();
|
||||
AlbumIds = Array.Empty<Guid>();
|
||||
AncestorIds = Array.Empty<Guid>();
|
||||
ArtistIds = Array.Empty<Guid>();
|
||||
BlockUnratedItems = Array.Empty<UnratedItem>();
|
||||
BoxSetLibraryFolders = Array.Empty<Guid>();
|
||||
ChannelIds = Array.Empty<Guid>();
|
||||
ContributingArtistIds = Array.Empty<Guid>();
|
||||
DtoOptions = new DtoOptions();
|
||||
EnableTotalRecordCount = true;
|
||||
ExcludeArtistIds = Array.Empty<Guid>();
|
||||
ExcludeInheritedTags = Array.Empty<string>();
|
||||
ExcludeItemIds = Array.Empty<Guid>();
|
||||
ExcludeItemTypes = Array.Empty<string>();
|
||||
ExcludeTags = Array.Empty<string>();
|
||||
GenreIds = Array.Empty<Guid>();
|
||||
Genres = Array.Empty<string>();
|
||||
GroupByPresentationUniqueKey = true;
|
||||
ImageTypes = Array.Empty<ImageType>();
|
||||
IncludeItemTypes = Array.Empty<string>();
|
||||
ItemIds = Array.Empty<Guid>();
|
||||
MediaTypes = Array.Empty<string>();
|
||||
MinSimilarityScore = 20;
|
||||
OfficialRatings = Array.Empty<string>();
|
||||
OrderBy = Array.Empty<ValueTuple<string, SortOrder>>();
|
||||
PersonIds = Array.Empty<Guid>();
|
||||
PersonTypes = Array.Empty<string>();
|
||||
PresetViews = Array.Empty<string>();
|
||||
SeriesStatuses = Array.Empty<SeriesStatus>();
|
||||
SourceTypes = Array.Empty<SourceType>();
|
||||
StudioIds = Array.Empty<Guid>();
|
||||
Tags = Array.Empty<string>();
|
||||
TopParentIds = Array.Empty<Guid>();
|
||||
TrailerTypes = Array.Empty<TrailerType>();
|
||||
VideoTypes = Array.Empty<VideoType>();
|
||||
Years = Array.Empty<int>();
|
||||
}
|
||||
|
||||
public InternalItemsQuery(User? user)
|
||||
: this()
|
||||
{
|
||||
if (user != null)
|
||||
{
|
||||
SetUser(user);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Recursive { get; set; }
|
||||
|
||||
public int? StartIndex { get; set; }
|
||||
@@ -186,23 +235,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public Guid[] TopParentIds { get; set; }
|
||||
|
||||
public BaseItem? Parent
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
ParentId = Guid.Empty;
|
||||
ParentType = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentId = value.Id;
|
||||
ParentType = value.GetType().Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string[] PresetViews { get; set; }
|
||||
|
||||
public TrailerType[] TrailerTypes { get; set; }
|
||||
@@ -270,72 +302,23 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public bool? DisplayAlbumFolders { get; set; }
|
||||
|
||||
public InternalItemsQuery()
|
||||
public BaseItem? Parent
|
||||
{
|
||||
AlbumArtistIds = Array.Empty<Guid>();
|
||||
AlbumIds = Array.Empty<Guid>();
|
||||
AncestorIds = Array.Empty<Guid>();
|
||||
ArtistIds = Array.Empty<Guid>();
|
||||
BlockUnratedItems = Array.Empty<UnratedItem>();
|
||||
BoxSetLibraryFolders = Array.Empty<Guid>();
|
||||
ChannelIds = Array.Empty<Guid>();
|
||||
ContributingArtistIds = Array.Empty<Guid>();
|
||||
DtoOptions = new DtoOptions();
|
||||
EnableTotalRecordCount = true;
|
||||
ExcludeArtistIds = Array.Empty<Guid>();
|
||||
ExcludeInheritedTags = Array.Empty<string>();
|
||||
ExcludeItemIds = Array.Empty<Guid>();
|
||||
ExcludeItemTypes = Array.Empty<string>();
|
||||
ExcludeTags = Array.Empty<string>();
|
||||
GenreIds = Array.Empty<Guid>();
|
||||
Genres = Array.Empty<string>();
|
||||
GroupByPresentationUniqueKey = true;
|
||||
ImageTypes = Array.Empty<ImageType>();
|
||||
IncludeItemTypes = Array.Empty<string>();
|
||||
ItemIds = Array.Empty<Guid>();
|
||||
MediaTypes = Array.Empty<string>();
|
||||
MinSimilarityScore = 20;
|
||||
OfficialRatings = Array.Empty<string>();
|
||||
OrderBy = Array.Empty<ValueTuple<string, SortOrder>>();
|
||||
PersonIds = Array.Empty<Guid>();
|
||||
PersonTypes = Array.Empty<string>();
|
||||
PresetViews = Array.Empty<string>();
|
||||
SeriesStatuses = Array.Empty<SeriesStatus>();
|
||||
SourceTypes = Array.Empty<SourceType>();
|
||||
StudioIds = Array.Empty<Guid>();
|
||||
Tags = Array.Empty<string>();
|
||||
TopParentIds = Array.Empty<Guid>();
|
||||
TrailerTypes = Array.Empty<TrailerType>();
|
||||
VideoTypes = Array.Empty<VideoType>();
|
||||
Years = Array.Empty<int>();
|
||||
}
|
||||
|
||||
public InternalItemsQuery(User? user)
|
||||
: this()
|
||||
{
|
||||
if (user != null)
|
||||
set
|
||||
{
|
||||
SetUser(user);
|
||||
if (value == null)
|
||||
{
|
||||
ParentId = Guid.Empty;
|
||||
ParentType = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentId = value.Id;
|
||||
ParentType = value.GetType().Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetUser(User user)
|
||||
{
|
||||
MaxParentalRating = user.MaxParentalAgeRating;
|
||||
|
||||
if (MaxParentalRating.HasValue)
|
||||
{
|
||||
string other = UnratedItem.Other.ToString();
|
||||
BlockUnratedItems = user.GetPreference(PreferenceKind.BlockUnratedItems)
|
||||
.Where(i => i != other)
|
||||
.Select(e => Enum.Parse<UnratedItem>(e, true)).ToArray();
|
||||
}
|
||||
|
||||
ExcludeInheritedTags = user.GetPreference(PreferenceKind.BlockedTags);
|
||||
|
||||
User = user;
|
||||
}
|
||||
|
||||
public Dictionary<string, string>? HasAnyProviderId { get; set; }
|
||||
|
||||
public Guid[] AlbumArtistIds { get; set; }
|
||||
@@ -361,5 +344,22 @@ namespace MediaBrowser.Controller.Entities
|
||||
public string? SearchTerm { get; set; }
|
||||
|
||||
public string? SeriesTimerId { get; set; }
|
||||
|
||||
public void SetUser(User user)
|
||||
{
|
||||
MaxParentalRating = user.MaxParentalAgeRating;
|
||||
|
||||
if (MaxParentalRating.HasValue)
|
||||
{
|
||||
string other = UnratedItem.Other.ToString();
|
||||
BlockUnratedItems = user.GetPreference(PreferenceKind.BlockUnratedItems)
|
||||
.Where(i => i != other)
|
||||
.Select(e => Enum.Parse<UnratedItem>(e, true)).ToArray();
|
||||
}
|
||||
|
||||
ExcludeInheritedTags = user.GetPreference(PreferenceKind.BlockedTags);
|
||||
|
||||
User = user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1721, CA1819, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -49,6 +49,30 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
/// <value>The display order.</value>
|
||||
public string DisplayOrder { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
private bool IsLegacyBoxSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(Path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LinkedChildren.Length > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path);
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool IsPreSorted => true;
|
||||
|
||||
public Guid[] LibraryFolderIds { get; set; }
|
||||
|
||||
protected override bool GetBlockUnratedValue(User user)
|
||||
{
|
||||
return user.GetPreferenceValues<UnratedItem>(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Movie);
|
||||
@@ -83,28 +107,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private bool IsLegacyBoxSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(Path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LinkedChildren.Length > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path);
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool IsPreSorted => true;
|
||||
|
||||
public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
|
||||
{
|
||||
return true;
|
||||
@@ -191,8 +193,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return IsVisible(user);
|
||||
}
|
||||
|
||||
public Guid[] LibraryFolderIds { get; set; }
|
||||
|
||||
private Guid[] GetLibraryFolderIds(User user)
|
||||
{
|
||||
return LibraryManager.GetUserRootFolder().GetChildren(user, true)
|
||||
|
||||
@@ -16,6 +16,26 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself.
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
public override string ContainingFolderPath => Path;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether to enable alpha numeric sorting.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public override bool EnableAlphaNumericSorting => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAncestors => false;
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
@@ -49,14 +69,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself.
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
public override string ContainingFolderPath => Path;
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
@@ -67,18 +79,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether to enable alpha numeric sorting.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public override bool EnableAlphaNumericSorting => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAncestors => false;
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -36,6 +36,30 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public string CameraMake { get; set; }
|
||||
|
||||
public string CameraModel { get; set; }
|
||||
|
||||
public string Software { get; set; }
|
||||
|
||||
public double? ExposureTime { get; set; }
|
||||
|
||||
public double? FocalLength { get; set; }
|
||||
|
||||
public ImageOrientation? Orientation { get; set; }
|
||||
|
||||
public double? Aperture { get; set; }
|
||||
|
||||
public double? ShutterSpeed { get; set; }
|
||||
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
public double? Altitude { get; set; }
|
||||
|
||||
public int? IsoSpeedRating { get; set; }
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
return true;
|
||||
@@ -69,29 +93,5 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
return base.GetDefaultPrimaryImageAspectRatio();
|
||||
}
|
||||
|
||||
public string CameraMake { get; set; }
|
||||
|
||||
public string CameraModel { get; set; }
|
||||
|
||||
public string Software { get; set; }
|
||||
|
||||
public double? ExposureTime { get; set; }
|
||||
|
||||
public double? FocalLength { get; set; }
|
||||
|
||||
public ImageOrientation? Orientation { get; set; }
|
||||
|
||||
public double? Aperture { get; set; }
|
||||
|
||||
public double? ShutterSpeed { get; set; }
|
||||
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
public double? Altitude { get; set; }
|
||||
|
||||
public int? IsoSpeedRating { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,19 +15,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class Studio : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself.
|
||||
@@ -42,6 +29,22 @@ namespace MediaBrowser.Controller.Entities
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAncestors => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 16;
|
||||
@@ -67,9 +70,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -23,6 +23,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
TrailerTypes = Array.Empty<TrailerType>();
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool StopRefreshIfLocalMetadataFound => false;
|
||||
|
||||
public TrailerType[] TrailerTypes { get; set; }
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
@@ -97,8 +100,5 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool StopRefreshIfLocalMetadataFound => false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,25 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class UserView : Folder, IHasCollectionType
|
||||
{
|
||||
private static readonly string[] _viewTypesEligibleForGrouping = new string[]
|
||||
{
|
||||
Model.Entities.CollectionType.Movies,
|
||||
Model.Entities.CollectionType.TvShows,
|
||||
string.Empty
|
||||
};
|
||||
|
||||
private static readonly string[] _originalFolderViewTypes = new string[]
|
||||
{
|
||||
Model.Entities.CollectionType.Books,
|
||||
Model.Entities.CollectionType.MusicVideos,
|
||||
Model.Entities.CollectionType.HomeVideos,
|
||||
Model.Entities.CollectionType.Photos,
|
||||
Model.Entities.CollectionType.Music,
|
||||
Model.Entities.CollectionType.BoxSets
|
||||
};
|
||||
|
||||
public static ITVSeriesManager TVSeriesManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the view type.
|
||||
/// </summary>
|
||||
@@ -30,12 +49,22 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public Guid? UserId { get; set; }
|
||||
|
||||
public static ITVSeriesManager TVSeriesManager;
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public string CollectionType => ViewType;
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public override bool SupportsInheritedParentImages => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Guid> GetIdsForAncestorQuery()
|
||||
{
|
||||
@@ -53,17 +82,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsInheritedParentImages => false;
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
return GetChildren(user, true).Count;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
|
||||
{
|
||||
var parent = this as Folder;
|
||||
@@ -81,6 +106,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
.GetUserItems(parent, this, CollectionType, query);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
{
|
||||
query ??= new InternalItemsQuery(user);
|
||||
@@ -91,16 +117,19 @@ namespace MediaBrowser.Controller.Entities
|
||||
return result.ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
{
|
||||
query.SetUser(user);
|
||||
@@ -111,32 +140,26 @@ namespace MediaBrowser.Controller.Entities
|
||||
return GetItemList(query);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
|
||||
{
|
||||
return GetChildren(user, false);
|
||||
}
|
||||
|
||||
private static readonly string[] UserSpecificViewTypes = new string[]
|
||||
{
|
||||
Model.Entities.CollectionType.Playlists
|
||||
};
|
||||
|
||||
public static bool IsUserSpecific(Folder folder)
|
||||
{
|
||||
var collectionFolder = folder as ICollectionFolder;
|
||||
|
||||
if (collectionFolder == null)
|
||||
if (folder is not ICollectionFolder collectionFolder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var supportsUserSpecific = folder as ISupportsUserSpecificView;
|
||||
if (supportsUserSpecific != null && supportsUserSpecific.EnableUserSpecificView)
|
||||
if (folder is ISupportsUserSpecificView supportsUserSpecific
|
||||
&& supportsUserSpecific.EnableUserSpecificView)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return UserSpecificViewTypes.Contains(collectionFolder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
return string.Equals(Model.Entities.CollectionType.Playlists, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static bool IsEligibleForGrouping(Folder folder)
|
||||
@@ -145,39 +168,19 @@ namespace MediaBrowser.Controller.Entities
|
||||
&& IsEligibleForGrouping(collectionFolder.CollectionType);
|
||||
}
|
||||
|
||||
private static string[] ViewTypesEligibleForGrouping = new string[]
|
||||
{
|
||||
Model.Entities.CollectionType.Movies,
|
||||
Model.Entities.CollectionType.TvShows,
|
||||
string.Empty
|
||||
};
|
||||
|
||||
public static bool IsEligibleForGrouping(string viewType)
|
||||
{
|
||||
return ViewTypesEligibleForGrouping.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
return _viewTypesEligibleForGrouping.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static string[] OriginalFolderViewTypes = new string[]
|
||||
{
|
||||
Model.Entities.CollectionType.Books,
|
||||
Model.Entities.CollectionType.MusicVideos,
|
||||
Model.Entities.CollectionType.HomeVideos,
|
||||
Model.Entities.CollectionType.Photos,
|
||||
Model.Entities.CollectionType.Music,
|
||||
Model.Entities.CollectionType.BoxSets
|
||||
};
|
||||
|
||||
public static bool EnableOriginalFolder(string viewType)
|
||||
{
|
||||
return OriginalFolderViewTypes.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
return _originalFolderViewTypes.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, Providers.MetadataRefreshOptions refreshOptions, Providers.IDirectoryService directoryService, System.Threading.CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
switch (viewType)
|
||||
{
|
||||
case CollectionType.Folders:
|
||||
return GetResult(_libraryManager.GetUserRootFolder().GetChildren(user, true), queryParent, query);
|
||||
return GetResult(_libraryManager.GetUserRootFolder().GetChildren(user, true), query);
|
||||
|
||||
case CollectionType.TvShows:
|
||||
return GetTvView(queryParent, user, query);
|
||||
@@ -110,7 +110,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return GetMovieMovies(queryParent, user, query);
|
||||
|
||||
case SpecialFolder.MovieCollections:
|
||||
return GetMovieCollections(queryParent, user, query);
|
||||
return GetMovieCollections(user, query);
|
||||
|
||||
case SpecialFolder.TvFavoriteEpisodes:
|
||||
return GetFavoriteEpisodes(queryParent, user, query);
|
||||
@@ -122,7 +122,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
if (queryParent is UserView)
|
||||
{
|
||||
return GetResult(GetMediaFolders(user).OfType<Folder>().SelectMany(i => i.GetChildren(user, true)), queryParent, query);
|
||||
return GetResult(GetMediaFolders(user).OfType<Folder>().SelectMany(i => i.GetChildren(user, true)), query);
|
||||
}
|
||||
|
||||
return queryParent.GetItems(query);
|
||||
@@ -160,7 +160,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
GetUserView(SpecialFolder.MovieGenres, "Genres", "5", parent)
|
||||
};
|
||||
|
||||
return GetResult(list, parent, query);
|
||||
return GetResult(list, query);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> GetFavoriteMovies(Folder parent, User user, InternalItemsQuery query)
|
||||
@@ -207,7 +207,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return _libraryManager.GetItemsResult(query);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> GetMovieCollections(Folder parent, User user, InternalItemsQuery query)
|
||||
private QueryResult<BaseItem> GetMovieCollections(User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Parent = null;
|
||||
query.IncludeItemTypes = new[] { nameof(BoxSet) };
|
||||
@@ -275,9 +275,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(i => GetUserViewWithName(i.Name, SpecialFolder.MovieGenre, i.SortName, parent));
|
||||
.Select(i => GetUserViewWithName(SpecialFolder.MovieGenre, i.SortName, parent));
|
||||
|
||||
return GetResult(genres, parent, query);
|
||||
return GetResult(genres, query);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> GetMovieGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
|
||||
@@ -323,7 +323,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
GetUserView(SpecialFolder.TvGenres, "Genres", "6", parent)
|
||||
};
|
||||
|
||||
return GetResult(list, parent, query);
|
||||
return GetResult(list, query);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> GetTvLatest(Folder parent, User user, InternalItemsQuery query)
|
||||
@@ -403,9 +403,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(i => GetUserViewWithName(i.Name, SpecialFolder.TvGenre, i.SortName, parent));
|
||||
.Select(i => GetUserViewWithName(SpecialFolder.TvGenre, i.SortName, parent));
|
||||
|
||||
return GetResult(genres, parent, query);
|
||||
return GetResult(genres, query);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
|
||||
@@ -432,13 +432,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
private QueryResult<BaseItem> GetResult<T>(
|
||||
IEnumerable<T> items,
|
||||
BaseItem queryParent,
|
||||
InternalItemsQuery query)
|
||||
where T : BaseItem
|
||||
{
|
||||
items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager));
|
||||
|
||||
return PostFilterAndSort(items, queryParent, null, query, _libraryManager, _config);
|
||||
return PostFilterAndSort(items, null, query, _libraryManager);
|
||||
}
|
||||
|
||||
public static bool FilterItem(BaseItem item, InternalItemsQuery query)
|
||||
@@ -448,11 +447,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public static QueryResult<BaseItem> PostFilterAndSort(
|
||||
IEnumerable<BaseItem> items,
|
||||
BaseItem queryParent,
|
||||
int? totalRecordLimit,
|
||||
InternalItemsQuery query,
|
||||
ILibraryManager libraryManager,
|
||||
IServerConfigurationManager configurationManager)
|
||||
ILibraryManager libraryManager)
|
||||
{
|
||||
var user = query.User;
|
||||
|
||||
@@ -1001,7 +998,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return new BaseItem[] { parent };
|
||||
}
|
||||
|
||||
private UserView GetUserViewWithName(string name, string type, string sortName, BaseItem parent)
|
||||
private UserView GetUserViewWithName(string type, string sortName, BaseItem parent)
|
||||
{
|
||||
return _userViewManager.GetUserSubView(parent.Id, parent.Id.ToString("N", CultureInfo.InvariantCulture), type, sortName);
|
||||
}
|
||||
|
||||
@@ -15,13 +15,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class Year : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAncestors => false;
|
||||
|
||||
list.Insert(0, "Year-" + Name);
|
||||
return list;
|
||||
}
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder containing the item.
|
||||
@@ -31,6 +29,19 @@ namespace MediaBrowser.Controller.Entities
|
||||
[JsonIgnore]
|
||||
public override string ContainingFolderPath => Path;
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, "Year-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 2;
|
||||
@@ -39,14 +50,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAncestors => false;
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
@@ -76,9 +79,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
|
||||
@@ -16,8 +16,6 @@ namespace MediaBrowser.Controller
|
||||
/// </summary>
|
||||
public interface IServerApplicationHost : IApplicationHost
|
||||
{
|
||||
event EventHandler HasUpdateAvailableChanged;
|
||||
|
||||
bool CoreStartupHasCompleted { get; }
|
||||
|
||||
bool CanLaunchWebBrowser { get; }
|
||||
@@ -39,12 +37,6 @@ namespace MediaBrowser.Controller
|
||||
/// </summary>
|
||||
bool ListenWithHttps { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance has update available.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value>
|
||||
bool HasUpdateAvailable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the friendly.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -31,6 +31,29 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
public interface ILibraryManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when [item added].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs> ItemAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item updated].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs> ItemUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item removed].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs> ItemRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root folder.
|
||||
/// </summary>
|
||||
/// <value>The root folder.</value>
|
||||
AggregateFolder RootFolder { get; }
|
||||
|
||||
bool IsScanRunning { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the path.
|
||||
/// </summary>
|
||||
@@ -57,16 +80,10 @@ namespace MediaBrowser.Controller.Library
|
||||
LibraryOptions libraryOptions,
|
||||
string collectionType = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root folder.
|
||||
/// </summary>
|
||||
/// <value>The root folder.</value>
|
||||
AggregateFolder RootFolder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Person.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="name">The name of the person.</param>
|
||||
/// <returns>Task{Person}.</returns>
|
||||
Person GetPerson(string name);
|
||||
|
||||
@@ -81,7 +98,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Gets the artist.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="name">The name of the artist.</param>
|
||||
/// <returns>Task{Artist}.</returns>
|
||||
MusicArtist GetArtist(string name);
|
||||
|
||||
@@ -90,21 +107,21 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Gets a Studio.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="name">The name of the studio.</param>
|
||||
/// <returns>Task{Studio}.</returns>
|
||||
Studio GetStudio(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Genre.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="name">The name of the genre.</param>
|
||||
/// <returns>Task{Genre}.</returns>
|
||||
Genre GetGenre(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the genre.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="name">The name of the music genre.</param>
|
||||
/// <returns>Task{MusicGenre}.</returns>
|
||||
MusicGenre GetMusicGenre(string name);
|
||||
|
||||
@@ -113,7 +130,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>Task{Year}.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Throws if year is invalid.</exception>
|
||||
Year GetYear(int value);
|
||||
|
||||
/// <summary>
|
||||
@@ -205,16 +222,26 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Creates the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to create.</param>
|
||||
/// <param name="parent">Parent of new item.</param>
|
||||
void CreateItem(BaseItem item, BaseItem parent);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the items.
|
||||
/// </summary>
|
||||
/// <param name="items">Items to create.</param>
|
||||
/// <param name="parent">Parent of new items.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
void CreateItems(IReadOnlyList<BaseItem> items, BaseItem parent, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the item.
|
||||
/// </summary>
|
||||
/// <param name="items">Items to update.</param>
|
||||
/// <param name="parent">Parent of updated items.</param>
|
||||
/// <param name="updateReason">Reason for update.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>Returns a Task that can be awaited.</returns>
|
||||
Task UpdateItemsAsync(IReadOnlyList<BaseItem> items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -224,6 +251,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="parent">The parent item.</param>
|
||||
/// <param name="updateReason">The update reason.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Returns a Task that can be awaited.</returns>
|
||||
Task UpdateItemAsync(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -233,23 +261,6 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem RetrieveItem(Guid id);
|
||||
|
||||
bool IsScanRunning { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item added].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs> ItemAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item updated].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs> ItemUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item removed].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs> ItemRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Finds the type of the collection.
|
||||
/// </summary>
|
||||
@@ -294,16 +305,25 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to delete.</param>
|
||||
/// <param name="options">Options to use for deletion.</param>
|
||||
void DeleteItem(BaseItem item, DeleteOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to delete.</param>
|
||||
/// <param name="options">Options to use for deletion.</param>
|
||||
/// <param name="notifyParentItem">Notify parent of deletion.</param>
|
||||
void DeleteItem(BaseItem item, DeleteOptions options, bool notifyParentItem);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to delete.</param>
|
||||
/// <param name="options">Options to use for deletion.</param>
|
||||
/// <param name="parent">Parent of item.</param>
|
||||
/// <param name="notifyParentItem">Notify parent of deletion.</param>
|
||||
void DeleteItem(BaseItem item, DeleteOptions options, BaseItem parent, bool notifyParentItem);
|
||||
|
||||
/// <summary>
|
||||
@@ -314,6 +334,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="parentId">The parent identifier.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <returns>The named view.</returns>
|
||||
UserView GetNamedView(
|
||||
User user,
|
||||
string name,
|
||||
@@ -328,6 +349,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <returns>The named view.</returns>
|
||||
UserView GetNamedView(
|
||||
User user,
|
||||
string name,
|
||||
@@ -340,6 +362,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <returns>The named view.</returns>
|
||||
UserView GetNamedView(
|
||||
string name,
|
||||
string viewType,
|
||||
@@ -397,6 +420,9 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Fills the missing episode numbers from path.
|
||||
/// </summary>
|
||||
/// <param name="episode">Episode to use.</param>
|
||||
/// <param name="forceRefresh">Option to force refresh of episode numbers.</param>
|
||||
/// <returns>True if successful.</returns>
|
||||
bool FillMissingEpisodeNumbersFromPath(Episode episode, bool forceRefresh);
|
||||
|
||||
/// <summary>
|
||||
@@ -539,6 +565,9 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Gets the items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query to use.</param>
|
||||
/// <param name="parents">Items to use for query.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1711, CS1591
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -62,16 +62,32 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Gets the playack media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="user">User to use for operation.</param>
|
||||
/// <param name="allowMediaProbe">Option to allow media probe.</param>
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>List of media sources wrapped in an awaitable task.</returns>
|
||||
Task<List<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the static media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="user">User to use for operation.</param>
|
||||
/// <returns>List of media sources.</returns>
|
||||
List<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the static media source.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="mediaSourceId">Media source to get.</param>
|
||||
/// <param name="liveStreamId">Live stream to use.</param>
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>The static media source wrapped in an awaitable task.</returns>
|
||||
Task<MediaSourceInfo> GetMediaSource(BaseItem item, string mediaSourceId, string liveStreamId, bool enablePathSubstitution, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@@ -21,6 +21,10 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Opens the media source.
|
||||
/// </summary>
|
||||
/// <param name="openToken">Token to use.</param>
|
||||
/// <param name="currentLiveStreams">List of live streams.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>The media source wrapped as an awaitable task.</returns>
|
||||
Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void Save(BaseItem item, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Entities;
|
||||
@@ -15,16 +15,28 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Gets the instant mix from song.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to use.</param>
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instant mix from artist.
|
||||
/// </summary>
|
||||
/// <param name="artist">The artist to use.</param>
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User user, DtoOptions dtoOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instant mix from genre.
|
||||
/// </summary>
|
||||
/// <param name="genres">The genres to use.</param>
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA1707, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -42,6 +42,9 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Gets the user data dto.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="user">User to use.</param>
|
||||
/// <returns>User data dto.</returns>
|
||||
UserItemDataDto GetUserDataDto(BaseItem item, User user);
|
||||
|
||||
UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions dto_options);
|
||||
@@ -64,6 +67,10 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Updates playstate for an item and returns true or false indicating if it was played to completion.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to update.</param>
|
||||
/// <param name="data">Data to update.</param>
|
||||
/// <param name="positionTicks">New playstate.</param>
|
||||
/// <returns>True if playstate was updated.</returns>
|
||||
bool UpdatePlayState(BaseItem item, UserItemData data, long? positionTicks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Initializes the user manager and ensures that a user exists.
|
||||
/// </summary>
|
||||
/// <returns>Awaitable task.</returns>
|
||||
Task InitializeAsync();
|
||||
|
||||
/// <summary>
|
||||
@@ -107,11 +108,18 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Changes the password.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="newPassword">New password to use.</param>
|
||||
/// <returns>Awaitable task.</returns>
|
||||
Task ChangePassword(User user, string newPassword);
|
||||
|
||||
/// <summary>
|
||||
/// Changes the easy password.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="newPassword">New password to use.</param>
|
||||
/// <param name="newPasswordSha1">Hash of new password.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ChangeEasyPassword(User user, string newPassword, string newPasswordSha1);
|
||||
|
||||
/// <summary>
|
||||
@@ -125,6 +133,12 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Authenticates the user.
|
||||
/// </summary>
|
||||
/// <param name="username">The user.</param>
|
||||
/// <param name="password">The password to use.</param>
|
||||
/// <param name="passwordSha1">Hash of password.</param>
|
||||
/// <param name="remoteEndPoint">Remove endpoint to use.</param>
|
||||
/// <param name="isUserSession">Specifies if a user session.</param>
|
||||
/// <returns>User wrapped in awaitable task.</returns>
|
||||
Task<User> AuthenticateUser(string username, string password, string passwordSha1, string remoteEndPoint, bool isUserSession);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -13,10 +13,29 @@ namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface IUserViewManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets user views.
|
||||
/// </summary>
|
||||
/// <param name="query">Query to use.</param>
|
||||
/// <returns>Set of folders.</returns>
|
||||
Folder[] GetUserViews(UserViewQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets user sub views.
|
||||
/// </summary>
|
||||
/// <param name="parentId">Parent to use.</param>
|
||||
/// <param name="type">Type to use.</param>
|
||||
/// <param name="localizationKey">Localization key to use.</param>
|
||||
/// <param name="sortName">Sort to use.</param>
|
||||
/// <returns>User view.</returns>
|
||||
UserView GetUserSubView(Guid parentId, string type, string localizationKey, string sortName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets latest items.
|
||||
/// </summary>
|
||||
/// <param name="request">Query to use.</param>
|
||||
/// <param name="options">Options to use.</param>
|
||||
/// <returns>Set of items.</returns>
|
||||
List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request, DtoOptions options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1711, CS1591
|
||||
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1721, CA1819, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -109,6 +109,21 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <value>The additional locations.</value>
|
||||
private List<string> AdditionalLocations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical locations.
|
||||
/// </summary>
|
||||
/// <value>The physical locations.</value>
|
||||
public string[] PhysicalLocations
|
||||
{
|
||||
get
|
||||
{
|
||||
var paths = string.IsNullOrEmpty(Path) ? Array.Empty<string>() : new[] { Path };
|
||||
return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public string CollectionType { get; set; }
|
||||
|
||||
public bool HasParent<T>()
|
||||
where T : Folder
|
||||
{
|
||||
@@ -138,6 +153,16 @@ namespace MediaBrowser.Controller.Library
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with the current object.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as ItemResolveArgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the additional location.
|
||||
/// </summary>
|
||||
@@ -156,19 +181,6 @@ namespace MediaBrowser.Controller.Library
|
||||
|
||||
// REVIEW: @bond
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical locations.
|
||||
/// </summary>
|
||||
/// <value>The physical locations.</value>
|
||||
public string[] PhysicalLocations
|
||||
{
|
||||
get
|
||||
{
|
||||
var paths = string.IsNullOrEmpty(Path) ? Array.Empty<string>() : new[] { Path };
|
||||
return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the file system entry by.
|
||||
/// </summary>
|
||||
@@ -190,7 +202,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>FileSystemInfo.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentNullException">Throws if path is invalid.</exception>
|
||||
public FileSystemMetadata GetFileSystemEntryByPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
@@ -224,18 +236,6 @@ namespace MediaBrowser.Controller.Library
|
||||
return CollectionType;
|
||||
}
|
||||
|
||||
public string CollectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with the current object.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as ItemResolveArgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -22,12 +22,22 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// </summary>
|
||||
public interface ILiveTvManager
|
||||
{
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled;
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated;
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the services.
|
||||
/// </summary>
|
||||
/// <value>The services.</value>
|
||||
IReadOnlyList<ILiveTvService> Services { get; }
|
||||
|
||||
IListingsProvider[] ListingProviders { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new timer defaults asynchronous.
|
||||
/// </summary>
|
||||
@@ -86,6 +96,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <returns>A recording.</returns>
|
||||
QueryResult<BaseItemDto> GetRecordings(RecordingQuery query, DtoOptions options);
|
||||
|
||||
/// <summary>
|
||||
@@ -176,11 +187,16 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Recommended programs.</returns>
|
||||
QueryResult<BaseItemDto> GetRecommendedPrograms(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the recommended programs internal.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Recommended programs.</returns>
|
||||
QueryResult<BaseItem> GetRecommendedProgramsInternal(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -202,6 +218,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// Gets the live tv folder.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Live TV folder.</returns>
|
||||
Folder GetInternalLiveTvFolder(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -213,11 +230,18 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// <summary>
|
||||
/// Gets the internal channels.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="dtoOptions">The options.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Internal channels.</returns>
|
||||
QueryResult<BaseItem> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to search for.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>Channel media sources wrapped in a task.</returns>
|
||||
Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(BaseItem item, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -232,6 +256,9 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// <summary>
|
||||
/// Saves the tuner host.
|
||||
/// </summary>
|
||||
/// <param name="info">Turner host to save.</param>
|
||||
/// <param name="dataSourceChanged">Option to specify that data source has changed.</param>
|
||||
/// <returns>Tuner host information wrapped in a task.</returns>
|
||||
Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true);
|
||||
|
||||
/// <summary>
|
||||
@@ -271,20 +298,10 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
|
||||
Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken);
|
||||
|
||||
IListingsProvider[] ListingProviders { get; }
|
||||
|
||||
List<NameIdPair> GetTunerHostTypes();
|
||||
|
||||
Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken);
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled;
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated;
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated;
|
||||
|
||||
string GetEmbyTvActiveRecordingPath(string id);
|
||||
|
||||
ActiveRecordingInfo GetActiveRecordingInfo(string path);
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// <summary>
|
||||
/// Gets the channels.
|
||||
/// </summary>
|
||||
/// <param name="enableCache">Option to enable using cache.</param>
|
||||
/// <param name="cancellationToken">The CancellationToken for this operation.</param>
|
||||
/// <returns>Task<IEnumerable<ChannelInfo>>.</returns>
|
||||
Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken);
|
||||
|
||||
@@ -47,6 +49,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// <param name="streamId">The stream identifier.</param>
|
||||
/// <param name="currentLiveStreams">The current live streams.</param>
|
||||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
|
||||
/// <returns>Live stream wrapped in a task.</returns>
|
||||
Task<ILiveStream> GetChannelStream(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -18,23 +18,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
public class LiveTvChannel : BaseItem, IHasMediaSources, IHasProgramAttributes
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (!ConfigurationManager.Configuration.DisableLiveTvChannelUserDataName)
|
||||
{
|
||||
list.Insert(0, GetClientTypeName() + "-" + Name);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.LiveTvChannel;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPositionTicksResume => false;
|
||||
|
||||
@@ -59,70 +42,9 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
[JsonIgnore]
|
||||
public override LocationType LocationType => LocationType.Remote;
|
||||
|
||||
protected override string CreateSortName()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Number))
|
||||
{
|
||||
double number = 0;
|
||||
|
||||
if (double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number))
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0:00000.0}", number) + "-" + (Name ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
return (Number ?? string.Empty) + "-" + (Name ?? string.Empty);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override string MediaType => ChannelType == ChannelType.Radio ? Model.Entities.MediaType.Audio : Model.Entities.MediaType.Video;
|
||||
|
||||
public override string GetClientTypeName()
|
||||
{
|
||||
return "TvChannel";
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
var list = new List<MediaSourceInfo>();
|
||||
|
||||
var info = new MediaSourceInfo
|
||||
{
|
||||
Id = Id.ToString("N", CultureInfo.InvariantCulture),
|
||||
Protocol = PathProtocol ?? MediaProtocol.File,
|
||||
MediaStreams = new List<MediaStream>(),
|
||||
Name = Name,
|
||||
Path = Path,
|
||||
RunTimeTicks = RunTimeTicks,
|
||||
Type = MediaSourceType.Placeholder,
|
||||
IsInfiniteStream = RunTimeTicks == null
|
||||
};
|
||||
|
||||
list.Add(info);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override List<MediaStream> GetMediaStreams()
|
||||
{
|
||||
return new List<MediaStream>();
|
||||
}
|
||||
|
||||
protected override string GetInternalMetadataPath(string basePath)
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N", CultureInfo.InvariantCulture), "metadata");
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsMovie { get; set; }
|
||||
|
||||
@@ -163,5 +85,83 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
/// <value>The episode title.</value>
|
||||
[JsonIgnore]
|
||||
public string EpisodeTitle { get; set; }
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (!ConfigurationManager.Configuration.DisableLiveTvChannelUserDataName)
|
||||
{
|
||||
list.Insert(0, GetClientTypeName() + "-" + Name);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.LiveTvChannel;
|
||||
}
|
||||
|
||||
protected override string CreateSortName()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Number))
|
||||
{
|
||||
double number = 0;
|
||||
|
||||
if (double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number))
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0:00000.0}", number) + "-" + (Name ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
return (Number ?? string.Empty) + "-" + (Name ?? string.Empty);
|
||||
}
|
||||
|
||||
public override string GetClientTypeName()
|
||||
{
|
||||
return "TvChannel";
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems()
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
var list = new List<MediaSourceInfo>();
|
||||
|
||||
var info = new MediaSourceInfo
|
||||
{
|
||||
Id = Id.ToString("N", CultureInfo.InvariantCulture),
|
||||
Protocol = PathProtocol ?? MediaProtocol.File,
|
||||
MediaStreams = new List<MediaStream>(),
|
||||
Name = Name,
|
||||
Path = Path,
|
||||
RunTimeTicks = RunTimeTicks,
|
||||
Type = MediaSourceType.Placeholder,
|
||||
IsInfiniteStream = RunTimeTicks == null
|
||||
};
|
||||
|
||||
list.Add(info);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override List<MediaStream> GetMediaStreams()
|
||||
{
|
||||
return new List<MediaStream>();
|
||||
}
|
||||
|
||||
protected override string GetInternalMetadataPath(string basePath)
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N", CultureInfo.InvariantCulture), "metadata");
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CS1591, SA1306
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -19,54 +19,14 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
public class LiveTvProgram : BaseItem, IHasLookupInfo<ItemLookupInfo>, IHasStartDate, IHasProgramAttributes
|
||||
{
|
||||
private static string EmbyServiceName = "Emby";
|
||||
|
||||
public LiveTvProgram()
|
||||
{
|
||||
IsVirtualItem = true;
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (!IsSeries)
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
key = this.GetProviderId(MetadataProvider.Tmdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(EpisodeTitle))
|
||||
{
|
||||
var name = GetClientTypeName();
|
||||
|
||||
list.Insert(0, name + "-" + Name + (EpisodeTitle ?? string.Empty));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static string EmbyServiceName = "Emby";
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
var serviceName = ServiceName;
|
||||
|
||||
if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 2.0 / 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 16.0 / 9;
|
||||
}
|
||||
}
|
||||
public string SeriesName { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public override SourceType SourceType => SourceType.LiveTV;
|
||||
@@ -182,6 +142,66 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
// Optimization
|
||||
if (IsNews || IsSports)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.SupportsPeople;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAncestors => false;
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (!IsSeries)
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
key = this.GetProviderId(MetadataProvider.Tmdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(EpisodeTitle))
|
||||
{
|
||||
var name = GetClientTypeName();
|
||||
|
||||
list.Insert(0, name + "-" + Name + (EpisodeTitle ?? string.Empty));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
var serviceName = ServiceName;
|
||||
|
||||
if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 2.0 / 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 16.0 / 9;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetClientTypeName()
|
||||
{
|
||||
return "Program";
|
||||
@@ -202,24 +222,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
return false;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
// Optimization
|
||||
if (IsNews || IsSports)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.SupportsPeople;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsAncestors => false;
|
||||
|
||||
private LiveTvOptions GetConfiguration()
|
||||
{
|
||||
return ConfigurationManager.GetConfiguration<LiveTvOptions>("livetv");
|
||||
@@ -273,7 +275,5 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public string SeriesName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,14 +35,15 @@
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release' ">true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode Condition=" '$(Configuration)' == 'Debug' ">AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release'">
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Stability)'=='Unstable'">
|
||||
|
||||
@@ -10,6 +10,15 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
public class BaseEncodingJobOptions
|
||||
{
|
||||
public BaseEncodingJobOptions()
|
||||
{
|
||||
EnableAutoStreamCopy = true;
|
||||
AllowVideoStreamCopy = true;
|
||||
AllowAudioStreamCopy = true;
|
||||
Context = EncodingContext.Streaming;
|
||||
StreamOptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
@@ -191,14 +200,5 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public BaseEncodingJobOptions()
|
||||
{
|
||||
EnableAutoStreamCopy = true;
|
||||
AllowVideoStreamCopy = true;
|
||||
AllowAudioStreamCopy = true;
|
||||
Context = EncodingContext.Streaming;
|
||||
StreamOptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,8 +143,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
|
||||
// Hybrid VPP tonemapping for QSV with VAAPI
|
||||
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
if (isLinux && string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
||||
if (OperatingSystem.IsLinux() && string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Limited to HEVC for now since the filter doesn't accept master data from VP9.
|
||||
return IsColorDepth10(state)
|
||||
@@ -162,6 +161,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Gets the name of the output video codec.
|
||||
/// </summary>
|
||||
/// <param name="state">Encording state.</param>
|
||||
/// <param name="encodingOptions">Encoding options.</param>
|
||||
/// <returns>Encoder string.</returns>
|
||||
public string GetVideoEncoder(EncodingJobInfo state, EncodingOptions encodingOptions)
|
||||
{
|
||||
var codec = state.OutputVideoCodec;
|
||||
@@ -316,6 +318,11 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
return container;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets decoder from a codec.
|
||||
/// </summary>
|
||||
/// <param name="codec">Codec to use.</param>
|
||||
/// <returns>Decoder string.</returns>
|
||||
public string GetDecoderFromCodec(string codec)
|
||||
{
|
||||
// For these need to find out the ffmpeg names
|
||||
@@ -345,6 +352,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Infers the audio codec based on the url.
|
||||
/// </summary>
|
||||
/// <param name="container">Container to use.</param>
|
||||
/// <returns>Codec string.</returns>
|
||||
public string InferAudioCodec(string container)
|
||||
{
|
||||
var ext = "." + (container ?? string.Empty);
|
||||
@@ -490,6 +499,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Gets the input argument.
|
||||
/// </summary>
|
||||
/// <param name="state">Encoding state.</param>
|
||||
/// <param name="encodingOptions">Encoding options.</param>
|
||||
/// <returns>Input arguments.</returns>
|
||||
public string GetInputArgument(EncodingJobInfo state, EncodingOptions encodingOptions)
|
||||
{
|
||||
var arg = new StringBuilder();
|
||||
@@ -503,9 +515,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
var isQsvEncoder = outputVideoCodec.IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
var isNvdecDecoder = videoDecoder.Contains("cuda", StringComparison.OrdinalIgnoreCase);
|
||||
var isCuvidHevcDecoder = videoDecoder.Contains("hevc_cuvid", StringComparison.OrdinalIgnoreCase);
|
||||
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
var isMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||
var isWindows = OperatingSystem.IsWindows();
|
||||
var isLinux = OperatingSystem.IsLinux();
|
||||
var isMacOS = OperatingSystem.IsMacOS();
|
||||
var isTonemappingSupported = IsTonemappingSupported(state, encodingOptions);
|
||||
var isVppTonemappingSupported = IsVppTonemappingSupported(state, encodingOptions);
|
||||
|
||||
@@ -966,6 +978,11 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Gets the video bitrate to specify on the command line.
|
||||
/// </summary>
|
||||
/// <param name="state">Encoding state.</param>
|
||||
/// <param name="videoEncoder">Video encoder to use.</param>
|
||||
/// <param name="encodingOptions">Encoding options.</param>
|
||||
/// <param name="defaultPreset">Default present to use for encoding.</param>
|
||||
/// <returns>Video bitrate.</returns>
|
||||
public string GetVideoQualityParam(EncodingJobInfo state, string videoEncoder, EncodingOptions encodingOptions, string defaultPreset)
|
||||
{
|
||||
var param = string.Empty;
|
||||
@@ -1692,7 +1709,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
return 128000;
|
||||
}
|
||||
|
||||
public string GetAudioFilterParam(EncodingJobInfo state, EncodingOptions encodingOptions, bool isHls)
|
||||
public string GetAudioFilterParam(EncodingJobInfo state, EncodingOptions encodingOptions)
|
||||
{
|
||||
var channels = state.OutputAudioChannels;
|
||||
|
||||
@@ -1967,8 +1984,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the graphical subtitle param.
|
||||
/// Gets the graphical subtitle parameter.
|
||||
/// </summary>
|
||||
/// <param name="state">Encoding state.</param>
|
||||
/// <param name="options">Encoding options.</param>
|
||||
/// <param name="outputVideoCodec">Video codec to use.</param>
|
||||
/// <returns>Graphical subtitle parameter.</returns>
|
||||
public string GetGraphicalSubtitleParam(
|
||||
EncodingJobInfo state,
|
||||
EncodingOptions options,
|
||||
@@ -1983,7 +2004,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
var videoSizeParam = string.Empty;
|
||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options) ?? string.Empty;
|
||||
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
var isLinux = OperatingSystem.IsLinux();
|
||||
|
||||
var isVaapiDecoder = videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
var isVaapiH264Encoder = outputVideoCodec.IndexOf("h264_vaapi", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
@@ -2486,6 +2507,13 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
return string.Format(CultureInfo.InvariantCulture, filter, widthParam, heightParam);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output size parameter.
|
||||
/// </summary>
|
||||
/// <param name="state">Encoding state.</param>
|
||||
/// <param name="options">Encoding options.</param>
|
||||
/// <param name="outputVideoCodec">Video codec to use.</param>
|
||||
/// <returns>The output size parameter.</returns>
|
||||
public string GetOutputSizeParam(
|
||||
EncodingJobInfo state,
|
||||
EncodingOptions options,
|
||||
@@ -2496,8 +2524,13 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output size parameter.
|
||||
/// If we're going to put a fixed size on the command line, this will calculate it.
|
||||
/// </summary>
|
||||
/// <param name="state">Encoding state.</param>
|
||||
/// <param name="options">Encoding options.</param>
|
||||
/// <param name="outputVideoCodec">Video codec to use.</param>
|
||||
/// <returns>The output size parameter.</returns>
|
||||
public string GetOutputSizeParamInternal(
|
||||
EncodingJobInfo state,
|
||||
EncodingOptions options,
|
||||
@@ -2528,7 +2561,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
var isCuvidHevcDecoder = videoDecoder.Contains("hevc_cuvid", StringComparison.OrdinalIgnoreCase);
|
||||
var isLibX264Encoder = outputVideoCodec.IndexOf("libx264", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
var isLibX265Encoder = outputVideoCodec.IndexOf("libx265", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
var isLinux = OperatingSystem.IsLinux();
|
||||
var isColorDepth10 = IsColorDepth10(state);
|
||||
var isTonemappingSupported = IsTonemappingSupported(state, options);
|
||||
var isVppTonemappingSupported = IsVppTonemappingSupported(state, options);
|
||||
@@ -2909,6 +2942,10 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Gets the number of threads.
|
||||
/// </summary>
|
||||
/// <param name="state">Encoding state.</param>
|
||||
/// <param name="encodingOptions">Encoding options.</param>
|
||||
/// <param name="outputVideoCodec">Video codec to use.</param>
|
||||
/// <returns>Number of threads.</returns>
|
||||
#nullable enable
|
||||
public static int GetNumberOfThreads(EncodingJobInfo? state, EncodingOptions encodingOptions, string? outputVideoCodec)
|
||||
{
|
||||
@@ -3552,6 +3589,11 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Gets a hw decoder name.
|
||||
/// </summary>
|
||||
/// <param name="options">Encoding options.</param>
|
||||
/// <param name="decoder">Decoder to use.</param>
|
||||
/// <param name="videoCodec">Video codec to use.</param>
|
||||
/// <param name="isColorDepth10">Specifies if color depth 10.</param>
|
||||
/// <returns>Hardware decoder name.</returns>
|
||||
public string GetHwDecoderName(EncodingOptions options, string decoder, string videoCodec, bool isColorDepth10)
|
||||
{
|
||||
var isCodecAvailable = _mediaEncoder.SupportsDecoder(decoder) && options.HardwareDecodingCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase);
|
||||
@@ -3570,10 +3612,15 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Gets a hwaccel type to use as a hardware decoder(dxva/vaapi) depending on the system.
|
||||
/// </summary>
|
||||
/// <param name="state">Encoding state.</param>
|
||||
/// <param name="options">Encoding options.</param>
|
||||
/// <param name="videoCodec">Video codec to use.</param>
|
||||
/// <param name="isColorDepth10">Specifies if color depth 10.</param>
|
||||
/// <returns>Hardware accelerator type.</returns>
|
||||
public string GetHwaccelType(EncodingJobInfo state, EncodingOptions options, string videoCodec, bool isColorDepth10)
|
||||
{
|
||||
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
var isWindows = OperatingSystem.IsWindows();
|
||||
var isLinux = OperatingSystem.IsLinux();
|
||||
var isWindows8orLater = Environment.OSVersion.Version.Major > 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor > 1);
|
||||
var isDxvaSupported = _mediaEncoder.SupportsHwaccel("dxva2") || _mediaEncoder.SupportsHwaccel("d3d11va");
|
||||
var isCodecAvailable = options.HardwareDecodingCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase);
|
||||
@@ -3836,7 +3883,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
args += " -ar " + state.OutputAudioSampleRate.Value.ToString(_usCulture);
|
||||
}
|
||||
|
||||
args += GetAudioFilterParam(state, encodingOptions, false);
|
||||
args += GetAudioFilterParam(state, encodingOptions);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CS1591, SA1401
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -20,6 +20,44 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
// For now, a common base class until the API and MediaEncoding classes are unified
|
||||
public class EncodingJobInfo
|
||||
{
|
||||
public int? OutputAudioBitrate;
|
||||
public int? OutputAudioChannels;
|
||||
|
||||
private TranscodeReason[] _transcodeReasons = null;
|
||||
|
||||
public EncodingJobInfo(TranscodingJobType jobType)
|
||||
{
|
||||
TranscodingType = jobType;
|
||||
RemoteHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
SupportedAudioCodecs = Array.Empty<string>();
|
||||
SupportedVideoCodecs = Array.Empty<string>();
|
||||
SupportedSubtitleCodecs = Array.Empty<string>();
|
||||
}
|
||||
|
||||
public TranscodeReason[] TranscodeReasons
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_transcodeReasons == null)
|
||||
{
|
||||
if (BaseRequest.TranscodeReasons == null)
|
||||
{
|
||||
return Array.Empty<TranscodeReason>();
|
||||
}
|
||||
|
||||
_transcodeReasons = BaseRequest.TranscodeReasons
|
||||
.Split(',')
|
||||
.Where(i => !string.IsNullOrEmpty(i))
|
||||
.Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return _transcodeReasons;
|
||||
}
|
||||
}
|
||||
|
||||
public IProgress<double> Progress { get; set; }
|
||||
|
||||
public MediaStream VideoStream { get; set; }
|
||||
|
||||
public VideoType VideoType { get; set; }
|
||||
@@ -58,40 +96,6 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
public string MimeType { get; set; }
|
||||
|
||||
public string GetMimeType(string outputPath, bool enableStreamDefault = true)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(MimeType))
|
||||
{
|
||||
return MimeType;
|
||||
}
|
||||
|
||||
return MimeTypes.GetMimeType(outputPath, enableStreamDefault);
|
||||
}
|
||||
|
||||
private TranscodeReason[] _transcodeReasons = null;
|
||||
|
||||
public TranscodeReason[] TranscodeReasons
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_transcodeReasons == null)
|
||||
{
|
||||
if (BaseRequest.TranscodeReasons == null)
|
||||
{
|
||||
return Array.Empty<TranscodeReason>();
|
||||
}
|
||||
|
||||
_transcodeReasons = BaseRequest.TranscodeReasons
|
||||
.Split(',')
|
||||
.Where(i => !string.IsNullOrEmpty(i))
|
||||
.Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return _transcodeReasons;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IgnoreInputDts => MediaSource.IgnoreDts;
|
||||
|
||||
public bool IgnoreInputIndex => MediaSource.IgnoreIndex;
|
||||
@@ -144,196 +148,17 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
public BaseEncodingJobOptions BaseRequest { get; set; }
|
||||
|
||||
public long? StartTimeTicks => BaseRequest.StartTimeTicks;
|
||||
|
||||
public bool CopyTimestamps => BaseRequest.CopyTimestamps;
|
||||
|
||||
public int? OutputAudioBitrate;
|
||||
public int? OutputAudioChannels;
|
||||
|
||||
public bool DeInterlace(string videoCodec, bool forceDeinterlaceIfSourceIsInterlaced)
|
||||
{
|
||||
var videoStream = VideoStream;
|
||||
var isInputInterlaced = videoStream != null && videoStream.IsInterlaced;
|
||||
|
||||
if (!isInputInterlaced)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Support general param
|
||||
if (BaseRequest.DeInterlace)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(videoCodec))
|
||||
{
|
||||
if (string.Equals(BaseRequest.GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return forceDeinterlaceIfSourceIsInterlaced && isInputInterlaced;
|
||||
}
|
||||
|
||||
public string[] GetRequestedProfiles(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BaseRequest.Profile))
|
||||
{
|
||||
return BaseRequest.Profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var profile = BaseRequest.GetOption(codec, "profile");
|
||||
|
||||
if (!string.IsNullOrEmpty(profile))
|
||||
{
|
||||
return profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
public string GetRequestedLevel(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BaseRequest.Level))
|
||||
{
|
||||
return BaseRequest.Level;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
return BaseRequest.GetOption(codec, "level");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedMaxRefFrames(string codec)
|
||||
{
|
||||
if (BaseRequest.MaxRefFrames.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxRefFrames;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "maxrefframes");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedVideoBitDepth(string codec)
|
||||
{
|
||||
if (BaseRequest.MaxVideoBitDepth.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxVideoBitDepth;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "videobitdepth");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedAudioBitDepth(string codec)
|
||||
{
|
||||
if (BaseRequest.MaxAudioBitDepth.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxAudioBitDepth;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "audiobitdepth");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedAudioChannels(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "audiochannels");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (BaseRequest.MaxAudioChannels.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxAudioChannels;
|
||||
}
|
||||
|
||||
if (BaseRequest.AudioChannels.HasValue)
|
||||
{
|
||||
return BaseRequest.AudioChannels;
|
||||
}
|
||||
|
||||
if (BaseRequest.TranscodingMaxAudioChannels.HasValue)
|
||||
{
|
||||
return BaseRequest.TranscodingMaxAudioChannels;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsVideoRequest { get; set; }
|
||||
|
||||
public TranscodingJobType TranscodingType { get; set; }
|
||||
|
||||
public EncodingJobInfo(TranscodingJobType jobType)
|
||||
{
|
||||
TranscodingType = jobType;
|
||||
RemoteHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
SupportedAudioCodecs = Array.Empty<string>();
|
||||
SupportedVideoCodecs = Array.Empty<string>();
|
||||
SupportedSubtitleCodecs = Array.Empty<string>();
|
||||
}
|
||||
public long? StartTimeTicks => BaseRequest.StartTimeTicks;
|
||||
|
||||
public bool CopyTimestamps => BaseRequest.CopyTimestamps;
|
||||
|
||||
public bool IsSegmentedLiveStream
|
||||
=> TranscodingType != TranscodingJobType.Progressive && !RunTimeTicks.HasValue;
|
||||
|
||||
public bool EnableBreakOnNonKeyFrames(string videoCodec)
|
||||
{
|
||||
if (TranscodingType != TranscodingJobType.Progressive)
|
||||
{
|
||||
if (IsSegmentedLiveStream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return BaseRequest.BreakOnNonKeyFrames && EncodingHelper.IsCopyCodec(videoCodec);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int? TotalOutputBitrate => (OutputAudioBitrate ?? 0) + (OutputVideoBitrate ?? 0);
|
||||
|
||||
public int? OutputWidth
|
||||
@@ -682,6 +507,21 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
public int HlsListSize => 0;
|
||||
|
||||
public bool EnableBreakOnNonKeyFrames(string videoCodec)
|
||||
{
|
||||
if (TranscodingType != TranscodingJobType.Progressive)
|
||||
{
|
||||
if (IsSegmentedLiveStream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return BaseRequest.BreakOnNonKeyFrames && EncodingHelper.IsCopyCodec(videoCodec);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int? GetMediaStreamCount(MediaStreamType type, int limit)
|
||||
{
|
||||
var count = MediaSource.GetStreamCount(type);
|
||||
@@ -694,7 +534,167 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
return count;
|
||||
}
|
||||
|
||||
public IProgress<double> Progress { get; set; }
|
||||
public string GetMimeType(string outputPath, bool enableStreamDefault = true)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(MimeType))
|
||||
{
|
||||
return MimeType;
|
||||
}
|
||||
|
||||
return MimeTypes.GetMimeType(outputPath, enableStreamDefault);
|
||||
}
|
||||
|
||||
public bool DeInterlace(string videoCodec, bool forceDeinterlaceIfSourceIsInterlaced)
|
||||
{
|
||||
var videoStream = VideoStream;
|
||||
var isInputInterlaced = videoStream != null && videoStream.IsInterlaced;
|
||||
|
||||
if (!isInputInterlaced)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Support general param
|
||||
if (BaseRequest.DeInterlace)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(videoCodec))
|
||||
{
|
||||
if (string.Equals(BaseRequest.GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return forceDeinterlaceIfSourceIsInterlaced && isInputInterlaced;
|
||||
}
|
||||
|
||||
public string[] GetRequestedProfiles(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BaseRequest.Profile))
|
||||
{
|
||||
return BaseRequest.Profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var profile = BaseRequest.GetOption(codec, "profile");
|
||||
|
||||
if (!string.IsNullOrEmpty(profile))
|
||||
{
|
||||
return profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
public string GetRequestedLevel(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BaseRequest.Level))
|
||||
{
|
||||
return BaseRequest.Level;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
return BaseRequest.GetOption(codec, "level");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedMaxRefFrames(string codec)
|
||||
{
|
||||
if (BaseRequest.MaxRefFrames.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxRefFrames;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "maxrefframes");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedVideoBitDepth(string codec)
|
||||
{
|
||||
if (BaseRequest.MaxVideoBitDepth.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxVideoBitDepth;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "videobitdepth");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedAudioBitDepth(string codec)
|
||||
{
|
||||
if (BaseRequest.MaxAudioBitDepth.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxAudioBitDepth;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "audiobitdepth");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetRequestedAudioChannels(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var value = BaseRequest.GetOption(codec, "audiochannels");
|
||||
if (!string.IsNullOrEmpty(value)
|
||||
&& int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (BaseRequest.MaxAudioChannels.HasValue)
|
||||
{
|
||||
return BaseRequest.MaxAudioChannels;
|
||||
}
|
||||
|
||||
if (BaseRequest.AudioChannels.HasValue)
|
||||
{
|
||||
return BaseRequest.AudioChannels;
|
||||
}
|
||||
|
||||
if (BaseRequest.TranscodingMaxAudioChannels.HasValue)
|
||||
{
|
||||
return BaseRequest.TranscodingMaxAudioChannels;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,13 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Refreshes the chapter images.
|
||||
/// </summary>
|
||||
/// <param name="video">Video to use.</param>
|
||||
/// <param name="directoryService">Directory service to use.</param>
|
||||
/// <param name="chapters">Set of chapters to refresh.</param>
|
||||
/// <param name="extractImages">Option to extract images.</param>
|
||||
/// <param name="saveChapters">Option to save chapters.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns><c>true</c> if successful, <c>false</c> if not.</returns>
|
||||
Task<bool> RefreshChapterImages(Video video, IDirectoryService directoryService, IReadOnlyList<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,13 +71,42 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Extracts the video image.
|
||||
/// </summary>
|
||||
/// <param name="inputFile">Input file.</param>
|
||||
/// <param name="container">Video container type.</param>
|
||||
/// <param name="mediaSource">Media source information.</param>
|
||||
/// <param name="videoStream">Media stream information.</param>
|
||||
/// <param name="threedFormat">Video 3D format.</param>
|
||||
/// <param name="offset">Time offset.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>Location of video image.</returns>
|
||||
Task<string> ExtractVideoImage(string inputFile, string container, MediaSourceInfo mediaSource, MediaStream videoStream, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the video image.
|
||||
/// </summary>
|
||||
/// <param name="inputFile">Input file.</param>
|
||||
/// <param name="container">Video container type.</param>
|
||||
/// <param name="mediaSource">Media source information.</param>
|
||||
/// <param name="imageStream">Media stream information.</param>
|
||||
/// <param name="imageStreamIndex">Index of the stream to extract from.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>Location of video image.</returns>
|
||||
Task<string> ExtractVideoImage(string inputFile, string container, MediaSourceInfo mediaSource, MediaStream imageStream, int? imageStreamIndex, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the video images on interval.
|
||||
/// </summary>
|
||||
/// <param name="inputFile">Input file.</param>
|
||||
/// <param name="container">Video container type.</param>
|
||||
/// <param name="videoStream">Media stream information.</param>
|
||||
/// <param name="mediaSource">Media source information.</param>
|
||||
/// <param name="threedFormat">Video 3D format.</param>
|
||||
/// <param name="interval">Time interval.</param>
|
||||
/// <param name="targetDirectory">Directory to write images.</param>
|
||||
/// <param name="filenamePrefix">Filename prefix to use.</param>
|
||||
/// <param name="maxWidth">Maximum width of image.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>A task.</returns>
|
||||
Task ExtractVideoImagesOnInterval(
|
||||
string inputFile,
|
||||
string container,
|
||||
@@ -122,10 +151,24 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <returns>System.String.</returns>
|
||||
string EscapeSubtitleFilterPath(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the path to find FFmpeg.
|
||||
/// </summary>
|
||||
void SetFFmpegPath();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the encoder path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="pathType">The type of path.</param>
|
||||
void UpdateEncoderPath(string path, string pathType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the primary playlist of .vob files.
|
||||
/// </summary>
|
||||
/// <param name="path">The to the .vob files.</param>
|
||||
/// <param name="titleNumber">The title number to start with.</param>
|
||||
/// <returns>A playlist.</returns>
|
||||
IEnumerable<string> GetPrimaryPlaylistVobFiles(string path, uint? titleNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,14 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Gets the subtitles.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="mediaSourceId">Media source.</param>
|
||||
/// <param name="subtitleStreamIndex">Subtitle stream to use.</param>
|
||||
/// <param name="outputFormat">Output format to use.</param>
|
||||
/// <param name="startTimeTicks">Start time.</param>
|
||||
/// <param name="endTimeTicks">End time.</param>
|
||||
/// <param name="preserveOriginalTimestamps">Option to preserve original timestamps.</param>
|
||||
/// <param name="cancellationToken">The cancellation token for the operation.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<Stream> GetSubtitles(
|
||||
BaseItem item,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA1819, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// <summary>
|
||||
/// Queues the refresh.
|
||||
/// </summary>
|
||||
/// <param name="itemId">Item ID.</param>
|
||||
/// <param name="options">MetadataRefreshOptions for operation.</param>
|
||||
/// <param name="priority">RefreshPriority for operation.</param>
|
||||
void QueueRefresh(Guid itemId, MetadataRefreshOptions options, RefreshPriority priority);
|
||||
|
||||
/// <summary>
|
||||
@@ -85,6 +88,13 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// <summary>
|
||||
/// Saves the image.
|
||||
/// </summary>
|
||||
/// <param name="item">Image to save.</param>
|
||||
/// <param name="source">Source of image.</param>
|
||||
/// <param name="mimeType">Mime type image.</param>
|
||||
/// <param name="type">Type of image.</param>
|
||||
/// <param name="imageIndex">Index of image.</param>
|
||||
/// <param name="saveLocallyWithMedia">Option to save locally.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use with operation.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken);
|
||||
|
||||
@@ -93,6 +103,11 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// <summary>
|
||||
/// Adds the metadata providers.
|
||||
/// </summary>
|
||||
/// <param name="imageProviders">Image providers to use.</param>
|
||||
/// <param name="metadataServices">Metadata services to use.</param>
|
||||
/// <param name="metadataProviders">Metadata providers to use.</param>
|
||||
/// <param name="metadataSavers">Metadata savers to use.</param>
|
||||
/// <param name="externalIds">External IDs to use.</param>
|
||||
void AddParts(
|
||||
IEnumerable<IImageProvider> imageProviders,
|
||||
IEnumerable<IMetadataService> metadataServices,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
@@ -10,6 +10,15 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class ImageRefreshOptions
|
||||
{
|
||||
public ImageRefreshOptions(IDirectoryService directoryService)
|
||||
{
|
||||
ImageRefreshMode = MetadataRefreshMode.Default;
|
||||
DirectoryService = directoryService;
|
||||
|
||||
ReplaceImages = Array.Empty<ImageType>();
|
||||
IsAutomated = true;
|
||||
}
|
||||
|
||||
public MetadataRefreshMode ImageRefreshMode { get; set; }
|
||||
|
||||
public IDirectoryService DirectoryService { get; private set; }
|
||||
@@ -20,15 +29,6 @@ namespace MediaBrowser.Controller.Providers
|
||||
|
||||
public bool IsAutomated { get; set; }
|
||||
|
||||
public ImageRefreshOptions(IDirectoryService directoryService)
|
||||
{
|
||||
ImageRefreshMode = MetadataRefreshMode.Default;
|
||||
DirectoryService = directoryService;
|
||||
|
||||
ReplaceImages = Array.Empty<ImageType>();
|
||||
IsAutomated = true;
|
||||
}
|
||||
|
||||
public bool IsReplacingImage(ImageType type)
|
||||
{
|
||||
return ImageRefreshMode == MetadataRefreshMode.FullRefresh &&
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original title
|
||||
/// Gets or sets the original title.
|
||||
/// </summary>
|
||||
/// <value>The original title of the item.</value>
|
||||
public string OriginalTitle { get; set; }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1819, CS1591
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -9,16 +9,16 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class SongInfo : ItemLookupInfo
|
||||
{
|
||||
public IReadOnlyList<string> AlbumArtists { get; set; }
|
||||
|
||||
public string Album { get; set; }
|
||||
|
||||
public IReadOnlyList<string> Artists { get; set; }
|
||||
|
||||
public SongInfo()
|
||||
{
|
||||
Artists = Array.Empty<string>();
|
||||
AlbumArtists = Array.Empty<string>();
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> AlbumArtists { get; set; }
|
||||
|
||||
public string Album { get; set; }
|
||||
|
||||
public IReadOnlyList<string> Artists { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ namespace MediaBrowser.Controller.Session
|
||||
/// <summary>
|
||||
/// Sends the message.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data.</typeparam>
|
||||
/// <param name="name">Name of message type.</param>
|
||||
/// <param name="messageId">Message ID.</param>
|
||||
/// <param name="data">Data to send.</param>
|
||||
/// <param name="cancellationToken">CancellationToken for operation.</param>
|
||||
/// <returns>A task.</returns>
|
||||
Task SendMessage<T>(SessionMessageType name, Guid messageId, T data, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace MediaBrowser.Controller.Session
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="remoteEndPoint">The remote end point.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>A task containing the session information.</returns>
|
||||
Task<SessionInfo> LogSessionActivity(string appName, string appVersion, string deviceId, string deviceName, string remoteEndPoint, Jellyfin.Data.Entities.User user);
|
||||
|
||||
/// <summary>
|
||||
@@ -106,7 +107,7 @@ namespace MediaBrowser.Controller.Session
|
||||
/// </summary>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentNullException">Throws if an argument is null.</exception>
|
||||
Task OnPlaybackProgress(PlaybackProgressInfo info);
|
||||
|
||||
Task OnPlaybackProgress(PlaybackProgressInfo info, bool isAutomated);
|
||||
@@ -116,14 +117,13 @@ namespace MediaBrowser.Controller.Session
|
||||
/// </summary>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentNullException">Throws if an argument is null.</exception>
|
||||
Task OnPlaybackStopped(PlaybackStopInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Reports the session ended.
|
||||
/// </summary>
|
||||
/// <param name="sessionId">The session identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void ReportSessionEnded(string sessionId);
|
||||
|
||||
/// <summary>
|
||||
@@ -171,6 +171,7 @@ namespace MediaBrowser.Controller.Session
|
||||
/// <param name="session">The session.</param>
|
||||
/// <param name="command">The group update.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <typeparam name="T">Type of group.</typeparam>
|
||||
/// <returns>Task.</returns>
|
||||
Task SendSyncPlayGroupUpdate<T>(SessionInfo session, GroupUpdate<T> command, CancellationToken cancellationToken);
|
||||
|
||||
@@ -197,8 +198,8 @@ namespace MediaBrowser.Controller.Session
|
||||
/// <summary>
|
||||
/// Sends the message to admin sessions.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <typeparam name="T">Type of data.</typeparam>
|
||||
/// <param name="name">Message type name.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
@@ -207,18 +208,31 @@ namespace MediaBrowser.Controller.Session
|
||||
/// <summary>
|
||||
/// Sends the message to user sessions.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="T">Type of data.</typeparam>
|
||||
/// <param name="userIds">Users to send messages to.</param>
|
||||
/// <param name="name">Message type name.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SendMessageToUserSessions<T>(List<Guid> userIds, SessionMessageType name, T data, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Sends the message to user sessions.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of data.</typeparam>
|
||||
/// <param name="userIds">Users to send messages to.</param>
|
||||
/// <param name="name">Message type name.</param>
|
||||
/// <param name="dataFn">Data function.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SendMessageToUserSessions<T>(List<Guid> userIds, SessionMessageType name, Func<T> dataFn, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Sends the message to user device sessions.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="T">Type of data.</typeparam>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="name">Message type name.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
@@ -337,6 +351,7 @@ namespace MediaBrowser.Controller.Session
|
||||
/// </summary>
|
||||
/// <param name="userId">The user's id.</param>
|
||||
/// <param name="currentAccessToken">The current access token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RevokeUserTokens(Guid userId, string currentAccessToken);
|
||||
|
||||
void CloseIfNeeded(SessionInfo session);
|
||||
|
||||
Reference in New Issue
Block a user