aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj8
-rw-r--r--src/Jellyfin.Drawing.Skia/SkiaEncoder.cs13
-rw-r--r--src/Jellyfin.Drawing.Skia/SkiaHelper.cs8
-rw-r--r--src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs30
-rw-r--r--src/Jellyfin.Drawing/ImageProcessor.cs16
-rw-r--r--src/Jellyfin.Drawing/Jellyfin.Drawing.csproj6
-rw-r--r--src/Jellyfin.Extensions/Jellyfin.Extensions.csproj4
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs2
-rw-r--r--src/Jellyfin.Extensions/StreamExtensions.cs10
-rw-r--r--src/Jellyfin.Extensions/StringExtensions.cs10
-rw-r--r--src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj4
-rw-r--r--src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs67
-rw-r--r--src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj4
13 files changed, 112 insertions, 70 deletions
diff --git a/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
index 3b0333299..c465c4ad0 100644
--- a/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
+++ b/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
@@ -21,6 +21,8 @@
<PackageReference Include="SkiaSharp" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" />
<PackageReference Include="SkiaSharp.Svg" />
+ <PackageReference Include="SkiaSharp.HarfBuzz" />
+ <PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" />
</ItemGroup>
<ItemGroup>
@@ -29,8 +31,12 @@
<ProjectReference Include="..\..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
</ItemGroup>
- <!-- Code analysers-->
+ <!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
index 2d980db18..126c0503e 100644
--- a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
+++ b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
@@ -122,8 +122,8 @@ public class SkiaEncoder : IImageEncoder
var svg = new SKSvg();
try
{
- svg.Load(path);
- return new ImageDimensions(Convert.ToInt32(svg.Picture.CullRect.Width), Convert.ToInt32(svg.Picture.CullRect.Height));
+ using var picture = svg.Load(path);
+ return new ImageDimensions(Convert.ToInt32(picture.CullRect.Width), Convert.ToInt32(picture.CullRect.Height));
}
catch (FormatException skiaColorException)
{
@@ -432,7 +432,8 @@ public class SkiaEncoder : IImageEncoder
// scale image (the FromImage creates a copy)
var imageInfo = new SKImageInfo(width, height, bitmap.ColorType, bitmap.AlphaType, bitmap.ColorSpace);
- using var resizedBitmap = SKBitmap.FromImage(ResizeImage(bitmap, imageInfo));
+ using var resizedImage = ResizeImage(bitmap, imageInfo);
+ using var resizedBitmap = SKBitmap.FromImage(resizedImage);
// If all we're doing is resizing then we can stop now
if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator)
@@ -489,10 +490,8 @@ public class SkiaEncoder : IImageEncoder
Directory.CreateDirectory(directory);
using (var outputStream = new SKFileWStream(outputPath))
{
- using (var pixmap = new SKPixmap(new SKImageInfo(width, height), saveBitmap.GetPixels()))
- {
- pixmap.Encode(outputStream, skiaOutputFormat, quality);
- }
+ using var pixmap = new SKPixmap(new SKImageInfo(width, height), saveBitmap.GetPixels());
+ pixmap.Encode(outputStream, skiaOutputFormat, quality);
}
return outputPath;
diff --git a/src/Jellyfin.Drawing.Skia/SkiaHelper.cs b/src/Jellyfin.Drawing.Skia/SkiaHelper.cs
index 00d224da9..bd1b2b0da 100644
--- a/src/Jellyfin.Drawing.Skia/SkiaHelper.cs
+++ b/src/Jellyfin.Drawing.Skia/SkiaHelper.cs
@@ -19,7 +19,6 @@ public static class SkiaHelper
public static SKBitmap? GetNextValidImage(SkiaEncoder skiaEncoder, IReadOnlyList<string> paths, int currentIndex, out int newIndex)
{
var imagesTested = new Dictionary<int, int>();
- SKBitmap? bitmap = null;
while (imagesTested.Count < paths.Count)
{
@@ -28,7 +27,7 @@ public static class SkiaHelper
currentIndex = 0;
}
- bitmap = skiaEncoder.Decode(paths[currentIndex], false, null, out _);
+ SKBitmap? bitmap = skiaEncoder.Decode(paths[currentIndex], false, null, out _);
imagesTested[currentIndex] = 0;
@@ -36,11 +35,12 @@ public static class SkiaHelper
if (bitmap is not null)
{
- break;
+ newIndex = currentIndex;
+ return bitmap;
}
}
newIndex = currentIndex;
- return bitmap;
+ return null;
}
}
diff --git a/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs b/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
index eee24c423..6dff7aa9b 100644
--- a/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
+++ b/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
@@ -3,13 +3,14 @@ using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using SkiaSharp;
+using SkiaSharp.HarfBuzz;
namespace Jellyfin.Drawing.Skia;
/// <summary>
/// Used to build collages of multiple images arranged in vertical strips.
/// </summary>
-public class StripCollageBuilder
+public partial class StripCollageBuilder
{
private readonly SkiaEncoder _skiaEncoder;
@@ -22,6 +23,12 @@ public class StripCollageBuilder
_skiaEncoder = skiaEncoder;
}
+ [GeneratedRegex(@"[^\p{IsCJKUnifiedIdeographs}\p{IsCJKUnifiedIdeographsExtensionA}\p{IsKatakana}\p{IsHiragana}\p{IsHangulSyllables}\p{IsHangulJamo}]")]
+ private static partial Regex NonCjkPatternRegex();
+
+ [GeneratedRegex(@"\p{IsArabic}|\p{IsArmenian}|\p{IsHebrew}|\p{IsSyriac}|\p{IsThaana}")]
+ private static partial Regex IsRtlTextRegex();
+
/// <summary>
/// Check which format an image has been encoded with using its filename extension.
/// </summary>
@@ -119,8 +126,7 @@ public class StripCollageBuilder
var typeFace = SKTypeface.FromFamilyName("sans-serif", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright);
// use the system fallback to find a typeface for the given CJK character
- var nonCjkPattern = @"[^\p{IsCJKUnifiedIdeographs}\p{IsCJKUnifiedIdeographsExtensionA}\p{IsKatakana}\p{IsHiragana}\p{IsHangulSyllables}\p{IsHangulJamo}]";
- var filteredName = Regex.Replace(libraryName ?? string.Empty, nonCjkPattern, string.Empty);
+ var filteredName = NonCjkPatternRegex().Replace(libraryName ?? string.Empty, string.Empty);
if (!string.IsNullOrEmpty(filteredName))
{
typeFace = SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, filteredName[0]);
@@ -144,7 +150,19 @@ public class StripCollageBuilder
textPaint.TextSize = 0.9f * width * textPaint.TextSize / textWidth;
}
- canvas.DrawText(libraryName, width / 2f, (height / 2f) + (textPaint.FontMetrics.XHeight / 2), textPaint);
+ if (string.IsNullOrWhiteSpace(libraryName))
+ {
+ return bitmap;
+ }
+
+ if (IsRtlTextRegex().IsMatch(libraryName))
+ {
+ canvas.DrawShapedText(libraryName, width / 2f, (height / 2f) + (textPaint.FontMetrics.XHeight / 2), textPaint);
+ }
+ else
+ {
+ canvas.DrawText(libraryName, width / 2f, (height / 2f) + (textPaint.FontMetrics.XHeight / 2), textPaint);
+ }
return bitmap;
}
@@ -171,12 +189,12 @@ public class StripCollageBuilder
// Scale image. The FromBitmap creates a copy
var imageInfo = new SKImageInfo(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType, currentBitmap.ColorSpace);
- using var resizedBitmap = SKBitmap.FromImage(SkiaEncoder.ResizeImage(currentBitmap, imageInfo));
+ using var resizeImage = SkiaEncoder.ResizeImage(currentBitmap, imageInfo);
// draw this image into the strip at the next position
var xPos = x * cellWidth;
var yPos = y * cellHeight;
- canvas.DrawBitmap(resizedBitmap, xPos, yPos);
+ canvas.DrawImage(resizeImage, xPos, yPos);
}
}
diff --git a/src/Jellyfin.Drawing/ImageProcessor.cs b/src/Jellyfin.Drawing/ImageProcessor.cs
index 533baba4f..4f16e294b 100644
--- a/src/Jellyfin.Drawing/ImageProcessor.cs
+++ b/src/Jellyfin.Drawing/ImageProcessor.cs
@@ -13,7 +13,6 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
@@ -50,14 +49,12 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
/// <param name="appPaths">The server application paths.</param>
/// <param name="fileSystem">The filesystem.</param>
/// <param name="imageEncoder">The image encoder.</param>
- /// <param name="mediaEncoder">The media encoder.</param>
/// <param name="config">The configuration.</param>
public ImageProcessor(
ILogger<ImageProcessor> logger,
IServerApplicationPaths appPaths,
IFileSystem fileSystem,
IImageEncoder imageEncoder,
- IMediaEncoder mediaEncoder,
IServerConfigurationManager config)
{
_logger = logger;
@@ -114,10 +111,8 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
public async Task ProcessImage(ImageProcessingOptions options, Stream toStream)
{
var file = await ProcessImage(options).ConfigureAwait(false);
- using (var fileStream = AsyncFile.OpenRead(file.Path))
- {
- await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
- }
+ using var fileStream = AsyncFile.OpenRead(file.Path);
+ await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
}
/// <inheritdoc />
@@ -439,8 +434,13 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
=> (item.Path + image.DateModified.Ticks).GetMD5().ToString("N", CultureInfo.InvariantCulture);
/// <inheritdoc />
- public string GetImageCacheTag(BaseItem item, ChapterInfo chapter)
+ public string? GetImageCacheTag(BaseItem item, ChapterInfo chapter)
{
+ if (chapter.ImagePath is null)
+ {
+ return null;
+ }
+
return GetImageCacheTag(item, new ItemImageInfo
{
Path = chapter.ImagePath,
diff --git a/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj b/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj
index e0963ac34..2a5e24a44 100644
--- a/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj
+++ b/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj
@@ -21,8 +21,12 @@
<Compile Include="..\..\SharedVersion.cs" />
</ItemGroup>
- <!-- Code analysers-->
+ <!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj b/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj
index 4f80aa941..36ae55ed2 100644
--- a/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj
+++ b/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj
@@ -34,6 +34,10 @@
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs
index 321cfa502..17096c017 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs
@@ -59,7 +59,7 @@ namespace Jellyfin.Extensions.Json.Converters
var typedValueIndex = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
- if (parsedValues[i] != null)
+ if (parsedValues[i] is not null)
{
typedValues.SetValue(parsedValues[i], typedValueIndex);
typedValueIndex++;
diff --git a/src/Jellyfin.Extensions/StreamExtensions.cs b/src/Jellyfin.Extensions/StreamExtensions.cs
index 9751d9d42..182996852 100644
--- a/src/Jellyfin.Extensions/StreamExtensions.cs
+++ b/src/Jellyfin.Extensions/StreamExtensions.cs
@@ -26,10 +26,8 @@ namespace Jellyfin.Extensions
/// <returns>All lines in the stream.</returns>
public static string[] ReadAllLines(this Stream stream, Encoding encoding)
{
- using (StreamReader reader = new StreamReader(stream, encoding))
- {
- return ReadAllLines(reader).ToArray();
- }
+ using StreamReader reader = new StreamReader(stream, encoding);
+ return ReadAllLines(reader).ToArray();
}
/// <summary>
@@ -40,7 +38,7 @@ namespace Jellyfin.Extensions
public static IEnumerable<string> ReadAllLines(this TextReader reader)
{
string? line;
- while ((line = reader.ReadLine()) != null)
+ while ((line = reader.ReadLine()) is not null)
{
yield return line;
}
@@ -54,7 +52,7 @@ namespace Jellyfin.Extensions
public static async IAsyncEnumerable<string> ReadAllLinesAsync(this TextReader reader)
{
string? line;
- while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
+ while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) is not null)
{
yield return line;
}
diff --git a/src/Jellyfin.Extensions/StringExtensions.cs b/src/Jellyfin.Extensions/StringExtensions.cs
index b22eb7c4e..fd8f7e59a 100644
--- a/src/Jellyfin.Extensions/StringExtensions.cs
+++ b/src/Jellyfin.Extensions/StringExtensions.cs
@@ -6,11 +6,13 @@ namespace Jellyfin.Extensions
/// <summary>
/// Provides extensions methods for <see cref="string" />.
/// </summary>
- public static class StringExtensions
+ public static partial class StringExtensions
{
// Matches non-conforming unicode chars
// https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/
- private static readonly Regex _nonConformingUnicode = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])|(\ufffd)", RegexOptions.Compiled);
+
+ [GeneratedRegex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])|(�)")]
+ private static partial Regex NonConformingUnicodeRegex();
/// <summary>
/// Removes the diacritics character from the strings.
@@ -19,7 +21,7 @@ namespace Jellyfin.Extensions
/// <returns>The string without diacritics character.</returns>
public static string RemoveDiacritics(this string text)
=> Diacritics.Extensions.StringExtensions.RemoveDiacritics(
- _nonConformingUnicode.Replace(text, string.Empty));
+ NonConformingUnicodeRegex().Replace(text, string.Empty));
/// <summary>
/// Checks whether or not the specified string has diacritics in it.
@@ -28,7 +30,7 @@ namespace Jellyfin.Extensions
/// <returns>True if the string has diacritics, false otherwise.</returns>
public static bool HasDiacritics(this string text)
=> Diacritics.Extensions.StringExtensions.HasDiacritics(text)
- || _nonConformingUnicode.IsMatch(text);
+ || NonConformingUnicodeRegex().IsMatch(text);
/// <summary>
/// Counts the number of occurrences of [needle] in the string.
diff --git a/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj b/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
index 3f4f55ee4..b792e7ec6 100644
--- a/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
+++ b/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
@@ -7,6 +7,10 @@
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
index febe9516a..479e6ffdc 100644
--- a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
+++ b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
@@ -68,51 +68,54 @@ public static class FfProbeKeyframeExtractor
double streamDuration = 0;
double formatDuration = 0;
- while (!reader.EndOfStream)
+ using (reader)
{
- var line = reader.ReadLine().AsSpan();
- if (line.IsEmpty)
+ while (!reader.EndOfStream)
{
- continue;
- }
+ var line = reader.ReadLine().AsSpan();
+ if (line.IsEmpty)
+ {
+ continue;
+ }
- var firstComma = line.IndexOf(',');
- var lineType = line[..firstComma];
- var rest = line[(firstComma + 1)..];
- if (lineType.Equals("packet", StringComparison.OrdinalIgnoreCase))
- {
- // Split time and flags from the packet line. Example line: packet,7169.079000,K_
- var secondComma = rest.IndexOf(',');
- var ptsTime = rest[..secondComma];
- var flags = rest[(secondComma + 1)..];
- if (flags.StartsWith("K_"))
+ var firstComma = line.IndexOf(',');
+ var lineType = line[..firstComma];
+ var rest = line[(firstComma + 1)..];
+ if (lineType.Equals("packet", StringComparison.OrdinalIgnoreCase))
{
- if (double.TryParse(ptsTime, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var keyframe))
+ // Split time and flags from the packet line. Example line: packet,7169.079000,K_
+ var secondComma = rest.IndexOf(',');
+ var ptsTime = rest[..secondComma];
+ var flags = rest[(secondComma + 1)..];
+ if (flags.StartsWith("K_"))
{
- // Have to manually convert to ticks to avoid rounding errors as TimeSpan is only precise down to 1 ms when converting double.
- keyframes.Add(Convert.ToInt64(keyframe * TimeSpan.TicksPerSecond));
+ if (double.TryParse(ptsTime, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var keyframe))
+ {
+ // Have to manually convert to ticks to avoid rounding errors as TimeSpan is only precise down to 1 ms when converting double.
+ keyframes.Add(Convert.ToInt64(keyframe * TimeSpan.TicksPerSecond));
+ }
}
}
- }
- else if (lineType.Equals("stream", StringComparison.OrdinalIgnoreCase))
- {
- if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var streamDurationResult))
+ else if (lineType.Equals("stream", StringComparison.OrdinalIgnoreCase))
{
- streamDuration = streamDurationResult;
+ if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var streamDurationResult))
+ {
+ streamDuration = streamDurationResult;
+ }
}
- }
- else if (lineType.Equals("format", StringComparison.OrdinalIgnoreCase))
- {
- if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var formatDurationResult))
+ else if (lineType.Equals("format", StringComparison.OrdinalIgnoreCase))
{
- formatDuration = formatDurationResult;
+ if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var formatDurationResult))
+ {
+ formatDuration = formatDurationResult;
+ }
}
}
- }
- // Prefer the stream duration as it should be more accurate
- var duration = streamDuration > 0 ? streamDuration : formatDuration;
+ // Prefer the stream duration as it should be more accurate
+ var duration = streamDuration > 0 ? streamDuration : formatDuration;
- return new KeyframeData(TimeSpan.FromSeconds(duration).Ticks, keyframes);
+ return new KeyframeData(TimeSpan.FromSeconds(duration).Ticks, keyframes);
+ }
}
}
diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj b/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj
index 71572bcf6..09b1f8faa 100644
--- a/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj
+++ b/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj
@@ -11,6 +11,10 @@
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>