aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Channels/Channel.cs5
-rw-r--r--MediaBrowser.Controller/Entities/AggregateFolder.cs4
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs2
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs49
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs37
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs10
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs4
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs8
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs4
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs2
-rw-r--r--MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs5
-rw-r--r--MediaBrowser.Controller/Library/IIntroProvider.cs6
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs31
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvChannel.cs2
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj2
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs203
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs19
-rw-r--r--MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs13
-rw-r--r--MediaBrowser.Controller/Persistence/IItemRepository.cs25
-rw-r--r--MediaBrowser.Controller/Persistence/IRepository.cs16
-rw-r--r--MediaBrowser.Controller/Persistence/IUserDataRepository.cs3
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs6
-rw-r--r--MediaBrowser.Controller/Session/SessionInfo.cs6
23 files changed, 186 insertions, 276 deletions
diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs
index 85a99d62c..94418683b 100644
--- a/MediaBrowser.Controller/Channels/Channel.cs
+++ b/MediaBrowser.Controller/Channels/Channel.cs
@@ -77,11 +77,6 @@ namespace MediaBrowser.Controller.Channels
return false;
}
- protected override bool IsAllowTagFilterEnforced()
- {
- return false;
- }
-
internal static bool IsChannelVisible(BaseItem channelItem, User user)
{
var channel = ChannelManager.GetChannel(channelItem.ChannelId.ToString(string.Empty));
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs
index 9589f5245..77a857b78 100644
--- a/MediaBrowser.Controller/Entities/AggregateFolder.cs
+++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs
@@ -187,14 +187,14 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="ArgumentNullException">The id is empty.</exception>
public BaseItem FindVirtualChild(Guid id)
{
- if (id.Equals(Guid.Empty))
+ if (id.Equals(default))
{
throw new ArgumentNullException(nameof(id));
}
foreach (var child in _virtualChildren)
{
- if (child.Id == id)
+ if (child.Id.Equals(id))
{
return child;
}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 11b95b94b..0f2d7e62d 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Entities.Audio
public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
{
[JsonIgnore]
- public bool IsAccessedByName => ParentId.Equals(Guid.Empty);
+ public bool IsAccessedByName => ParentId.Equals(default);
[JsonIgnore]
public override bool IsFolder => !IsAccessedByName;
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 0f62e8e1e..2bb966d2c 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -231,7 +231,7 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (!ChannelId.Equals(Guid.Empty))
+ if (!ChannelId.Equals(default))
{
return SourceType.Channel;
}
@@ -521,7 +521,7 @@ namespace MediaBrowser.Controller.Entities
get
{
var id = DisplayParentId;
- if (id.Equals(Guid.Empty))
+ if (id.Equals(default))
{
return null;
}
@@ -737,7 +737,7 @@ namespace MediaBrowser.Controller.Entities
public virtual bool StopRefreshIfLocalMetadataFound => true;
[JsonIgnore]
- protected virtual bool SupportsOwnedItems => !ParentId.Equals(Guid.Empty) && IsFileProtocol;
+ protected virtual bool SupportsOwnedItems => !ParentId.Equals(default) && IsFileProtocol;
[JsonIgnore]
public virtual bool SupportsPeople => false;
@@ -848,7 +848,7 @@ namespace MediaBrowser.Controller.Entities
public BaseItem GetOwner()
{
var ownerId = OwnerId;
- return ownerId.Equals(Guid.Empty) ? null : LibraryManager.GetItemById(ownerId);
+ return ownerId.Equals(default) ? null : LibraryManager.GetItemById(ownerId);
}
public bool CanDelete(User user, List<Folder> allCollectionFolders)
@@ -878,16 +878,13 @@ namespace MediaBrowser.Controller.Entities
return CanDownload() && IsAuthorizedToDownload(user);
}
- /// <summary>
- /// Returns a <see cref="string" /> that represents this instance.
- /// </summary>
- /// <returns>A <see cref="string" /> that represents this instance.</returns>
+ /// <inheritdoc />
public override string ToString()
{
return Name;
}
- public string GetInternalMetadataPath()
+ public virtual string GetInternalMetadataPath()
{
var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath;
@@ -984,12 +981,12 @@ namespace MediaBrowser.Controller.Entities
public BaseItem GetParent()
{
var parentId = ParentId;
- if (!parentId.Equals(Guid.Empty))
+ if (parentId.Equals(default))
{
- return LibraryManager.GetItemById(parentId);
+ return null;
}
- return null;
+ return LibraryManager.GetItemById(parentId);
}
public IEnumerable<BaseItem> GetParents()
@@ -1397,7 +1394,7 @@ namespace MediaBrowser.Controller.Entities
var tasks = extras.Select(i =>
{
var subOptions = new MetadataRefreshOptions(options);
- if (i.OwnerId != ownerId || i.ParentId != Guid.Empty)
+ if (!i.OwnerId.Equals(ownerId) || !i.ParentId.Equals(default))
{
i.OwnerId = ownerId;
i.ParentId = Guid.Empty;
@@ -1595,23 +1592,6 @@ namespace MediaBrowser.Controller.Entities
return value.Value <= maxAllowedRating.Value;
}
- public int? GetParentalRatingValue()
- {
- var rating = CustomRating;
-
- if (string.IsNullOrEmpty(rating))
- {
- rating = OfficialRating;
- }
-
- if (string.IsNullOrEmpty(rating))
- {
- return null;
- }
-
- return LocalizationManager.GetRatingLevel(rating);
- }
-
public int? GetInheritedParentalRatingValue()
{
var rating = CustomRatingForComparison;
@@ -1652,11 +1632,6 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- protected virtual bool IsAllowTagFilterEnforced()
- {
- return true;
- }
-
public virtual UnratedItem GetBlockUnratedType()
{
if (SourceType == SourceType.Channel)
@@ -1736,7 +1711,7 @@ namespace MediaBrowser.Controller.Entities
// First get using the cached Id
if (info.ItemId.HasValue)
{
- if (info.ItemId.Value.Equals(Guid.Empty))
+ if (info.ItemId.Value.Equals(default))
{
return null;
}
@@ -2657,7 +2632,7 @@ namespace MediaBrowser.Controller.Entities
}
/// <inheritdoc />
- public bool Equals(BaseItem other) => Id == other?.Id;
+ public bool Equals(BaseItem other) => other is not null && other.Id.Equals(Id);
/// <inheritdoc />
public override int GetHashCode() => HashCode.Combine(Id);
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 4d9aac6f9..b6983b73e 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -189,21 +189,6 @@ namespace MediaBrowser.Controller.Entities
return baseResult;
}
- protected override bool IsAllowTagFilterEnforced()
- {
- if (this is ICollectionFolder)
- {
- return false;
- }
-
- if (this is UserView)
- {
- return false;
- }
-
- return true;
- }
-
/// <summary>
/// Adds the child.
/// </summary>
@@ -213,7 +198,7 @@ namespace MediaBrowser.Controller.Entities
{
item.SetParent(this);
- if (item.Id.Equals(Guid.Empty))
+ if (item.Id.Equals(default))
{
item.Id = LibraryManager.GetNewItemId(item.Path, item.GetType());
}
@@ -730,7 +715,9 @@ namespace MediaBrowser.Controller.Entities
return PostFilterAndSort(items, query, true);
}
- if (this is not UserRootFolder && this is not AggregateFolder && query.ParentId == Guid.Empty)
+ if (this is not UserRootFolder
+ && this is not AggregateFolder
+ && query.ParentId.Equals(default))
{
query.Parent = this;
}
@@ -848,6 +835,18 @@ namespace MediaBrowser.Controller.Entities
return true;
}
+ if (query.HasThemeSong.HasValue)
+ {
+ Logger.LogDebug("Query requires post-filtering due to HasThemeSong");
+ return true;
+ }
+
+ if (query.HasThemeVideo.HasValue)
+ {
+ Logger.LogDebug("Query requires post-filtering due to HasThemeVideo");
+ return true;
+ }
+
// Filter by VideoType
if (query.VideoTypes.Length > 0)
{
@@ -1492,7 +1491,7 @@ namespace MediaBrowser.Controller.Entities
{
if (i.ItemId.HasValue)
{
- if (i.ItemId.Value == itemId)
+ if (i.ItemId.Value.Equals(itemId))
{
return true;
}
@@ -1502,7 +1501,7 @@ namespace MediaBrowser.Controller.Entities
var child = GetLinkedChild(i);
- if (child != null && child.Id == itemId)
+ if (child != null && child.Id.Equals(itemId))
{
return true;
}
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index c8a0e21eb..15b721fe6 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -74,12 +74,12 @@ namespace MediaBrowser.Controller.Entities.TV
get
{
var seriesId = SeriesId;
- if (seriesId.Equals(Guid.Empty))
+ if (seriesId.Equals(default))
{
seriesId = FindSeriesId();
}
- return !seriesId.Equals(Guid.Empty) ? (LibraryManager.GetItemById(seriesId) as Series) : null;
+ return seriesId.Equals(default) ? null : (LibraryManager.GetItemById(seriesId) as Series);
}
}
@@ -89,12 +89,12 @@ namespace MediaBrowser.Controller.Entities.TV
get
{
var seasonId = SeasonId;
- if (seasonId.Equals(Guid.Empty))
+ if (seasonId.Equals(default))
{
seasonId = FindSeasonId();
}
- return !seasonId.Equals(Guid.Empty) ? (LibraryManager.GetItemById(seasonId) as Season) : null;
+ return seasonId.Equals(default) ? null : (LibraryManager.GetItemById(seasonId) as Season);
}
}
@@ -271,7 +271,7 @@ namespace MediaBrowser.Controller.Entities.TV
var seasonId = SeasonId;
- if (!seasonId.Equals(Guid.Empty) && !list.Contains(seasonId))
+ if (!seasonId.Equals(default) && !list.Contains(seasonId))
{
list.Add(seasonId);
}
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 926c7b045..bd8df2fac 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -48,12 +48,12 @@ namespace MediaBrowser.Controller.Entities.TV
get
{
var seriesId = SeriesId;
- if (seriesId == Guid.Empty)
+ if (seriesId.Equals(default))
{
seriesId = FindSeriesId();
}
- return seriesId == Guid.Empty ? null : (LibraryManager.GetItemById(seriesId) as Series);
+ return seriesId.Equals(default) ? null : (LibraryManager.GetItemById(seriesId) as Series);
}
}
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index 5c9be7337..47432ee93 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -69,11 +69,11 @@ namespace MediaBrowser.Controller.Entities
/// <inheritdoc />
public override IEnumerable<Guid> GetIdsForAncestorQuery()
{
- if (!DisplayParentId.Equals(Guid.Empty))
+ if (!DisplayParentId.Equals(default))
{
yield return DisplayParentId;
}
- else if (!ParentId.Equals(Guid.Empty))
+ else if (!ParentId.Equals(default))
{
yield return ParentId;
}
@@ -94,11 +94,11 @@ namespace MediaBrowser.Controller.Entities
{
var parent = this as Folder;
- if (!DisplayParentId.Equals(Guid.Empty))
+ if (!DisplayParentId.Equals(default))
{
parent = LibraryManager.GetItemById(DisplayParentId) as Folder ?? parent;
}
- else if (!ParentId.Equals(Guid.Empty))
+ else if (!ParentId.Equals(default))
{
parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
}
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 279206da4..2996104e7 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -988,7 +988,7 @@ namespace MediaBrowser.Controller.Entities
public static IEnumerable<BaseItem> FilterForAdjacency(List<BaseItem> list, string adjacentToId)
{
var adjacentToIdGuid = new Guid(adjacentToId);
- var adjacentToItem = list.FirstOrDefault(i => i.Id == adjacentToIdGuid);
+ var adjacentToItem = list.FirstOrDefault(i => i.Id.Equals(adjacentToIdGuid));
var index = list.IndexOf(adjacentToItem);
@@ -1005,7 +1005,7 @@ namespace MediaBrowser.Controller.Entities
nextId = list[index + 1].Id;
}
- return list.Where(i => i.Id == previousId || i.Id == nextId || i.Id == adjacentToIdGuid);
+ return list.Where(i => i.Id.Equals(previousId) || i.Id.Equals(nextId) || i.Id.Equals(adjacentToIdGuid));
}
}
}
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 5ab7808c3..5de2e0f50 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -455,7 +455,7 @@ namespace MediaBrowser.Controller.Entities
foreach (var child in LinkedAlternateVersions)
{
// Reset the cached value
- if (child.ItemId.HasValue && child.ItemId.Value.Equals(Guid.Empty))
+ if (child.ItemId.HasValue && child.ItemId.Value.Equals(default))
{
child.ItemId = null;
}
diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs
index 1fedf7205..5a7110261 100644
--- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs
+++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs
@@ -15,6 +15,11 @@ namespace MediaBrowser.Controller.Extensions
public const string DefaultRedirectKey = "DefaultRedirectPath";
/// <summary>
+ /// The key for the address override option.
+ /// </summary>
+ public const string AddressOverrideKey = "PublishedServerUrl";
+
+ /// <summary>
/// The key for a setting that indicates whether the application should host web client content.
/// </summary>
public const string HostWebClientKey = "hostwebclient";
diff --git a/MediaBrowser.Controller/Library/IIntroProvider.cs b/MediaBrowser.Controller/Library/IIntroProvider.cs
index a74d1b9f0..4a9721acb 100644
--- a/MediaBrowser.Controller/Library/IIntroProvider.cs
+++ b/MediaBrowser.Controller/Library/IIntroProvider.cs
@@ -24,11 +24,5 @@ namespace MediaBrowser.Controller.Library
/// <param name="user">The user.</param>
/// <returns>IEnumerable{System.String}.</returns>
Task<IEnumerable<IntroInfo>> GetIntros(BaseItem item, Jellyfin.Data.Entities.User user);
-
- /// <summary>
- /// Gets all intro files.
- /// </summary>
- /// <returns>IEnumerable{System.String}.</returns>
- IEnumerable<string> GetAllIntroFiles();
}
}
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 2b0193771..313d27ce6 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -138,10 +138,10 @@ namespace MediaBrowser.Controller.Library
/// Validate and refresh the People sub-set of the IBN.
/// The items are stored in the db but not loaded into memory until actually requested by an operation.
/// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress);
+ Task ValidatePeopleAsync(IProgress<double> progress, CancellationToken cancellationToken);
/// <summary>
/// Reloads the root media folder.
@@ -151,11 +151,6 @@ namespace MediaBrowser.Controller.Library
/// <returns>Task.</returns>
Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken);
- /// <summary>
- /// Queues the library scan.
- /// </summary>
- void QueueLibraryScan();
-
Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false);
/// <summary>
@@ -182,12 +177,6 @@ namespace MediaBrowser.Controller.Library
Task<IEnumerable<Video>> GetIntros(BaseItem item, User user);
/// <summary>
- /// Gets all intro files.
- /// </summary>
- /// <returns>IEnumerable{System.String}.</returns>
- IEnumerable<string> GetAllIntroFiles();
-
- /// <summary>
/// Adds the parts.
/// </summary>
/// <param name="rules">The rules.</param>
@@ -508,15 +497,6 @@ namespace MediaBrowser.Controller.Library
string GetPathAfterNetworkSubstitution(string path, BaseItem ownerItem = null);
/// <summary>
- /// Substitutes the path.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="from">From.</param>
- /// <param name="to">To.</param>
- /// <returns>System.String.</returns>
- string SubstitutePath(string path, string from, string to);
-
- /// <summary>
/// Converts the image to local.
/// </summary>
/// <param name="item">The item.</param>
@@ -587,15 +567,8 @@ namespace MediaBrowser.Controller.Library
int GetCount(InternalItemsQuery query);
- void AddExternalSubtitleStreams(
- List<MediaStream> streams,
- string videoPath,
- string[] files);
-
Task RunMetadataSavers(BaseItem item, ItemUpdateType updateReason);
- BaseItem GetParentItem(string parentId, Guid? userId);
-
BaseItem GetParentItem(Guid? parentId, Guid? userId);
}
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
index e63874f21..335222da9 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
@@ -134,7 +134,7 @@ namespace MediaBrowser.Controller.LiveTv
{
Id = Id.ToString("N", CultureInfo.InvariantCulture),
Protocol = PathProtocol ?? MediaProtocol.File,
- MediaStreams = new List<MediaStream>(),
+ MediaStreams = Array.Empty<MediaStream>(),
Name = Name,
Path = Path,
RunTimeTicks = RunTimeTicks,
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index e76a478a5..6164e51cd 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -57,7 +57,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
- <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.376" PrivateAssets="All" />
+ <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.406" PrivateAssets="All" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
</ItemGroup>
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index bde10dbbf..633ba2d76 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -12,6 +12,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
@@ -28,7 +29,7 @@ namespace MediaBrowser.Controller.MediaEncoding
private const string VideotoolboxAlias = "vt";
private const string OpenclAlias = "ocl";
private const string CudaAlias = "cu";
-
+ private readonly IApplicationPaths _appPaths;
private readonly IMediaEncoder _mediaEncoder;
private readonly ISubtitleEncoder _subtitleEncoder;
@@ -51,9 +52,11 @@ namespace MediaBrowser.Controller.MediaEncoding
};
public EncodingHelper(
+ IApplicationPaths appPaths,
IMediaEncoder mediaEncoder,
ISubtitleEncoder subtitleEncoder)
{
+ _appPaths = appPaths;
_mediaEncoder = mediaEncoder;
_subtitleEncoder = subtitleEncoder;
}
@@ -81,7 +84,6 @@ namespace MediaBrowser.Controller.MediaEncoding
{ "vaapi", hwEncoder + "_vaapi" },
{ "videotoolbox", hwEncoder + "_videotoolbox" },
{ "v4l2m2m", hwEncoder + "_v4l2m2m" },
- { "omx", hwEncoder + "_omx" },
};
if (!string.IsNullOrEmpty(hwType)
@@ -578,13 +580,13 @@ namespace MediaBrowser.Controller.MediaEncoding
options);
}
- private string GetVaapiDeviceArgs(string renderNodePath, string kernelDriver, string driver, string alias)
+ private string GetVaapiDeviceArgs(string renderNodePath, string driver, string kernelDriver, string alias)
{
alias ??= VaapiAlias;
renderNodePath = renderNodePath ?? "/dev/dri/renderD128";
- var options = string.IsNullOrEmpty(kernelDriver) || string.IsNullOrEmpty(driver)
+ var options = string.IsNullOrEmpty(driver)
? renderNodePath
- : ",kernel_driver=" + kernelDriver + ",driver=" + driver;
+ : ",driver=" + driver + (string.IsNullOrEmpty(kernelDriver) ? string.Empty : ",kernel_driver=" + kernelDriver);
return string.Format(
CultureInfo.InvariantCulture,
@@ -599,7 +601,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (OperatingSystem.IsLinux())
{
// derive qsv from vaapi device
- return GetVaapiDeviceArgs(null, "i915", "iHD", VaapiAlias) + arg + "@" + VaapiAlias;
+ return GetVaapiDeviceArgs(null, "iHD", "i915", VaapiAlias) + arg + "@" + VaapiAlias;
}
if (OperatingSystem.IsWindows())
@@ -688,7 +690,19 @@ namespace MediaBrowser.Controller.MediaEncoding
return string.Empty;
}
- args.Append(GetVaapiDeviceArgs(options.VaapiDevice, null, null, VaapiAlias));
+ if (_mediaEncoder.IsVaapiDeviceInteliHD)
+ {
+ args.Append(GetVaapiDeviceArgs(null, "iHD", null, VaapiAlias));
+ }
+ else if (_mediaEncoder.IsVaapiDeviceInteli965)
+ {
+ args.Append(GetVaapiDeviceArgs(null, "i965", null, VaapiAlias));
+ }
+ else
+ {
+ args.Append(GetVaapiDeviceArgs(options.VaapiDevice, null, null, VaapiAlias));
+ }
+
var filterDevArgs = GetFilterHwDeviceArgs(VaapiAlias);
if (isHwTonemapAvailable && IsOpenclFullSupported())
@@ -768,10 +782,6 @@ namespace MediaBrowser.Controller.MediaEncoding
args.Append(GetCudaDeviceArgs(0, CudaAlias))
.Append(GetFilterHwDeviceArgs(CudaAlias));
-
- // workaround for "No decoder surfaces left" error,
- // but will increase vram usage. https://trac.ffmpeg.org/ticket/7562
- args.Append(" -extra_hw_frames 3");
}
else if (string.Equals(optHwaccelType, "amf", StringComparison.OrdinalIgnoreCase))
{
@@ -832,8 +842,9 @@ namespace MediaBrowser.Controller.MediaEncoding
/// </summary>
/// <param name="state">Encoding state.</param>
/// <param name="options">Encoding options.</param>
+ /// <param name="segmentContainer">Segment Container.</param>
/// <returns>Input arguments.</returns>
- public string GetInputArgument(EncodingJobInfo state, EncodingOptions options)
+ public string GetInputArgument(EncodingJobInfo state, EncodingOptions options, string segmentContainer)
{
var arg = new StringBuilder();
var inputVidHwaccelArgs = GetInputVideoHwaccelArgs(state, options);
@@ -870,7 +881,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Also seek the external subtitles stream.
- var seekSubParam = GetFastSeekCommandLineParameter(state, options);
+ var seekSubParam = GetFastSeekCommandLineParameter(state, options, segmentContainer);
if (!string.IsNullOrEmpty(seekSubParam))
{
arg.Append(' ').Append(seekSubParam);
@@ -887,7 +898,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (state.AudioStream != null && state.AudioStream.IsExternal)
{
// Also seek the external audio stream.
- var seekAudioParam = GetFastSeekCommandLineParameter(state, options);
+ var seekAudioParam = GetFastSeekCommandLineParameter(state, options, segmentContainer);
if (!string.IsNullOrEmpty(seekAudioParam))
{
arg.Append(' ').Append(seekAudioParam);
@@ -958,6 +969,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// Apply aac_adtstoasc bitstream filter when media source is in mpegts.
if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase)
&& (string.Equals(mediaSourceContainer, "mpegts", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(mediaSourceContainer, "aac", StringComparison.OrdinalIgnoreCase)
|| string.Equals(mediaSourceContainer, "hls", StringComparison.OrdinalIgnoreCase)))
{
bitStreamArgs = GetBitStreamArgs(state.AudioStream);
@@ -1080,6 +1092,12 @@ namespace MediaBrowser.Controller.MediaEncoding
var alphaParam = enableAlpha ? ":alpha=1" : string.Empty;
var sub2videoParam = enableSub2video ? ":sub2video=1" : string.Empty;
+ var fontPath = Path.Combine(_appPaths.CachePath, "attachments", state.MediaSource.Id);
+ var fontParam = string.Format(
+ CultureInfo.InvariantCulture,
+ ":fontsdir='{0}'",
+ _mediaEncoder.EscapeSubtitleFilterPath(fontPath));
+
// TODO
// var fallbackFontPath = Path.Combine(_appPaths.ProgramDataPath, "fonts", "DroidSansFallback.ttf");
// string fallbackFontParam = string.Empty;
@@ -1120,11 +1138,12 @@ namespace MediaBrowser.Controller.MediaEncoding
// TODO: Perhaps also use original_size=1920x800 ??
return string.Format(
CultureInfo.InvariantCulture,
- "subtitles=f='{0}'{1}{2}{3}{4}",
+ "subtitles=f='{0}'{1}{2}{3}{4}{5}",
_mediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
charsetParam,
alphaParam,
sub2videoParam,
+ fontParam,
// fallbackFontParam,
setPtsParam);
}
@@ -1133,11 +1152,12 @@ namespace MediaBrowser.Controller.MediaEncoding
return string.Format(
CultureInfo.InvariantCulture,
- "subtitles='{0}:si={1}{2}{3}'{4}",
+ "subtitles=f='{0}':si={1}{2}{3}{4}{5}",
_mediaEncoder.EscapeSubtitleFilterPath(mediaPath),
state.InternalSubtitleStreamOffset.ToString(CultureInfo.InvariantCulture),
alphaParam,
sub2videoParam,
+ fontParam,
// fallbackFontParam,
setPtsParam);
}
@@ -1281,11 +1301,6 @@ namespace MediaBrowser.Controller.MediaEncoding
param += " -low_power 1";
}
- if (string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase))
- {
- param += " -pix_fmt nv21";
- }
-
var isVc1 = string.Equals(state.VideoStream?.Codec, "vc1", StringComparison.OrdinalIgnoreCase);
var isLibX265 = string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase);
@@ -1343,29 +1358,37 @@ namespace MediaBrowser.Controller.MediaEncoding
switch (encodingOptions.EncoderPreset)
{
case "veryslow":
-
- param += " -preset slow"; // lossless is only supported on maxwell and newer(2014+)
+ param += " -preset p7";
break;
case "slow":
+ param += " -preset p6";
+ break;
+
case "slower":
- param += " -preset slow";
+ param += " -preset p5";
break;
case "medium":
- param += " -preset medium";
+ param += " -preset p4";
break;
case "fast":
+ param += " -preset p3";
+ break;
+
case "faster":
+ param += " -preset p2";
+ break;
+
case "veryfast":
case "superfast":
case "ultrafast":
- param += " -preset fast";
+ param += " -preset p1";
break;
default:
- param += " -preset default";
+ param += " -preset p4";
break;
}
}
@@ -1571,10 +1594,8 @@ namespace MediaBrowser.Controller.MediaEncoding
if (!string.IsNullOrEmpty(profile))
{
- if (!string.Equals(videoEncoder, "h264_omx", StringComparison.OrdinalIgnoreCase)
- && !string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase))
+ if (!string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase))
{
- // not supported by h264_omx
param += " -profile:v:0 " + profile;
}
}
@@ -1613,8 +1634,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// NVENC cannot adjust the given level, just throw an error.
// level option may cause corrupted frames on AMD VAAPI.
}
- else if (!string.Equals(videoEncoder, "h264_omx", StringComparison.OrdinalIgnoreCase)
- || !string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase))
+ else if (!string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase))
{
param += " -level " + level;
}
@@ -1677,7 +1697,8 @@ namespace MediaBrowser.Controller.MediaEncoding
// Source and target codecs must match
if (string.IsNullOrEmpty(videoStream.Codec)
- || !state.SupportedVideoCodecs.Contains(videoStream.Codec, StringComparison.OrdinalIgnoreCase))
+ || (state.SupportedVideoCodecs.Length != 0
+ && !state.SupportedVideoCodecs.Contains(videoStream.Codec, StringComparison.OrdinalIgnoreCase)))
{
return false;
}
@@ -1780,7 +1801,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return false;
}
- return request.EnableAutoStreamCopy;
+ return true;
}
public bool CanStreamCopyAudio(EncodingJobInfo state, MediaStream audioStream, IEnumerable<string> supportedAudioCodecs)
@@ -1837,17 +1858,11 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Video bitrate must fall within requested value
- if (request.AudioBitRate.HasValue)
+ if (request.AudioBitRate.HasValue
+ && audioStream.BitDepth.HasValue
+ && audioStream.BitRate.Value > request.AudioBitRate.Value)
{
- if (!audioStream.BitRate.HasValue || audioStream.BitRate.Value <= 0)
- {
- return false;
- }
-
- if (audioStream.BitRate.Value > request.AudioBitRate.Value)
- {
- return false;
- }
+ return false;
}
return request.EnableAutoStreamCopy;
@@ -2149,9 +2164,10 @@ namespace MediaBrowser.Controller.MediaEncoding
/// </summary>
/// <param name="state">The state.</param>
/// <param name="options">The options.</param>
+ /// <param name="segmentContainer">Segment Container.</param>
/// <returns>System.String.</returns>
/// <value>The fast seek command line parameter.</value>
- public string GetFastSeekCommandLineParameter(EncodingJobInfo state, EncodingOptions options)
+ public string GetFastSeekCommandLineParameter(EncodingJobInfo state, EncodingOptions options, string segmentContainer)
{
var time = state.BaseRequest.StartTimeTicks ?? 0;
var seekParam = string.Empty;
@@ -2163,9 +2179,13 @@ namespace MediaBrowser.Controller.MediaEncoding
if (state.IsVideoRequest)
{
var outputVideoCodec = GetVideoEncoder(state, options);
+ var segmentFormat = GetSegmentFileExtension(segmentContainer).TrimStart('.');
// Important: If this is ever re-enabled, make sure not to use it with wtv because it breaks seeking
+ // Disable -noaccurate_seek on mpegts container due to the timestamps issue on some clients,
+ // but it's still required for fMP4 container otherwise the audio can't be synced to the video.
if (!string.Equals(state.InputContainer, "wtv", StringComparison.OrdinalIgnoreCase)
+ && !string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase)
&& state.TranscodingType != TranscodingJobType.Progressive
&& !state.EnableBreakOnNonKeyFrames(outputVideoCodec)
&& (state.BaseRequest.StartTimeTicks ?? 0) > 0)
@@ -2695,6 +2715,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var vidDecoder = GetHardwareVideoDecoder(state, options) ?? string.Empty;
var isSwDecoder = string.IsNullOrEmpty(vidDecoder);
var isVaapiEncoder = vidEncoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase);
+ var isV4l2Encoder = vidEncoder.Contains("h264_v4l2m2m", StringComparison.OrdinalIgnoreCase);
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
@@ -2723,6 +2744,10 @@ namespace MediaBrowser.Controller.MediaEncoding
{
outFormat = "nv12";
}
+ else if (isV4l2Encoder)
+ {
+ outFormat = "yuv420p";
+ }
// sw scale
mainFilters.Add(swScaleFilter);
@@ -2773,16 +2798,15 @@ namespace MediaBrowser.Controller.MediaEncoding
var isSwDecoder = string.IsNullOrEmpty(vidDecoder);
var isSwEncoder = !vidEncoder.Contains("nvenc", StringComparison.OrdinalIgnoreCase);
- // legacy cuvid(resize/deint/sw) pipeline(copy-back)
+ // legacy cuvid pipeline(copy-back)
if ((isSwDecoder && isSwEncoder)
|| !IsCudaFullSupported()
- || !options.EnableEnhancedNvdecDecoder
|| !_mediaEncoder.SupportsFilter("alphasrc"))
{
return GetSwVidFilterChain(state, options, vidEncoder);
}
- // prefered nvdec + cuda filters + nvenc pipeline
+ // prefered nvdec/cuvid + cuda filters + nvenc pipeline
return GetNvidiaVidFiltersPrefered(state, options, vidDecoder, vidEncoder);
}
@@ -2800,11 +2824,11 @@ namespace MediaBrowser.Controller.MediaEncoding
var reqMaxH = state.BaseRequest.MaxHeight;
var threeDFormat = state.MediaSource.Video3DFormat;
- var isNvdecDecoder = vidDecoder.Contains("cuda", StringComparison.OrdinalIgnoreCase);
+ var isNvDecoder = vidDecoder.Contains("cuda", StringComparison.OrdinalIgnoreCase);
var isNvencEncoder = vidEncoder.Contains("nvenc", StringComparison.OrdinalIgnoreCase);
var isSwDecoder = string.IsNullOrEmpty(vidDecoder);
var isSwEncoder = !isNvencEncoder;
- var isCuInCuOut = isNvdecDecoder && isNvencEncoder;
+ var isCuInCuOut = isNvDecoder && isNvencEncoder;
var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.AverageFrameRate ?? 60) <= 30;
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
@@ -2847,7 +2871,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
- if (isNvdecDecoder)
+ if (isNvDecoder)
{
// INPUT cuda surface(vram)
// hw deint
@@ -2871,8 +2895,8 @@ namespace MediaBrowser.Controller.MediaEncoding
}
var memoryOutput = false;
- var isUploadForOclTonemap = isSwDecoder && doCuTonemap;
- if ((isNvdecDecoder && isSwEncoder) || isUploadForOclTonemap)
+ var isUploadForCuTonemap = isSwDecoder && doCuTonemap;
+ if ((isNvDecoder && isSwEncoder) || (isUploadForCuTonemap && hasSubs))
{
memoryOutput = true;
@@ -2882,7 +2906,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// OUTPUT yuv420p surface(memory)
- if (isSwDecoder && isNvencEncoder)
+ if (isSwDecoder && isNvencEncoder && !isUploadForCuTonemap)
{
memoryOutput = true;
}
@@ -4268,11 +4292,6 @@ namespace MediaBrowser.Controller.MediaEncoding
{
return GetVideotoolboxVidDecoder(state, options, videoStream, bitDepth);
}
-
- if (string.Equals(options.HardwareAccelerationType, "omx", StringComparison.OrdinalIgnoreCase))
- {
- return GetOmxVidDecoder(state, options, videoStream, bitDepth);
- }
}
var whichCodec = videoStream.Codec;
@@ -4409,9 +4428,18 @@ namespace MediaBrowser.Controller.MediaEncoding
// Nvidia cuda
if (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
{
- if (options.EnableEnhancedNvdecDecoder && isCudaSupported && isCodecAvailable)
+ if (isCudaSupported && isCodecAvailable)
{
- return " -hwaccel cuda" + (outputHwSurface ? " -hwaccel_output_format cuda" : string.Empty) + (isAv1 ? " -c:v av1" : string.Empty);
+ if (options.EnableEnhancedNvdecDecoder)
+ {
+ // set -threads 1 to nvdec decoder explicitly since it doesn't implement threading support.
+ return " -hwaccel cuda" + (outputHwSurface ? " -hwaccel_output_format cuda" : string.Empty) + " -threads 1" + (isAv1 ? " -c:v av1" : string.Empty);
+ }
+ else
+ {
+ // cuvid decoder doesn't have threading issue.
+ return " -hwaccel cuda" + (outputHwSurface ? " -hwaccel_output_format cuda" : string.Empty);
+ }
}
}
@@ -4521,9 +4549,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return null;
}
- var hwSurface = IsCudaFullSupported()
- && options.EnableEnhancedNvdecDecoder
- && _mediaEncoder.SupportsFilter("alphasrc");
+ var hwSurface = IsCudaFullSupported() && _mediaEncoder.SupportsFilter("alphasrc");
var is8bitSwFormatsNvdec = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase);
var is8_10bitSwFormatsNvdec = is8bitSwFormatsNvdec || string.Equals("yuv420p10le", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase);
// TODO: add more 8/10/12bit and 4:4:4 formats for Nvdec after finishing the ffcheck tool
@@ -4747,43 +4773,6 @@ namespace MediaBrowser.Controller.MediaEncoding
return null;
}
- public string GetOmxVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
- {
- if (!OperatingSystem.IsLinux()
- || !string.Equals(options.HardwareAccelerationType, "omx", StringComparison.OrdinalIgnoreCase))
- {
- return null;
- }
-
- var is8bitSwFormatsOmx = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase);
-
- if (is8bitSwFormatsOmx)
- {
- if (string.Equals("avc", videoStream.Codec, StringComparison.OrdinalIgnoreCase)
- || string.Equals("h264", videoStream.Codec, StringComparison.OrdinalIgnoreCase))
- {
- return GetHwDecoderName(options, "h264", "mmal", "h264", bitDepth);
- }
-
- if (string.Equals("mpeg2video", videoStream.Codec, StringComparison.OrdinalIgnoreCase))
- {
- return GetHwDecoderName(options, "mpeg2", "mmal", "mpeg2video", bitDepth);
- }
-
- if (string.Equals("mpeg4", videoStream.Codec, StringComparison.OrdinalIgnoreCase))
- {
- return GetHwDecoderName(options, "mpeg4", "mmal", "mpeg4", bitDepth);
- }
-
- if (string.Equals("vc1", videoStream.Codec, StringComparison.OrdinalIgnoreCase))
- {
- return GetHwDecoderName(options, "vc1", "mmal", "vc1", bitDepth);
- }
- }
-
- return null;
- }
-
/// <summary>
/// Gets the number of threads.
/// </summary>
@@ -4848,7 +4837,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
- public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOptions)
+ public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOptions, string segmentContainer)
{
var inputModifier = string.Empty;
var probeSizeArgument = string.Empty;
@@ -4884,7 +4873,7 @@ namespace MediaBrowser.Controller.MediaEncoding
inputModifier = inputModifier.Trim();
- inputModifier += " " + GetFastSeekCommandLineParameter(state, encodingOptions);
+ inputModifier += " " + GetFastSeekCommandLineParameter(state, encodingOptions, segmentContainer);
inputModifier = inputModifier.Trim();
if (state.InputProtocol == MediaProtocol.Rtsp)
@@ -5191,13 +5180,13 @@ namespace MediaBrowser.Controller.MediaEncoding
var threads = GetNumberOfThreads(state, encodingOptions, videoCodec);
- var inputModifier = GetInputModifier(state, encodingOptions);
+ var inputModifier = GetInputModifier(state, encodingOptions, null);
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}{2} {3} {4} -map_metadata -1 -map_chapters -1 -threads {5} {6}{7}{8} -y \"{9}\"",
inputModifier,
- GetInputArgument(state, encodingOptions),
+ GetInputArgument(state, encodingOptions, null),
keyFrame,
GetMapArgs(state),
GetProgressiveVideoArguments(state, encodingOptions, videoCodec, defaultPreset),
@@ -5379,13 +5368,13 @@ namespace MediaBrowser.Controller.MediaEncoding
var threads = GetNumberOfThreads(state, encodingOptions, null);
- var inputModifier = GetInputModifier(state, encodingOptions);
+ var inputModifier = GetInputModifier(state, encodingOptions, null);
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}{7}{8} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1{6} -y \"{5}\"",
inputModifier,
- GetInputArgument(state, encodingOptions),
+ GetInputArgument(state, encodingOptions, null),
threads,
" -vn",
string.Join(' ', audioTranscodeParams),
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index c4affa567..4f6743590 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Text.Json.Serialization;
using Jellyfin.Data.Entities;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Drawing;
@@ -23,7 +24,7 @@ namespace MediaBrowser.Controller.MediaEncoding
public int? OutputAudioBitrate;
public int? OutputAudioChannels;
- private TranscodeReason[] _transcodeReasons = null;
+ private TranscodeReason? _transcodeReasons = null;
public EncodingJobInfo(TranscodingJobType jobType)
{
@@ -34,25 +35,23 @@ namespace MediaBrowser.Controller.MediaEncoding
SupportedSubtitleCodecs = Array.Empty<string>();
}
- public TranscodeReason[] TranscodeReasons
+ public TranscodeReason TranscodeReason
{
get
{
- if (_transcodeReasons == null)
+ if (!_transcodeReasons.HasValue)
{
if (BaseRequest.TranscodeReasons == null)
{
- return Array.Empty<TranscodeReason>();
+ _transcodeReasons = 0;
+ return 0;
}
- _transcodeReasons = BaseRequest.TranscodeReasons
- .Split(',')
- .Where(i => !string.IsNullOrEmpty(i))
- .Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true))
- .ToArray();
+ _ = Enum.TryParse<TranscodeReason>(BaseRequest.TranscodeReasons, out var reason);
+ _transcodeReasons = reason;
}
- return _transcodeReasons;
+ return _transcodeReasons.Value;
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs b/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs
index 4e7e26624..09840d2ee 100644
--- a/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs
+++ b/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs
@@ -6,6 +6,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.MediaEncoding
@@ -17,5 +18,17 @@ namespace MediaBrowser.Controller.MediaEncoding
string mediaSourceId,
int attachmentStreamIndex,
CancellationToken cancellationToken);
+
+ Task ExtractAllAttachments(
+ string inputFile,
+ MediaSourceInfo mediaSource,
+ string outputPath,
+ CancellationToken cancellationToken);
+
+ Task ExtractAllAttachmentsExternal(
+ string inputArgument,
+ string id,
+ string outputPath,
+ CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index 837bf0bb2..24f7b5cd3 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -15,16 +15,9 @@ namespace MediaBrowser.Controller.Persistence
/// <summary>
/// Provides an interface to implement an Item repository.
/// </summary>
- public interface IItemRepository : IRepository
+ public interface IItemRepository : IDisposable
{
/// <summary>
- /// Saves an item.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- void SaveItem(BaseItem item, CancellationToken cancellationToken);
-
- /// <summary>
/// Deletes the item.
/// </summary>
/// <param name="id">The identifier.</param>
@@ -81,7 +74,7 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="id">The identifier.</param>
/// <param name="streams">The streams.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- void SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken);
+ void SaveMediaStreams(Guid id, IReadOnlyList<MediaStream> streams, CancellationToken cancellationToken);
/// <summary>
/// Gets the media attachments.
@@ -99,13 +92,6 @@ namespace MediaBrowser.Controller.Persistence
void SaveMediaAttachments(Guid id, IReadOnlyList<MediaAttachment> attachments, CancellationToken cancellationToken);
/// <summary>
- /// Gets the item ids.
- /// </summary>
- /// <param name="query">The query.</param>
- /// <returns>IEnumerable&lt;Guid&gt;.</returns>
- QueryResult<Guid> GetItemIds(InternalItemsQuery query);
-
- /// <summary>
/// Gets the items.
/// </summary>
/// <param name="query">The query.</param>
@@ -141,13 +127,6 @@ namespace MediaBrowser.Controller.Persistence
List<string> GetPeopleNames(InternalPeopleQuery query);
/// <summary>
- /// Gets the item ids with path.
- /// </summary>
- /// <param name="query">The query.</param>
- /// <returns>QueryResult&lt;Tuple&lt;Guid, System.String&gt;&gt;.</returns>
- List<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query);
-
- /// <summary>
/// Gets the item list.
/// </summary>
/// <param name="query">The query.</param>
diff --git a/MediaBrowser.Controller/Persistence/IRepository.cs b/MediaBrowser.Controller/Persistence/IRepository.cs
deleted file mode 100644
index 42f285076..000000000
--- a/MediaBrowser.Controller/Persistence/IRepository.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Persistence
-{
- /// <summary>
- /// Provides a base interface for all the repository interfaces.
- /// </summary>
- public interface IRepository : IDisposable
- {
- /// <summary>
- /// Gets the name of the repository.
- /// </summary>
- /// <value>The name.</value>
- string Name { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
index c43acfb6d..f2fb2826a 100644
--- a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
@@ -1,5 +1,6 @@
#nullable disable
+using System;
using System.Collections.Generic;
using System.Threading;
using MediaBrowser.Controller.Entities;
@@ -9,7 +10,7 @@ namespace MediaBrowser.Controller.Persistence
/// <summary>
/// Provides an interface to implement a UserData repository.
/// </summary>
- public interface IUserDataRepository : IRepository
+ public interface IUserDataRepository : IDisposable
{
/// <summary>
/// Saves the user data.
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 89f3bdf46..828ecb2c5 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -233,7 +233,7 @@ namespace MediaBrowser.Controller.Playlists
return base.IsVisible(user);
}
- if (user.Id == OwnerUserId)
+ if (user.Id.Equals(OwnerUserId))
{
return true;
}
@@ -244,8 +244,8 @@ namespace MediaBrowser.Controller.Playlists
return base.IsVisible(user);
}
- var userId = user.Id.ToString("N", CultureInfo.InvariantCulture);
- return shares.Any(share => string.Equals(share.UserId, userId, StringComparison.OrdinalIgnoreCase));
+ var userId = user.Id;
+ return shares.Any(share => Guid.TryParse(share.UserId, out var id) && id.Equals(userId));
}
public override bool IsVisibleStandalone(User user)
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index 6134c0cf3..c2ca23386 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -39,6 +39,8 @@ namespace MediaBrowser.Controller.Session
AdditionalUsers = Array.Empty<SessionUserInfo>();
PlayState = new PlayerStateInfo();
SessionControllers = Array.Empty<ISessionController>();
+ NowPlayingQueue = Array.Empty<QueueItem>();
+ NowPlayingQueueFullItems = Array.Empty<BaseItemDto>();
}
public PlayerStateInfo PlayState { get; set; }
@@ -219,7 +221,9 @@ namespace MediaBrowser.Controller.Session
}
}
- public QueueItem[] NowPlayingQueue { get; set; }
+ public IReadOnlyList<QueueItem> NowPlayingQueue { get; set; }
+
+ public IReadOnlyList<BaseItemDto> NowPlayingQueueFullItems { get; set; }
public bool HasCustomDeviceName { get; set; }