Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ba76a8f3ad | |||
| 8cd5652157 | |||
| 8aff4227d9 | |||
| daca285568 | |||
| fbb9a0b2c7 | |||
| 29b3aa8543 | |||
| 94f3725208 | |||
| 0ee81e87be | |||
| c491a918c2 | |||
| 1e7e46cb82 | |||
| 5ae444d96d | |||
| ee7ad83427 |
@@ -36,7 +36,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Naming</PackageId>
|
<PackageId>Jellyfin.Naming</PackageId>
|
||||||
<VersionPrefix>10.11.3</VersionPrefix>
|
<VersionPrefix>10.11.4</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -497,8 +497,17 @@ namespace Emby.Server.Implementations.IO
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual bool AreEqual(string path1, string path2)
|
public virtual bool AreEqual(string path1, string path2)
|
||||||
{
|
{
|
||||||
return Path.TrimEndingDirectorySeparator(path1).Equals(
|
if (string.IsNullOrWhiteSpace(path1) || string.IsNullOrWhiteSpace(path2))
|
||||||
Path.TrimEndingDirectorySeparator(path2),
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized1 = Path.TrimEndingDirectorySeparator(path1);
|
||||||
|
var normalized2 = Path.TrimEndingDirectorySeparator(path2);
|
||||||
|
|
||||||
|
return string.Equals(
|
||||||
|
normalized1,
|
||||||
|
normalized2,
|
||||||
_isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
|
_isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -347,8 +347,8 @@ pli||pi|Pali|pali
|
|||||||
pol||pl|Polish|polonais
|
pol||pl|Polish|polonais
|
||||||
pon|||Pohnpeian|pohnpei
|
pon|||Pohnpeian|pohnpei
|
||||||
por||pt|Portuguese|portugais
|
por||pt|Portuguese|portugais
|
||||||
por||pt-pt|Portuguese (Portugal)|portugais (pt-pt)
|
pop||pt-pt|Portuguese (Portugal)|portugais (pt-pt)
|
||||||
por||pt-br|Portuguese (Brazil)|portugais (pt-br)
|
pob||pt-br|Portuguese (Brazil)|portugais (pt-br)
|
||||||
pra|||Prakrit languages|prâkrit, langues
|
pra|||Prakrit languages|prâkrit, langues
|
||||||
pro|||Provençal, Old (to 1500)|provençal ancien (jusqu'à 1500)
|
pro|||Provençal, Old (to 1500)|provençal ancien (jusqu'à 1500)
|
||||||
pus||ps|Pushto; Pashto|pachto
|
pus||ps|Pushto; Pashto|pachto
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Data</PackageId>
|
<PackageId>Jellyfin.Data</PackageId>
|
||||||
<VersionPrefix>10.11.3</VersionPrefix>
|
<VersionPrefix>10.11.4</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -618,12 +618,18 @@ public sealed class BaseItemRepository
|
|||||||
{
|
{
|
||||||
context.BaseItemProviders.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
context.BaseItemProviders.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
||||||
context.BaseItemImageInfos.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
context.BaseItemImageInfos.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
||||||
|
context.BaseItemMetadataFields.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
||||||
|
|
||||||
if (entity.Images is { Count: > 0 })
|
if (entity.Images is { Count: > 0 })
|
||||||
{
|
{
|
||||||
context.BaseItemImageInfos.AddRange(entity.Images);
|
context.BaseItemImageInfos.AddRange(entity.Images);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entity.LockedFields is { Count: > 0 })
|
||||||
|
{
|
||||||
|
context.BaseItemMetadataFields.AddRange(entity.LockedFields);
|
||||||
|
}
|
||||||
|
|
||||||
context.BaseItems.Attach(entity).State = EntityState.Modified;
|
context.BaseItems.Attach(entity).State = EntityState.Modified;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1647,19 +1653,18 @@ public sealed class BaseItemRepository
|
|||||||
var tags = filter.Tags.ToList();
|
var tags = filter.Tags.ToList();
|
||||||
var excludeTags = filter.ExcludeTags.ToList();
|
var excludeTags = filter.ExcludeTags.ToList();
|
||||||
|
|
||||||
if (filter.IsMovie == true)
|
if (filter.IsMovie.HasValue)
|
||||||
{
|
{
|
||||||
if (filter.IncludeItemTypes.Length == 0
|
var shouldIncludeAllMovieTypes = filter.IsMovie.Value
|
||||||
|| filter.IncludeItemTypes.Contains(BaseItemKind.Movie)
|
&& (filter.IncludeItemTypes.Length == 0
|
||||||
|| filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
|
|| filter.IncludeItemTypes.Contains(BaseItemKind.Movie)
|
||||||
|
|| filter.IncludeItemTypes.Contains(BaseItemKind.Trailer));
|
||||||
|
|
||||||
|
if (!shouldIncludeAllMovieTypes)
|
||||||
{
|
{
|
||||||
baseQuery = baseQuery.Where(e => e.IsMovie);
|
baseQuery = baseQuery.Where(e => e.IsMovie == filter.IsMovie.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (filter.IsMovie.HasValue)
|
|
||||||
{
|
|
||||||
baseQuery = baseQuery.Where(e => e.IsMovie == filter.IsMovie);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.IsSeries.HasValue)
|
if (filter.IsSeries.HasValue)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,9 +33,11 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Microsoft.OpenApi.Any;
|
using Microsoft.OpenApi.Any;
|
||||||
using Microsoft.OpenApi.Interfaces;
|
using Microsoft.OpenApi.Interfaces;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.Swagger;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
using AuthenticationSchemes = Jellyfin.Api.Constants.AuthenticationSchemes;
|
using AuthenticationSchemes = Jellyfin.Api.Constants.AuthenticationSchemes;
|
||||||
|
|
||||||
@@ -259,7 +261,8 @@ namespace Jellyfin.Server.Extensions
|
|||||||
c.OperationFilter<FileRequestFilter>();
|
c.OperationFilter<FileRequestFilter>();
|
||||||
c.OperationFilter<ParameterObsoleteFilter>();
|
c.OperationFilter<ParameterObsoleteFilter>();
|
||||||
c.DocumentFilter<AdditionalModelFilter>();
|
c.DocumentFilter<AdditionalModelFilter>();
|
||||||
});
|
})
|
||||||
|
.Replace(ServiceDescriptor.Transient<ISwaggerProvider, CachingOpenApiProvider>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddPolicy(this AuthorizationOptions authorizationOptions, string policyName, IAuthorizationRequirement authorizationRequirement)
|
private static void AddPolicy(this AuthorizationOptions authorizationOptions, string policyName, IAuthorizationRequirement authorizationRequirement)
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.Swagger;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
|
||||||
|
namespace Jellyfin.Server.Filters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OpenApi provider with caching.
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class CachingOpenApiProvider : ISwaggerProvider
|
||||||
|
{
|
||||||
|
private const string CacheKey = "openapi.json";
|
||||||
|
|
||||||
|
private static readonly MemoryCacheEntryOptions _cacheOptions = new() { SlidingExpiration = TimeSpan.FromMinutes(5) };
|
||||||
|
private static readonly SemaphoreSlim _lock = new(1, 1);
|
||||||
|
private static readonly TimeSpan _lockTimeout = TimeSpan.FromSeconds(1);
|
||||||
|
|
||||||
|
private readonly IMemoryCache _memoryCache;
|
||||||
|
private readonly SwaggerGenerator _swaggerGenerator;
|
||||||
|
private readonly SwaggerGeneratorOptions _swaggerGeneratorOptions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CachingOpenApiProvider"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="optionsAccessor">The options accessor.</param>
|
||||||
|
/// <param name="apiDescriptionsProvider">The api descriptions provider.</param>
|
||||||
|
/// <param name="schemaGenerator">The schema generator.</param>
|
||||||
|
/// <param name="memoryCache">The memory cache.</param>
|
||||||
|
public CachingOpenApiProvider(
|
||||||
|
IOptions<SwaggerGeneratorOptions> optionsAccessor,
|
||||||
|
IApiDescriptionGroupCollectionProvider apiDescriptionsProvider,
|
||||||
|
ISchemaGenerator schemaGenerator,
|
||||||
|
IMemoryCache memoryCache)
|
||||||
|
{
|
||||||
|
_swaggerGeneratorOptions = optionsAccessor.Value;
|
||||||
|
_swaggerGenerator = new SwaggerGenerator(_swaggerGeneratorOptions, apiDescriptionsProvider, schemaGenerator);
|
||||||
|
_memoryCache = memoryCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public OpenApiDocument GetSwagger(string documentName, string? host = null, string? basePath = null)
|
||||||
|
{
|
||||||
|
if (_memoryCache.TryGetValue(CacheKey, out OpenApiDocument? openApiDocument) && openApiDocument is not null)
|
||||||
|
{
|
||||||
|
return AdjustDocument(openApiDocument, host, basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var acquired = _lock.Wait(_lockTimeout);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_memoryCache.TryGetValue(CacheKey, out openApiDocument) && openApiDocument is not null)
|
||||||
|
{
|
||||||
|
return AdjustDocument(openApiDocument, host, basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acquired)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("OpenApi document is generating");
|
||||||
|
}
|
||||||
|
|
||||||
|
openApiDocument = _swaggerGenerator.GetSwagger(documentName);
|
||||||
|
_memoryCache.Set(CacheKey, openApiDocument, _cacheOptions);
|
||||||
|
return AdjustDocument(openApiDocument, host, basePath);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (acquired)
|
||||||
|
{
|
||||||
|
_lock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpenApiDocument AdjustDocument(OpenApiDocument document, string? host, string? basePath)
|
||||||
|
{
|
||||||
|
document.Servers = _swaggerGeneratorOptions.Servers.Count != 0
|
||||||
|
? _swaggerGeneratorOptions.Servers
|
||||||
|
: string.IsNullOrEmpty(host) && string.IsNullOrEmpty(basePath)
|
||||||
|
? []
|
||||||
|
: [new OpenApiServer { Url = $"{host}{basePath}" }];
|
||||||
|
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Common</PackageId>
|
<PackageId>Jellyfin.Common</PackageId>
|
||||||
<VersionPrefix>10.11.3</VersionPrefix>
|
<VersionPrefix>10.11.4</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1409,7 +1409,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
if (this is BoxSet && (query.OrderBy is null || query.OrderBy.Count == 0))
|
if (this is BoxSet && (query.OrderBy is null || query.OrderBy.Count == 0))
|
||||||
{
|
{
|
||||||
realChildren = realChildren
|
realChildren = realChildren
|
||||||
.OrderBy(e => e.ProductionYear ?? int.MaxValue)
|
.OrderBy(e => e.PremiereDate ?? DateTime.MaxValue)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,29 @@ public static class FileSystemHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resolves a single link hop for the specified path.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Returns <c>null</c> if the path is not a symbolic link or the filesystem does not support link resolution (e.g., exFAT).
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="path">The file path to resolve.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="FileInfo"/> representing the next link target if the path is a link; otherwise, <c>null</c>.
|
||||||
|
/// </returns>
|
||||||
|
private static FileInfo? Resolve(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return File.ResolveLinkTarget(path, returnFinalTarget: false) as FileInfo;
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
// Filesystem doesn't support links (e.g., exFAT).
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target of the specified file link.
|
/// Gets the target of the specified file link.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -84,23 +107,26 @@ public static class FileSystemHelper
|
|||||||
|
|
||||||
if (!returnFinalTarget)
|
if (!returnFinalTarget)
|
||||||
{
|
{
|
||||||
return File.ResolveLinkTarget(linkPath, returnFinalTarget: false) as FileInfo;
|
return Resolve(linkPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (File.ResolveLinkTarget(linkPath, returnFinalTarget: false) is not FileInfo targetInfo)
|
var targetInfo = Resolve(linkPath);
|
||||||
{
|
if (targetInfo is null || !targetInfo.Exists)
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!targetInfo.Exists)
|
|
||||||
{
|
{
|
||||||
return targetInfo;
|
return targetInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentPath = targetInfo.FullName;
|
var currentPath = targetInfo.FullName;
|
||||||
var visited = new HashSet<string>(StringComparer.Ordinal) { linkPath, currentPath };
|
var visited = new HashSet<string>(StringComparer.Ordinal) { linkPath, currentPath };
|
||||||
while (File.ResolveLinkTarget(currentPath, returnFinalTarget: false) is FileInfo linkInfo)
|
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
|
var linkInfo = Resolve(currentPath);
|
||||||
|
if (linkInfo is null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
var targetPath = linkInfo.FullName;
|
var targetPath = linkInfo.FullName;
|
||||||
|
|
||||||
// If an infinite loop is detected, return the file info for the
|
// If an infinite loop is detected, return the file info for the
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Controller</PackageId>
|
<PackageId>Jellyfin.Controller</PackageId>
|
||||||
<VersionPrefix>10.11.3</VersionPrefix>
|
<VersionPrefix>10.11.4</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -2378,6 +2378,13 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
var requestHasSDR = requestedRangeTypes.Contains(VideoRangeType.SDR.ToString(), StringComparison.OrdinalIgnoreCase);
|
var requestHasSDR = requestedRangeTypes.Contains(VideoRangeType.SDR.ToString(), StringComparison.OrdinalIgnoreCase);
|
||||||
var requestHasDOVI = requestedRangeTypes.Contains(VideoRangeType.DOVI.ToString(), StringComparison.OrdinalIgnoreCase);
|
var requestHasDOVI = requestedRangeTypes.Contains(VideoRangeType.DOVI.ToString(), StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
// If SDR is the only supported range, we should not copy any of the HDR streams.
|
||||||
|
// All the following copy check assumes at least one HDR format is supported.
|
||||||
|
if (requestedRangeTypes.Length == 1 && requestHasSDR && videoStream.VideoRangeType != VideoRangeType.SDR)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// If the client does not support DOVI and the video stream is DOVI without fallback, we should not copy it.
|
// If the client does not support DOVI and the video stream is DOVI without fallback, we should not copy it.
|
||||||
if (!requestHasDOVI && videoStream.VideoRangeType == VideoRangeType.DOVI)
|
if (!requestHasDOVI && videoStream.VideoRangeType == VideoRangeType.DOVI)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using BDInfo.IO;
|
using BDInfo.IO;
|
||||||
@@ -58,6 +59,8 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsHidden(ReadOnlySpan<char> name) => name.StartsWith('.');
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the directories.
|
/// Gets the directories.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -65,6 +68,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
|||||||
public IDirectoryInfo[] GetDirectories()
|
public IDirectoryInfo[] GetDirectories()
|
||||||
{
|
{
|
||||||
return _fileSystem.GetDirectories(_impl.FullName)
|
return _fileSystem.GetDirectories(_impl.FullName)
|
||||||
|
.Where(d => !IsHidden(d.Name))
|
||||||
.Select(x => new BdInfoDirectoryInfo(_fileSystem, x))
|
.Select(x => new BdInfoDirectoryInfo(_fileSystem, x))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
@@ -76,6 +80,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
|||||||
public IFileInfo[] GetFiles()
|
public IFileInfo[] GetFiles()
|
||||||
{
|
{
|
||||||
return _fileSystem.GetFiles(_impl.FullName)
|
return _fileSystem.GetFiles(_impl.FullName)
|
||||||
|
.Where(d => !IsHidden(d.Name))
|
||||||
.Select(x => new BdInfoFileInfo(x))
|
.Select(x => new BdInfoFileInfo(x))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
@@ -88,6 +93,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
|||||||
public IFileInfo[] GetFiles(string searchPattern)
|
public IFileInfo[] GetFiles(string searchPattern)
|
||||||
{
|
{
|
||||||
return _fileSystem.GetFiles(_impl.FullName, new[] { searchPattern }, false, false)
|
return _fileSystem.GetFiles(_impl.FullName, new[] { searchPattern }, false, false)
|
||||||
|
.Where(d => !IsHidden(d.Name))
|
||||||
.Select(x => new BdInfoFileInfo(x))
|
.Select(x => new BdInfoFileInfo(x))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
@@ -105,6 +111,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
|||||||
new[] { searchPattern },
|
new[] { searchPattern },
|
||||||
false,
|
false,
|
||||||
searchOption == SearchOption.AllDirectories)
|
searchOption == SearchOption.AllDirectories)
|
||||||
|
.Where(d => !IsHidden(d.Name))
|
||||||
.Select(x => new BdInfoFileInfo(x))
|
.Select(x => new BdInfoFileInfo(x))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -511,7 +511,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
? "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_chapters -show_format"
|
? "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_chapters -show_format"
|
||||||
: "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_format";
|
: "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_format";
|
||||||
|
|
||||||
if (!isAudio && _proberSupportsFirstVideoFrame)
|
if (protocol == MediaProtocol.File && !isAudio && _proberSupportsFirstVideoFrame)
|
||||||
{
|
{
|
||||||
args += " -show_frames -only_first_vframe";
|
args += " -show_frames -only_first_vframe";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Model</PackageId>
|
<PackageId>Jellyfin.Model</PackageId>
|
||||||
<VersionPrefix>10.11.3</VersionPrefix>
|
<VersionPrefix>10.11.4</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -151,9 +151,9 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
updateType |= beforeSaveResult;
|
updateType |= beforeSaveResult;
|
||||||
|
|
||||||
if (!isFirstRefresh)
|
if (isFirstRefresh)
|
||||||
{
|
{
|
||||||
updateType = await SaveInternal(item, refreshOptions, updateType, isFirstRefresh, requiresRefresh, metadataResult, cancellationToken).ConfigureAwait(false);
|
await SaveItemAsync(metadataResult, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next run metadata providers
|
// Next run metadata providers
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("10.11.3")]
|
[assembly: AssemblyVersion("10.11.4")]
|
||||||
[assembly: AssemblyFileVersion("10.11.3")]
|
[assembly: AssemblyFileVersion("10.11.4")]
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Extensions</PackageId>
|
<PackageId>Jellyfin.Extensions</PackageId>
|
||||||
<VersionPrefix>10.11.3</VersionPrefix>
|
<VersionPrefix>10.11.4</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user