Compare commits

..

14 Commits

Author SHA1 Message Date
Jellyfin Release Bot 24d482b36b Bump version to 10.9.10 2024-08-25 02:34:36 -04:00
Dmitry Lyzo fff4477a93 Apply all codec conditions (#12499) 2024-08-23 07:54:12 -06:00
Fredrik Eriksson 9810d22d96 Revert "NextUp query respects Limit (#11956)" (#12414)
fix from PR #11956 leads to unexpected behaviour as
Fixes: #12367
2024-08-23 07:54:02 -06:00
ikelos 5027e3cd53 Include AVIF extension for support images (#12415) 2024-08-22 08:04:50 -06:00
Niels van Velzen 9645955629 Set Content-Disposition header to attachment for image endpoints (#12490) 2024-08-22 08:01:10 -06:00
Niels van Velzen 078ee1f2de Merge pull request #12493 from jellyfin/fix-ts-bsf
Fix bitstream filter not applied to videos in TS container
2024-08-22 15:50:56 +02:00
Nyanmisaka 236c7649dd Fix bitstream filter not applied to videos in TS container
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
2024-08-21 22:52:08 +08:00
Bond-009 c1e52df0b7 Fix the record series button missing on many programs (port of #12398) (#12481)
Co-authored-by: grumpycat <bryan.pauquette@gmail.com>
2024-08-20 11:13:37 -06:00
Bond-009 be949af59e Merge pull request #12425 from scampower3/10.9.z-dont-force-virtual
Don't force non-virtual when all episodes in season are isMissing=true
2024-08-14 16:10:30 +02:00
Bond-009 122da8f447 Merge pull request #12443 from gnattu/check-attach-path-for-null
Check attachment path for null before use
2024-08-14 16:10:11 +02:00
gnattu 486c7fa51e Check attachment path for null before use
This one is particularly nasty because the `Path` is not supposed to be nullable. However, fixing it in the parser and type constructor is beyond the scope of the 10.9 release. For now, just check with `IsNullOrEmpty`.

Signed-off-by: gnattu <gnattuoc@me.com>
2024-08-14 04:44:35 +08:00
LJQ 6709c80f0a Don't force non-virtual when all episodes in season have isMissing flag. 2024-08-11 18:06:09 +08:00
Niels van Velzen 3f3145600c Merge pull request #12390 from justinkb/fix-sa1201
fix SA1201 issue
2024-08-05 14:19:48 +02:00
Paul Mulders bc613b8344 fix SA1201 issue 2024-08-05 13:22:24 +02:00
18 changed files with 38 additions and 25 deletions
+1 -1
View File
@@ -36,7 +36,7 @@
<PropertyGroup> <PropertyGroup>
<Authors>Jellyfin Contributors</Authors> <Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Naming</PackageId> <PackageId>Jellyfin.Naming</PackageId>
<VersionPrefix>10.9.9</VersionPrefix> <VersionPrefix>10.9.10</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>
@@ -91,7 +91,7 @@ namespace Emby.Server.Implementations.TV
} }
string? presentationUniqueKey = null; string? presentationUniqueKey = null;
int? limit = request.Limit; int? limit = null;
if (!request.SeriesId.IsNullOrEmpty()) if (!request.SeriesId.IsNullOrEmpty())
{ {
if (_libraryManager.GetItemById(request.SeriesId.Value) is Series series) if (_libraryManager.GetItemById(request.SeriesId.Value) is Series series)
@@ -2089,6 +2089,8 @@ public class ImageController : BaseJellyfinApiController
Response.Headers.Append(HeaderNames.Age, Convert.ToInt64((DateTime.UtcNow - dateImageModified).TotalSeconds).ToString(CultureInfo.InvariantCulture)); Response.Headers.Append(HeaderNames.Age, Convert.ToInt64((DateTime.UtcNow - dateImageModified).TotalSeconds).ToString(CultureInfo.InvariantCulture));
Response.Headers.Append(HeaderNames.Vary, HeaderNames.Accept); Response.Headers.Append(HeaderNames.Vary, HeaderNames.Accept);
Response.Headers.ContentDisposition = "attachment";
if (disableCaching) if (disableCaching)
{ {
Response.Headers.Append(HeaderNames.CacheControl, "no-cache, no-store, must-revalidate"); Response.Headers.Append(HeaderNames.CacheControl, "no-cache, no-store, must-revalidate");
@@ -233,6 +233,8 @@ public class PluginsController : BaseJellyfinApiController
return NotFound(); return NotFound();
} }
Response.Headers.ContentDisposition = "attachment";
imagePath = Path.Combine(plugin.Path, plugin.Manifest.ImagePath); imagePath = Path.Combine(plugin.Path, plugin.Manifest.ImagePath);
return PhysicalFile(imagePath, MimeTypes.GetMimeType(imagePath)); return PhysicalFile(imagePath, MimeTypes.GetMimeType(imagePath));
} }
@@ -95,6 +95,7 @@ public class TrickplayController : BaseJellyfinApiController
var path = _trickplayManager.GetTrickplayTilePath(item, width, index); var path = _trickplayManager.GetTrickplayTilePath(item, width, index);
if (System.IO.File.Exists(path)) if (System.IO.File.Exists(path))
{ {
Response.Headers.ContentDisposition = "attachment";
return PhysicalFile(path, MediaTypeNames.Image.Jpeg); return PhysicalFile(path, MediaTypeNames.Image.Jpeg);
} }
+1 -1
View File
@@ -18,7 +18,7 @@
<PropertyGroup> <PropertyGroup>
<Authors>Jellyfin Contributors</Authors> <Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Data</PackageId> <PackageId>Jellyfin.Data</PackageId>
<VersionPrefix>10.9.9</VersionPrefix> <VersionPrefix>10.9.10</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>
@@ -8,7 +8,7 @@
<PropertyGroup> <PropertyGroup>
<Authors>Jellyfin Contributors</Authors> <Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Common</PackageId> <PackageId>Jellyfin.Common</PackageId>
<VersionPrefix>10.9.9</VersionPrefix> <VersionPrefix>10.9.10</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>
@@ -8,7 +8,7 @@
<PropertyGroup> <PropertyGroup>
<Authors>Jellyfin Contributors</Authors> <Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Controller</PackageId> <PackageId>Jellyfin.Controller</PackageId>
<VersionPrefix>10.9.9</VersionPrefix> <VersionPrefix>10.9.10</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>
@@ -1313,7 +1313,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// Apply aac_adtstoasc bitstream filter when media source is in mpegts. // Apply aac_adtstoasc bitstream filter when media source is in mpegts.
if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase) if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase)
&& (string.Equals(mediaSourceContainer, "mpegts", StringComparison.OrdinalIgnoreCase) && (string.Equals(mediaSourceContainer, "ts", StringComparison.OrdinalIgnoreCase)
|| string.Equals(mediaSourceContainer, "aac", StringComparison.OrdinalIgnoreCase) || string.Equals(mediaSourceContainer, "aac", StringComparison.OrdinalIgnoreCase)
|| string.Equals(mediaSourceContainer, "hls", StringComparison.OrdinalIgnoreCase))) || string.Equals(mediaSourceContainer, "hls", StringComparison.OrdinalIgnoreCase)))
{ {
@@ -89,7 +89,8 @@ namespace MediaBrowser.MediaEncoding.Attachments
string outputPath, string outputPath,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var shouldExtractOneByOne = mediaSource.MediaAttachments.Any(a => a.FileName.Contains('/', StringComparison.OrdinalIgnoreCase) || a.FileName.Contains('\\', StringComparison.OrdinalIgnoreCase)); var shouldExtractOneByOne = mediaSource.MediaAttachments.Any(a => !string.IsNullOrEmpty(a.FileName)
&& (a.FileName.Contains('/', StringComparison.OrdinalIgnoreCase) || a.FileName.Contains('\\', StringComparison.OrdinalIgnoreCase)));
if (shouldExtractOneByOne) if (shouldExtractOneByOne)
{ {
var attachmentIndexes = mediaSource.MediaAttachments.Select(a => a.Index); var attachmentIndexes = mediaSource.MediaAttachments.Select(a => a.Index);
@@ -168,6 +168,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly string _encoderPath; private readonly string _encoderPath;
private readonly Version _minFFmpegMultiThreadedCli = new Version(7, 0);
public EncoderValidator(ILogger logger, string encoderPath) public EncoderValidator(ILogger logger, string encoderPath)
{ {
_logger = logger; _logger = logger;
@@ -477,8 +479,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
return false; return false;
} }
private readonly Version _minFFmpegMultiThreadedCli = new Version(7, 0);
public bool CheckSupportedRuntimeKey(string keyDesc, Version? ffmpegVersion) public bool CheckSupportedRuntimeKey(string keyDesc, Version? ffmpegVersion)
{ {
if (string.IsNullOrEmpty(keyDesc)) if (string.IsNullOrEmpty(keyDesc))
+10 -8
View File
@@ -898,8 +898,10 @@ namespace MediaBrowser.Model.Dlna
var appliedVideoConditions = options.Profile.CodecProfiles var appliedVideoConditions = options.Profile.CodecProfiles
.Where(i => i.Type == CodecType.Video && .Where(i => i.Type == CodecType.Video &&
i.ContainsAnyCodec(videoStream?.Codec, container) && i.ContainsAnyCodec(videoStream?.Codec, container) &&
i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))); i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)))
var isFirstAppliedCodecProfile = true; // Reverse codec profiles for backward compatibility - first codec profile has higher priority
.Reverse();
foreach (var i in appliedVideoConditions) foreach (var i in appliedVideoConditions)
{ {
var transcodingVideoCodecs = ContainerProfile.SplitValue(videoCodec); var transcodingVideoCodecs = ContainerProfile.SplitValue(videoCodec);
@@ -907,8 +909,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (i.ContainsAnyCodec(transcodingVideoCodec, container)) if (i.ContainsAnyCodec(transcodingVideoCodec, container))
{ {
ApplyTranscodingConditions(playlistItem, i.Conditions, transcodingVideoCodec, true, isFirstAppliedCodecProfile); ApplyTranscodingConditions(playlistItem, i.Conditions, transcodingVideoCodec, true, true);
isFirstAppliedCodecProfile = false;
continue; continue;
} }
} }
@@ -930,8 +931,10 @@ namespace MediaBrowser.Model.Dlna
var appliedAudioConditions = options.Profile.CodecProfiles var appliedAudioConditions = options.Profile.CodecProfiles
.Where(i => i.Type == CodecType.VideoAudio && .Where(i => i.Type == CodecType.VideoAudio &&
i.ContainsAnyCodec(audioStream?.Codec, container) && i.ContainsAnyCodec(audioStream?.Codec, container) &&
i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio))); i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio)))
isFirstAppliedCodecProfile = true; // Reverse codec profiles for backward compatibility - first codec profile has higher priority
.Reverse();
foreach (var codecProfile in appliedAudioConditions) foreach (var codecProfile in appliedAudioConditions)
{ {
var transcodingAudioCodecs = ContainerProfile.SplitValue(audioCodec); var transcodingAudioCodecs = ContainerProfile.SplitValue(audioCodec);
@@ -939,8 +942,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (codecProfile.ContainsAnyCodec(transcodingAudioCodec, container)) if (codecProfile.ContainsAnyCodec(transcodingAudioCodec, container))
{ {
ApplyTranscodingConditions(playlistItem, codecProfile.Conditions, transcodingAudioCodec, true, isFirstAppliedCodecProfile); ApplyTranscodingConditions(playlistItem, codecProfile.Conditions, transcodingAudioCodec, true, true);
isFirstAppliedCodecProfile = false;
break; break;
} }
} }
+1 -1
View File
@@ -8,7 +8,7 @@
<PropertyGroup> <PropertyGroup>
<Authors>Jellyfin Contributors</Authors> <Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Model</PackageId> <PackageId>Jellyfin.Model</PackageId>
<VersionPrefix>10.9.9</VersionPrefix> <VersionPrefix>10.9.10</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>
@@ -211,8 +211,12 @@ namespace MediaBrowser.Providers.TV
} }
else if (existingSeason.IsVirtualItem) else if (existingSeason.IsVirtualItem)
{ {
existingSeason.IsVirtualItem = false; var episodeCount = seriesChildren.OfType<Episode>().Count(e => e.ParentIndexNumber == seasonNumber && !e.IsMissingEpisode);
await existingSeason.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); if (episodeCount > 0)
{
existingSeason.IsVirtualItem = false;
await existingSeason.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
}
} }
} }
} }
+2 -2
View File
@@ -1,4 +1,4 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("10.9.9")] [assembly: AssemblyVersion("10.9.10")]
[assembly: AssemblyFileVersion("10.9.9")] [assembly: AssemblyFileVersion("10.9.10")]
+2 -1
View File
@@ -102,7 +102,8 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
"astc", "astc",
"ktx", "ktx",
"pkm", "pkm",
"wbmp" "wbmp",
"avif"
}; };
/// <inheritdoc /> /// <inheritdoc />
@@ -15,7 +15,7 @@
<PropertyGroup> <PropertyGroup>
<Authors>Jellyfin Contributors</Authors> <Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Extensions</PackageId> <PackageId>Jellyfin.Extensions</PackageId>
<VersionPrefix>10.9.9</VersionPrefix> <VersionPrefix>10.9.10</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>
@@ -167,7 +167,7 @@ namespace Jellyfin.LiveTv.Listings
Overview = program.Description, Overview = program.Description,
ProductionYear = program.CopyrightDate?.Year, ProductionYear = program.CopyrightDate?.Year,
SeasonNumber = program.Episode.Series, SeasonNumber = program.Episode.Series,
IsSeries = program.Episode.Series is not null, IsSeries = program.Episode.Episode is not null,
IsRepeat = program.IsPreviouslyShown && !program.IsNew, IsRepeat = program.IsPreviouslyShown && !program.IsNew,
IsPremiere = program.Premiere is not null, IsPremiere = program.Premiere is not null,
IsKids = programCategories.Any(c => info.KidsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)), IsKids = programCategories.Any(c => info.KidsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),