aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Drawing/IImageEncoder.cs4
-rw-r--r--MediaBrowser.Controller/Drawing/IImageProcessor.cs6
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicGenre.cs2
-rw-r--r--MediaBrowser.Controller/Entities/BaseItemExtensions.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs13
-rw-r--r--MediaBrowser.Controller/Entities/Genre.cs8
-rw-r--r--MediaBrowser.Controller/Entities/InternalPeopleQuery.cs5
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs10
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs36
-rw-r--r--MediaBrowser.Controller/IDisplayPreferencesManager.cs6
-rw-r--r--MediaBrowser.Controller/IServerApplicationHost.cs19
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs5
-rw-r--r--MediaBrowser.Controller/Library/IMediaSourceManager.cs2
-rw-r--r--MediaBrowser.Controller/Library/IUserManager.cs9
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj4
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs290
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs11
-rw-r--r--MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs3
-rw-r--r--MediaBrowser.Controller/Net/AuthorizationInfo.cs18
-rw-r--r--MediaBrowser.Controller/Net/IWebSocketManager.cs6
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs4
-rw-r--r--MediaBrowser.Controller/Resolvers/IItemResolver.cs3
-rw-r--r--MediaBrowser.Controller/Subtitles/ISubtitleManager.cs9
24 files changed, 302 insertions, 176 deletions
diff --git a/MediaBrowser.Controller/Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
index f9b2e6fef..770c6dc2d 100644
--- a/MediaBrowser.Controller/Drawing/IImageEncoder.cs
+++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
@@ -1,4 +1,5 @@
#pragma warning disable CS1591
+#nullable enable
using System;
using System.Collections.Generic;
@@ -63,6 +64,7 @@ namespace MediaBrowser.Controller.Drawing
/// Create an image collage.
/// </summary>
/// <param name="options">The options to use when creating the collage.</param>
- void CreateImageCollage(ImageCollageOptions options);
+ /// <param name="libraryName">Optional. </param>
+ void CreateImageCollage(ImageCollageOptions options, string? libraryName);
}
}
diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
index b7edb1052..935a79031 100644
--- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs
+++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
@@ -1,4 +1,5 @@
#pragma warning disable CS1591
+#nullable enable
using System;
using System.Collections.Generic;
@@ -75,7 +76,7 @@ namespace MediaBrowser.Controller.Drawing
/// </summary>
/// <param name="options">The options.</param>
/// <returns>Task.</returns>
- Task<(string path, string mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options);
+ Task<(string path, string? mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options);
/// <summary>
/// Gets the supported image output formats.
@@ -87,7 +88,8 @@ namespace MediaBrowser.Controller.Drawing
/// Creates the image collage.
/// </summary>
/// <param name="options">The options.</param>
- void CreateImageCollage(ImageCollageOptions options);
+ /// <param name="libraryName">The library name to draw onto the collage.</param>
+ void CreateImageCollage(ImageCollageOptions options, string? libraryName);
bool SupportsTransparency(string path);
}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 397a68ff7..c5e50cf45 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -56,7 +56,7 @@ namespace MediaBrowser.Controller.Entities.Audio
{
if (query.IncludeItemTypes.Length == 0)
{
- query.IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name };
+ query.IncludeItemTypes = new[] { nameof(Audio), nameof(MusicVideo), nameof(MusicAlbum) };
query.ArtistIds = new[] { Id };
}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
index 5a117a6b1..f0c076108 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
@@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Entities.Audio
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.GenreIds = new[] { Id };
- query.IncludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
+ query.IncludeItemTypes = new[] { nameof(MusicVideo), nameof(Audio), nameof(MusicAlbum), nameof(MusicArtist) };
return LibraryManager.GetItemList(query);
}
diff --git a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs
index 8a69971d0..c65477d39 100644
--- a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs
+++ b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs
@@ -45,7 +45,8 @@ namespace MediaBrowser.Controller.Entities
{
if (file.StartsWith("http", System.StringComparison.OrdinalIgnoreCase))
{
- item.SetImage(new ItemImageInfo
+ item.SetImage(
+ new ItemImageInfo
{
Path = file,
Type = imageType
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 901ea875b..a76c8a376 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -255,7 +255,8 @@ namespace MediaBrowser.Controller.Entities
var id = child.Id;
if (dictionary.ContainsKey(id))
{
- Logger.LogError("Found folder containing items with duplicate id. Path: {path}, Child Name: {ChildName}",
+ Logger.LogError(
+ "Found folder containing items with duplicate id. Path: {path}, Child Name: {ChildName}",
Path ?? Name,
child.Path ?? child.Name);
}
@@ -722,7 +723,7 @@ namespace MediaBrowser.Controller.Entities
private bool RequiresPostFiltering2(InternalItemsQuery query)
{
- if (query.IncludeItemTypes.Length == 1 && string.Equals(query.IncludeItemTypes[0], typeof(BoxSet).Name, StringComparison.OrdinalIgnoreCase))
+ if (query.IncludeItemTypes.Length == 1 && string.Equals(query.IncludeItemTypes[0], nameof(BoxSet), StringComparison.OrdinalIgnoreCase))
{
Logger.LogDebug("Query requires post-filtering due to BoxSet query");
return true;
@@ -812,7 +813,7 @@ namespace MediaBrowser.Controller.Entities
if (query.IsPlayed.HasValue)
{
- if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes.Contains(typeof(Series).Name))
+ if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes.Contains(nameof(Series)))
{
Logger.LogDebug("Query requires post-filtering due to IsPlayed");
return true;
@@ -984,7 +985,8 @@ namespace MediaBrowser.Controller.Entities
return items;
}
- private static bool CollapseBoxSetItems(InternalItemsQuery query,
+ private static bool CollapseBoxSetItems(
+ InternalItemsQuery query,
BaseItem queryParent,
User user,
IServerConfigurationManager configurationManager)
@@ -1593,7 +1595,8 @@ namespace MediaBrowser.Controller.Entities
/// <param name="datePlayed">The date played.</param>
/// <param name="resetPosition">if set to <c>true</c> [reset position].</param>
/// <returns>Task.</returns>
- public override void MarkPlayed(User user,
+ public override void MarkPlayed(
+ User user,
DateTime? datePlayed,
bool resetPosition)
{
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
index db6c85caf..74a170204 100644
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ b/MediaBrowser.Controller/Entities/Genre.cs
@@ -59,7 +59,13 @@ namespace MediaBrowser.Controller.Entities
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.GenreIds = new[] { Id };
- query.ExcludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio.Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
+ query.ExcludeItemTypes = new[]
+ {
+ nameof(MusicVideo),
+ nameof(Entities.Audio.Audio),
+ nameof(MusicAlbum),
+ nameof(MusicArtist)
+ };
return LibraryManager.GetItemList(query);
}
diff --git a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs
index 4e09ee573..5b96a5af6 100644
--- a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs
@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System;
+using Jellyfin.Data.Entities;
namespace MediaBrowser.Controller.Entities
{
@@ -23,6 +24,10 @@ namespace MediaBrowser.Controller.Entities
public string NameContains { get; set; }
+ public User User { get; set; }
+
+ public bool? IsFavorite { get; set; }
+
public InternalPeopleQuery()
{
PersonTypes = Array.Empty<string>();
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 75a746bfb..e8afa9a49 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -151,7 +151,7 @@ namespace MediaBrowser.Controller.Entities.TV
if (query.IncludeItemTypes.Length == 0)
{
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
+ query.IncludeItemTypes = new[] { nameof(Episode) };
}
query.IsVirtualItem = false;
@@ -207,7 +207,7 @@ namespace MediaBrowser.Controller.Entities.TV
query.AncestorWithPresentationUniqueKey = null;
query.SeriesPresentationUniqueKey = seriesKey;
- query.IncludeItemTypes = new[] { typeof(Season).Name };
+ query.IncludeItemTypes = new[] { nameof(Season) };
query.OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray();
if (user != null && !user.DisplayMissingEpisodes)
@@ -233,7 +233,7 @@ namespace MediaBrowser.Controller.Entities.TV
if (query.IncludeItemTypes.Length == 0)
{
- query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
+ query.IncludeItemTypes = new[] { nameof(Episode), nameof(Season) };
}
query.IsVirtualItem = false;
@@ -253,7 +253,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey,
- IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
+ IncludeItemTypes = new[] { nameof(Episode), nameof(Season) },
OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
};
@@ -364,7 +364,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
AncestorWithPresentationUniqueKey = queryFromSeries ? null : seriesKey,
SeriesPresentationUniqueKey = queryFromSeries ? seriesKey : null,
- IncludeItemTypes = new[] { typeof(Episode).Name },
+ IncludeItemTypes = new[] { nameof(Episode) },
OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
};
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 068a76769..a262fee15 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -142,7 +142,7 @@ namespace MediaBrowser.Controller.Entities
if (query.IncludeItemTypes.Length == 0)
{
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
+ query.IncludeItemTypes = new[] { nameof(Movie) };
}
return parent.QueryRecursive(query);
@@ -167,7 +167,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
+ query.IncludeItemTypes = new[] { nameof(Movie) };
return _libraryManager.GetItemsResult(query);
}
@@ -178,7 +178,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(Series).Name };
+ query.IncludeItemTypes = new[] { nameof(Series) };
return _libraryManager.GetItemsResult(query);
}
@@ -189,7 +189,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
+ query.IncludeItemTypes = new[] { nameof(Episode) };
return _libraryManager.GetItemsResult(query);
}
@@ -200,7 +200,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
+ query.IncludeItemTypes = new[] { nameof(Movie) };
return _libraryManager.GetItemsResult(query);
}
@@ -208,7 +208,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMovieCollections(Folder parent, User user, InternalItemsQuery query)
{
query.Parent = null;
- query.IncludeItemTypes = new[] { typeof(BoxSet).Name };
+ query.IncludeItemTypes = new[] { nameof(BoxSet) };
query.SetUser(user);
query.Recursive = true;
@@ -223,7 +223,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
+ query.IncludeItemTypes = new[] { nameof(Movie) };
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -236,7 +236,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
+ query.IncludeItemTypes = new[] { nameof(Movie) };
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -255,7 +255,7 @@ namespace MediaBrowser.Controller.Entities
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
- IncludeItemTypes = new[] { typeof(Movie).Name },
+ IncludeItemTypes = new[] { nameof(Movie) },
Recursive = true,
EnableTotalRecordCount = false
}).Items
@@ -286,7 +286,7 @@ namespace MediaBrowser.Controller.Entities
query.GenreIds = new[] { displayParent.Id };
query.SetUser(user);
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
+ query.IncludeItemTypes = new[] { nameof(Movie) };
return _libraryManager.GetItemsResult(query);
}
@@ -333,7 +333,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
+ query.IncludeItemTypes = new[] { nameof(Episode) };
query.IsVirtualItem = false;
return ConvertToResult(_libraryManager.GetItemList(query));
@@ -343,7 +343,8 @@ namespace MediaBrowser.Controller.Entities
{
var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.TvShows, string.Empty });
- var result = _tvSeriesManager.GetNextUp(new NextUpQuery
+ var result = _tvSeriesManager.GetNextUp(
+ new NextUpQuery
{
Limit = query.Limit,
StartIndex = query.StartIndex,
@@ -361,7 +362,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
+ query.IncludeItemTypes = new[] { nameof(Episode) };
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -372,7 +373,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
- query.IncludeItemTypes = new[] { typeof(Series).Name };
+ query.IncludeItemTypes = new[] { nameof(Series) };
return _libraryManager.GetItemsResult(query);
}
@@ -381,7 +382,7 @@ namespace MediaBrowser.Controller.Entities
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
- IncludeItemTypes = new[] { typeof(Series).Name },
+ IncludeItemTypes = new[] { nameof(Series) },
Recursive = true,
EnableTotalRecordCount = false
}).Items
@@ -412,7 +413,7 @@ namespace MediaBrowser.Controller.Entities
query.GenreIds = new[] { displayParent.Id };
query.SetUser(user);
- query.IncludeItemTypes = new[] { typeof(Series).Name };
+ query.IncludeItemTypes = new[] { nameof(Series) };
return _libraryManager.GetItemsResult(query);
}
@@ -443,7 +444,8 @@ namespace MediaBrowser.Controller.Entities
return Filter(item, query.User, query, BaseItem.UserDataManager, BaseItem.LibraryManager);
}
- public static QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
+ public static QueryResult<BaseItem> PostFilterAndSort(
+ IEnumerable<BaseItem> items,
BaseItem queryParent,
int? totalRecordLimit,
InternalItemsQuery query,
diff --git a/MediaBrowser.Controller/IDisplayPreferencesManager.cs b/MediaBrowser.Controller/IDisplayPreferencesManager.cs
index b35f83096..6658269bd 100644
--- a/MediaBrowser.Controller/IDisplayPreferencesManager.cs
+++ b/MediaBrowser.Controller/IDisplayPreferencesManager.cs
@@ -12,6 +12,9 @@ namespace MediaBrowser.Controller
/// <summary>
/// Gets the display preferences for the user and client.
/// </summary>
+ /// <remarks>
+ /// This will create the display preferences if it does not exist, but it will not save automatically.
+ /// </remarks>
/// <param name="userId">The user's id.</param>
/// <param name="client">The client string.</param>
/// <returns>The associated display preferences.</returns>
@@ -20,6 +23,9 @@ namespace MediaBrowser.Controller
/// <summary>
/// Gets the default item display preferences for the user and client.
/// </summary>
+ /// <remarks>
+ /// This will create the item display preferences if it does not exist, but it will not save automatically.
+ /// </remarks>
/// <param name="userId">The user id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="client">The client string.</param>
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index cfad17fb7..ffbb147b0 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -6,8 +6,8 @@ using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common;
+using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.System;
-using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller
{
@@ -56,10 +56,11 @@ namespace MediaBrowser.Controller
/// <summary>
/// Gets the system info.
/// </summary>
+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param>
/// <returns>SystemInfo.</returns>
- Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken);
+ Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken = default);
- Task<PublicSystemInfo> GetPublicSystemInfo(CancellationToken cancellationToken);
+ Task<PublicSystemInfo> GetPublicSystemInfo(CancellationToken cancellationToken = default);
/// <summary>
/// Gets all the local IP addresses of this API instance. Each address is validated by sending a 'ping' request
@@ -67,7 +68,7 @@ namespace MediaBrowser.Controller
/// </summary>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param>
/// <returns>A list containing all the local IP addresses of the server.</returns>
- Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken);
+ Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken = default);
/// <summary>
/// Gets a local (LAN) URL that can be used to access the API. The hostname used is the first valid configured
@@ -75,7 +76,7 @@ namespace MediaBrowser.Controller
/// </summary>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param>
/// <returns>The server URL.</returns>
- Task<string> GetLocalApiUrl(CancellationToken cancellationToken);
+ Task<string> GetLocalApiUrl(CancellationToken cancellationToken = default);
/// <summary>
/// Gets a localhost URL that can be used to access the API using the loop-back IP address (127.0.0.1)
@@ -119,5 +120,13 @@ namespace MediaBrowser.Controller
string ExpandVirtualPath(string path);
string ReverseVirtualPath(string path);
+
+ /// <summary>
+ /// Gets the list of local plugins.
+ /// </summary>
+ /// <param name="path">Plugin base directory.</param>
+ /// <param name="cleanup">Cleanup old plugins.</param>
+ /// <returns>Enumerable of local plugins.</returns>
+ IEnumerable<LocalPlugin> GetLocalPlugins(string path, bool cleanup = true);
}
}
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 332730bcc..c7c79df76 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -566,8 +566,11 @@ namespace MediaBrowser.Controller.Library
int GetCount(InternalItemsQuery query);
- void AddExternalSubtitleStreams(List<MediaStream> streams,
+ void AddExternalSubtitleStreams(
+ List<MediaStream> streams,
string videoPath,
string[] files);
+
+ BaseItem GetParentItem(string parentId, Guid? userId);
}
}
diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs
index 22bf9488f..21c6ef2af 100644
--- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs
+++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs
@@ -115,5 +115,7 @@ namespace MediaBrowser.Controller.Library
public interface IDirectStreamProvider
{
Task CopyToAsync(Stream stream, CancellationToken cancellationToken);
+
+ string GetFilePath();
}
}
diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index 6a4f5cf67..8fd3b8c34 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -158,7 +158,8 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="userId">The user's Id.</param>
/// <param name="config">The request containing the new user configuration.</param>
- void UpdateConfiguration(Guid userId, UserConfiguration config);
+ /// <returns>A task representing the update.</returns>
+ Task UpdateConfigurationAsync(Guid userId, UserConfiguration config);
/// <summary>
/// This method updates the user's policy.
@@ -167,12 +168,14 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="userId">The user's Id.</param>
/// <param name="policy">The request containing the new user policy.</param>
- void UpdatePolicy(Guid userId, UserPolicy policy);
+ /// <returns>A task representing the update.</returns>
+ Task UpdatePolicyAsync(Guid userId, UserPolicy policy);
/// <summary>
/// Clears the user's profile image.
/// </summary>
/// <param name="user">The user.</param>
- void ClearProfileImage(User user);
+ /// <returns>A task representing the clearing of the profile image.</returns>
+ Task ClearProfileImageAsync(User user);
}
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 654470406..4374317d6 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -14,8 +14,8 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.8" />
- <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.8" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.9" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.9" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index c5529ad5b..5846a603a 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -70,15 +70,15 @@ namespace MediaBrowser.Controller.MediaEncoding
var codecMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
- {"qsv", hwEncoder + "_qsv"},
- {hwEncoder + "_qsv", hwEncoder + "_qsv"},
- {"nvenc", hwEncoder + "_nvenc"},
- {"amf", hwEncoder + "_amf"},
- {"omx", hwEncoder + "_omx"},
- {hwEncoder + "_v4l2m2m", hwEncoder + "_v4l2m2m"},
- {"mediacodec", hwEncoder + "_mediacodec"},
- {"vaapi", hwEncoder + "_vaapi"},
- {"videotoolbox", hwEncoder + "_videotoolbox"}
+ { "qsv", hwEncoder + "_qsv" },
+ { hwEncoder + "_qsv", hwEncoder + "_qsv" },
+ { "nvenc", hwEncoder + "_nvenc" },
+ { "amf", hwEncoder + "_amf" },
+ { "omx", hwEncoder + "_omx" },
+ { hwEncoder + "_v4l2m2m", hwEncoder + "_v4l2m2m" },
+ { "mediacodec", hwEncoder + "_mediacodec" },
+ { "vaapi", hwEncoder + "_vaapi" },
+ { "videotoolbox", hwEncoder + "_videotoolbox" }
};
if (!string.IsNullOrEmpty(hwType)
@@ -451,11 +451,13 @@ namespace MediaBrowser.Controller.MediaEncoding
var arg = new StringBuilder();
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions) ?? string.Empty;
var outputVideoCodec = GetVideoEncoder(state, encodingOptions) ?? string.Empty;
+ var isSwDecoder = string.IsNullOrEmpty(videoDecoder);
+ var isD3d11vaDecoder = videoDecoder.IndexOf("d3d11va", StringComparison.OrdinalIgnoreCase) != -1;
var isVaapiDecoder = videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1;
var isVaapiEncoder = outputVideoCodec.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1;
var isQsvDecoder = videoDecoder.IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1;
var isQsvEncoder = outputVideoCodec.IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1;
- var isNvencHevcDecoder = videoDecoder.IndexOf("hevc_cuvid", StringComparison.OrdinalIgnoreCase) != -1;
+ var isNvdecHevcDecoder = videoDecoder.IndexOf("hevc_cuvid", StringComparison.OrdinalIgnoreCase) != -1;
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
var isMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
@@ -517,11 +519,12 @@ namespace MediaBrowser.Controller.MediaEncoding
}
if (state.IsVideoRequest
- && string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
+ && (string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase) && isNvdecHevcDecoder || isSwDecoder)
+ || (string.Equals(encodingOptions.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase) && isD3d11vaDecoder || isSwDecoder))
{
var isColorDepth10 = IsColorDepth10(state);
- if (isNvencHevcDecoder && isColorDepth10
+ if (isColorDepth10
&& _mediaEncoder.SupportsHwaccel("opencl")
&& encodingOptions.EnableTonemapping
&& !string.IsNullOrEmpty(state.VideoStream.VideoRange)
@@ -880,6 +883,19 @@ namespace MediaBrowser.Controller.MediaEncoding
param += "-quality speed";
break;
}
+
+ var videoStream = state.VideoStream;
+ var isColorDepth10 = IsColorDepth10(state);
+
+ if (isColorDepth10
+ && _mediaEncoder.SupportsHwaccel("opencl")
+ && encodingOptions.EnableTonemapping
+ && !string.IsNullOrEmpty(videoStream.VideoRange)
+ && videoStream.VideoRange.Contains("HDR", StringComparison.OrdinalIgnoreCase))
+ {
+ // Enhance workload when tone mapping with AMF on some APUs
+ param += " -preanalysis true";
+ }
}
else if (string.Equals(videoEncoder, "libvpx", StringComparison.OrdinalIgnoreCase)) // webm
{
@@ -1023,19 +1039,19 @@ namespace MediaBrowser.Controller.MediaEncoding
&& !string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(videoEncoder, "h264_nvenc", StringComparison.OrdinalIgnoreCase)
+ && !string.Equals(videoEncoder, "h264_amf", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase))
{
param = "-pix_fmt yuv420p " + param;
}
- if (string.Equals(videoEncoder, "h264_nvenc", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(videoEncoder, "h264_nvenc", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(videoEncoder, "h264_amf", StringComparison.OrdinalIgnoreCase))
{
- var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions) ?? string.Empty;
var videoStream = state.VideoStream;
var isColorDepth10 = IsColorDepth10(state);
- if (videoDecoder.IndexOf("hevc_cuvid", StringComparison.OrdinalIgnoreCase) != -1
- && isColorDepth10
+ if (isColorDepth10
&& _mediaEncoder.SupportsHwaccel("opencl")
&& encodingOptions.EnableTonemapping
&& !string.IsNullOrEmpty(videoStream.VideoRange)
@@ -1364,24 +1380,40 @@ namespace MediaBrowser.Controller.MediaEncoding
public int? GetAudioBitrateParam(BaseEncodingJobOptions request, MediaStream audioStream)
{
+ if (audioStream == null)
+ {
+ return null;
+ }
+
if (request.AudioBitRate.HasValue)
{
// Don't encode any higher than this
return Math.Min(384000, request.AudioBitRate.Value);
}
- return null;
+ // Empty bitrate area is not allow on iOS
+ // Default audio bitrate to 128K if it is not being requested
+ // https://ffmpeg.org/ffmpeg-codecs.html#toc-Codec-Options
+ return 128000;
}
public int? GetAudioBitrateParam(int? audioBitRate, MediaStream audioStream)
{
+ if (audioStream == null)
+ {
+ return null;
+ }
+
if (audioBitRate.HasValue)
{
// Don't encode any higher than this
return Math.Min(384000, audioBitRate.Value);
}
- return null;
+ // Empty bitrate area is not allow on iOS
+ // Default audio bitrate to 128K if it is not being requested
+ // https://ffmpeg.org/ffmpeg-codecs.html#toc-Codec-Options
+ return 128000;
}
public string GetAudioFilterParam(EncodingJobInfo state, EncodingOptions encodingOptions, bool isHls)
@@ -1651,47 +1683,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var outputSizeParam = ReadOnlySpan<char>.Empty;
var request = state.BaseRequest;
- outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"');
-
- // All possible beginning of video filters
- // Don't break the order
- string[] beginOfOutputSizeParam = new[]
- {
- // for tonemap_opencl
- "hwupload,tonemap_opencl",
-
- // hwupload=extra_hw_frames=64,vpp_qsv (for overlay_qsv on linux)
- "hwupload=extra_hw_frames",
-
- // vpp_qsv
- "vpp",
-
- // hwdownload,format=p010le (hardware decode + software encode for vaapi)
- "hwdownload",
-
- // format=nv12|vaapi,hwupload,scale_vaapi
- "format",
-
- // bwdif,scale=expr
- "bwdif",
-
- // yadif,scale=expr
- "yadif",
-
- // scale=expr
- "scale"
- };
-
- var index = -1;
- foreach (var param in beginOfOutputSizeParam)
- {
- index = outputSizeParam.IndexOf(param, StringComparison.OrdinalIgnoreCase);
- if (index != -1)
- {
- outputSizeParam = outputSizeParam.Slice(index);
- break;
- }
- }
+ outputSizeParam = GetOutputSizeParamInternal(state, options, outputVideoCodec);
var videoSizeParam = string.Empty;
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options) ?? string.Empty;
@@ -1822,7 +1814,8 @@ namespace MediaBrowser.Controller.MediaEncoding
return (Convert.ToInt32(outputWidth), Convert.ToInt32(outputHeight));
}
- public List<string> GetScalingFilters(EncodingJobInfo state,
+ public List<string> GetScalingFilters(
+ EncodingJobInfo state,
int? videoWidth,
int? videoHeight,
Video3DFormat? threedFormat,
@@ -2082,10 +2075,19 @@ namespace MediaBrowser.Controller.MediaEncoding
return string.Format(CultureInfo.InvariantCulture, filter, widthParam, heightParam);
}
+ public string GetOutputSizeParam(
+ EncodingJobInfo state,
+ EncodingOptions options,
+ string outputVideoCodec)
+ {
+ string filters = GetOutputSizeParamInternal(state, options, outputVideoCodec);
+ return string.IsNullOrEmpty(filters) ? string.Empty : " -vf \"" + filters + "\"";
+ }
+
/// <summary>
/// If we're going to put a fixed size on the command line, this will calculate it.
/// </summary>
- public string GetOutputSizeParam(
+ public string GetOutputSizeParamInternal(
EncodingJobInfo state,
EncodingOptions options,
string outputVideoCodec)
@@ -2101,6 +2103,8 @@ namespace MediaBrowser.Controller.MediaEncoding
var inputHeight = videoStream?.Height;
var threeDFormat = state.MediaSource.Video3DFormat;
+ var isSwDecoder = string.IsNullOrEmpty(videoDecoder);
+ var isD3d11vaDecoder = videoDecoder.IndexOf("d3d11va", StringComparison.OrdinalIgnoreCase) != -1;
var isVaapiDecoder = videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1;
var isVaapiH264Encoder = outputVideoCodec.IndexOf("h264_vaapi", StringComparison.OrdinalIgnoreCase) != -1;
var isQsvH264Encoder = outputVideoCodec.IndexOf("h264_qsv", StringComparison.OrdinalIgnoreCase) != -1;
@@ -2116,47 +2120,77 @@ namespace MediaBrowser.Controller.MediaEncoding
// If double rate deinterlacing is enabled and the input framerate is 30fps or below, otherwise the output framerate will be too high for many devices
var doubleRateDeinterlace = options.DeinterlaceDoubleRate && (videoStream?.RealFrameRate ?? 60) <= 30;
- // Currently only with the use of NVENC decoder can we get a decent performance.
- // Currently only the HEVC/H265 format is supported.
- // NVIDIA Pascal and Turing or higher are recommended.
- if (isNvdecHevcDecoder && isColorDepth10
- && _mediaEncoder.SupportsHwaccel("opencl")
- && options.EnableTonemapping
- && !string.IsNullOrEmpty(videoStream.VideoRange)
- && videoStream.VideoRange.Contains("HDR", StringComparison.OrdinalIgnoreCase))
- {
- var parameters = "tonemap_opencl=format=nv12:primaries=bt709:transfer=bt709:matrix=bt709:tonemap={0}:desat={1}:threshold={2}:peak={3}";
+ var isScalingInAdvance = false;
+ var isDeinterlaceH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
+ var isDeinterlaceHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
- if (options.TonemappingParam != 0)
+ if ((string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase) && isNvdecHevcDecoder || isSwDecoder)
+ || (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase) && isD3d11vaDecoder || isSwDecoder))
+ {
+ // Currently only with the use of NVENC decoder can we get a decent performance.
+ // Currently only the HEVC/H265 format is supported with NVDEC decoder.
+ // NVIDIA Pascal and Turing or higher are recommended.
+ // AMD Polaris and Vega or higher are recommended.
+ if (isColorDepth10
+ && _mediaEncoder.SupportsHwaccel("opencl")
+ && options.EnableTonemapping
+ && !string.IsNullOrEmpty(videoStream.VideoRange)
+ && videoStream.VideoRange.Contains("HDR", StringComparison.OrdinalIgnoreCase))
{
- parameters += ":param={4}";
- }
+ var parameters = "tonemap_opencl=format=nv12:primaries=bt709:transfer=bt709:matrix=bt709:tonemap={0}:desat={1}:threshold={2}:peak={3}";
- if (!string.Equals(options.TonemappingRange, "auto", StringComparison.OrdinalIgnoreCase))
- {
- parameters += ":range={5}";
- }
+ if (options.TonemappingParam != 0)
+ {
+ parameters += ":param={4}";
+ }
- // Upload the HDR10 or HLG data to the OpenCL device,
- // use tonemap_opencl filter for tone mapping,
- // and then download the SDR data to memory.
- filters.Add("hwupload");
- filters.Add(
- string.Format(
- CultureInfo.InvariantCulture,
- parameters,
- options.TonemappingAlgorithm,
- options.TonemappingDesat,
- options.TonemappingThreshold,
- options.TonemappingPeak,
- options.TonemappingParam,
- options.TonemappingRange));
- filters.Add("hwdownload");
-
- if (hasGraphicalSubs || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true)
- || string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
- {
- filters.Add("format=nv12");
+ if (!string.Equals(options.TonemappingRange, "auto", StringComparison.OrdinalIgnoreCase))
+ {
+ parameters += ":range={5}";
+ }
+
+ if (isSwDecoder || isD3d11vaDecoder)
+ {
+ isScalingInAdvance = true;
+ // Add zscale filter before tone mapping filter for performance.
+ var (width, height) = GetFixedOutputSize(inputWidth, inputHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight);
+ if (width.HasValue && height.HasValue)
+ {
+ filters.Add(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "zscale=s={0}x{1}",
+ width.Value,
+ height.Value));
+ }
+
+ // Convert to hardware pixel format p010 when using SW decoder.
+ filters.Add("format=p010");
+ }
+
+ // Upload the HDR10 or HLG data to the OpenCL device,
+ // use tonemap_opencl filter for tone mapping,
+ // and then download the SDR data to memory.
+ filters.Add("hwupload");
+ filters.Add(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ parameters,
+ options.TonemappingAlgorithm,
+ options.TonemappingDesat,
+ options.TonemappingThreshold,
+ options.TonemappingPeak,
+ options.TonemappingParam,
+ options.TonemappingRange));
+ filters.Add("hwdownload");
+
+ if (isLibX264Encoder
+ || hasGraphicalSubs
+ || (isNvdecHevcDecoder && isDeinterlaceHevc)
+ || (!isNvdecHevcDecoder && isDeinterlaceH264 || isDeinterlaceHevc))
+ {
+ filters.Add("format=nv12");
+ }
}
}
@@ -2201,7 +2235,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Add hardware deinterlace filter before scaling filter
- if (state.DeInterlace("h264", true) || state.DeInterlace("avc", true))
+ if (isDeinterlaceH264)
{
if (isVaapiH264Encoder)
{
@@ -2214,10 +2248,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Add software deinterlace filter before scaling filter
- if ((state.DeInterlace("h264", true)
- || state.DeInterlace("avc", true)
- || state.DeInterlace("h265", true)
- || state.DeInterlace("hevc", true))
+ if ((isDeinterlaceH264 || isDeinterlaceHevc)
&& !isVaapiH264Encoder
&& !isQsvH264Encoder
&& !isNvdecH264Decoder)
@@ -2241,7 +2272,21 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Add scaling filter: scale_*=format=nv12 or scale_*=w=*:h=*:format=nv12 or scale=expr
- filters.AddRange(GetScalingFilters(state, inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight));
+ if (!isScalingInAdvance)
+ {
+ filters.AddRange(
+ GetScalingFilters(
+ state,
+ inputWidth,
+ inputHeight,
+ threeDFormat,
+ videoDecoder,
+ outputVideoCodec,
+ request.Width,
+ request.Height,
+ request.MaxWidth,
+ request.MaxHeight));
+ }
// Add parameters to use VAAPI with burn-in text subtitles (GH issue #642)
if (isVaapiH264Encoder)
@@ -2274,7 +2319,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
output += string.Format(
CultureInfo.InvariantCulture,
- " -vf \"{0}\"",
+ "{0}",
string.Join(",", filters));
}
@@ -2630,9 +2675,10 @@ namespace MediaBrowser.Controller.MediaEncoding
state.MediaSource = mediaSource;
var request = state.BaseRequest;
- if (!string.IsNullOrWhiteSpace(request.AudioCodec))
+ var supportedAudioCodecs = state.SupportedAudioCodecs;
+ if (request != null && supportedAudioCodecs != null && supportedAudioCodecs.Length > 0)
{
- var supportedAudioCodecsList = request.AudioCodec.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
+ var supportedAudioCodecsList = supportedAudioCodecs.ToList();
ShiftAudioCodecsIfNeeded(supportedAudioCodecsList, state.AudioStream);
@@ -3039,7 +3085,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
- var whichCodec = videoStream.Codec.ToLowerInvariant();
+ var whichCodec = videoStream.Codec?.ToLowerInvariant();
switch (whichCodec)
{
case "avc":
@@ -3067,21 +3113,31 @@ namespace MediaBrowser.Controller.MediaEncoding
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");
- if ((isDxvaSupported || IsVaapiSupported(state)) && options.HardwareDecodingCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase))
+ if (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase))
{
- if (isLinux)
+ // Currently there is no AMF decoder on Linux, only have h264 encoder.
+ if (isDxvaSupported && options.HardwareDecodingCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase))
{
- return "-hwaccel vaapi";
- }
+ if (isWindows && isWindows8orLater)
+ {
+ return "-hwaccel d3d11va";
+ }
- if (isWindows && isWindows8orLater)
- {
- return "-hwaccel d3d11va";
+ if (isWindows && !isWindows8orLater)
+ {
+ return "-hwaccel dxva2";
+ }
}
+ }
- if (isWindows && !isWindows8orLater)
+ if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
+ {
+ if (IsVaapiSupported(state) && options.HardwareDecodingCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase))
{
- return "-hwaccel dxva2";
+ if (isLinux)
+ {
+ return "-hwaccel vaapi";
+ }
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index c7ec878d2..6e9362cd1 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -287,6 +287,11 @@ namespace MediaBrowser.Controller.MediaEncoding
return BaseRequest.AudioChannels;
}
+ if (BaseRequest.TranscodingMaxAudioChannels.HasValue)
+ {
+ return BaseRequest.TranscodingMaxAudioChannels;
+ }
+
if (!string.IsNullOrEmpty(codec))
{
var value = BaseRequest.GetOption(codec, "audiochannels");
@@ -342,7 +347,8 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
- var newSize = DrawingUtils.Resize(size,
+ var newSize = DrawingUtils.Resize(
+ size,
BaseRequest.Width ?? 0,
BaseRequest.Height ?? 0,
BaseRequest.MaxWidth ?? 0,
@@ -368,7 +374,8 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
- var newSize = DrawingUtils.Resize(size,
+ var newSize = DrawingUtils.Resize(
+ size,
BaseRequest.Width ?? 0,
BaseRequest.Height ?? 0,
BaseRequest.MaxWidth ?? 0,
diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
index 17d6dc5d2..f6bc1f4de 100644
--- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
@@ -68,7 +68,8 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <summary>
/// Extracts the video images on interval.
/// </summary>
- Task ExtractVideoImagesOnInterval(string[] inputFiles,
+ Task ExtractVideoImagesOnInterval(
+ string[] inputFiles,
string container,
MediaStream videoStream,
MediaProtocol protocol,
diff --git a/MediaBrowser.Controller/Net/AuthorizationInfo.cs b/MediaBrowser.Controller/Net/AuthorizationInfo.cs
index 735c46ef8..0194c596f 100644
--- a/MediaBrowser.Controller/Net/AuthorizationInfo.cs
+++ b/MediaBrowser.Controller/Net/AuthorizationInfo.cs
@@ -1,10 +1,11 @@
-#pragma warning disable CS1591
-
using System;
using Jellyfin.Data.Entities;
namespace MediaBrowser.Controller.Net
{
+ /// <summary>
+ /// The request authorization info.
+ /// </summary>
public class AuthorizationInfo
{
/// <summary>
@@ -43,6 +44,19 @@ namespace MediaBrowser.Controller.Net
/// <value>The token.</value>
public string Token { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether the authorization is from an api key.
+ /// </summary>
+ public bool IsApiKey { get; set; }
+
+ /// <summary>
+ /// Gets or sets the user making the request.
+ /// </summary>
public User User { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the token is authenticated.
+ /// </summary>
+ public bool IsAuthenticated { get; set; }
}
}
diff --git a/MediaBrowser.Controller/Net/IWebSocketManager.cs b/MediaBrowser.Controller/Net/IWebSocketManager.cs
index e9f00ae88..ce74173e7 100644
--- a/MediaBrowser.Controller/Net/IWebSocketManager.cs
+++ b/MediaBrowser.Controller/Net/IWebSocketManager.cs
@@ -17,12 +17,6 @@ namespace MediaBrowser.Controller.Net
event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected;
/// <summary>
- /// Inits this instance.
- /// </summary>
- /// <param name="listeners">The websocket listeners.</param>
- void Init(IEnumerable<IWebSocketListener> listeners);
-
- /// <summary>
/// The HTTP request handler.
/// </summary>
/// <param name="context">The current HTTP context.</param>
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 216dd2709..e8b7be7e2 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -160,7 +160,7 @@ namespace MediaBrowser.Controller.Playlists
return LibraryManager.GetItemList(new InternalItemsQuery(user)
{
Recursive = true,
- IncludeItemTypes = new[] { typeof(Audio).Name },
+ IncludeItemTypes = new[] { nameof(Audio) },
GenreIds = new[] { musicGenre.Id },
OrderBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
@@ -172,7 +172,7 @@ namespace MediaBrowser.Controller.Playlists
return LibraryManager.GetItemList(new InternalItemsQuery(user)
{
Recursive = true,
- IncludeItemTypes = new[] { typeof(Audio).Name },
+ IncludeItemTypes = new[] { nameof(Audio) },
ArtistIds = new[] { musicArtist.Id },
OrderBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
diff --git a/MediaBrowser.Controller/Resolvers/IItemResolver.cs b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
index eb7fb793a..75286eadc 100644
--- a/MediaBrowser.Controller/Resolvers/IItemResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
@@ -29,7 +29,8 @@ namespace MediaBrowser.Controller.Resolvers
public interface IMultiItemResolver
{
- MultiItemResolverResult ResolveMultiple(Folder parent,
+ MultiItemResolverResult ResolveMultiple(
+ Folder parent,
List<FileSystemMetadata> files,
string collectionType,
IDirectoryService directoryService);
diff --git a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs
index f43d523a6..feb26bc10 100644
--- a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs
+++ b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
@@ -53,6 +54,14 @@ namespace MediaBrowser.Controller.Subtitles
Task DownloadSubtitles(Video video, LibraryOptions libraryOptions, string subtitleId, CancellationToken cancellationToken);
/// <summary>
+ /// Upload new subtitle.
+ /// </summary>
+ /// <param name="video">The video the subtitle belongs to.</param>
+ /// <param name="response">The subtitle response.</param>
+ /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
+ Task UploadSubtitle(Video video, SubtitleResponse response);
+
+ /// <summary>
/// Gets the remote subtitles.
/// </summary>
/// <param name="id">The identifier.</param>