Compare commits

...

48 Commits

Author SHA1 Message Date
Joshua M. Boniface
a26cded0f5 Bump version to 10.8.5 2022-09-24 22:01:59 -04:00
Joshua M. Boniface
4ec82ec662 Merge pull request #8433 from jellyfin/dotnet-6.0.9 2022-09-20 09:45:01 -04:00
Cody Robibero
879787212e Update to dotnet 6.0.9 2022-09-19 08:19:32 -06:00
Bond-009
e6124bc154 Merge pull request #8399 from cvium/respectTagRestrictions 2022-09-15 14:08:50 +02:00
Bond-009
88d5230bab Merge pull request #8348 from jellyfin/revert-7985-revert-7961-next_up_idk 2022-09-14 01:54:45 +02:00
LogicalPhallacy
2920c52d61 Reorder and check for query user null to avoid null ref issues 2022-09-13 09:12:38 +02:00
LogicalPhallacy
de196a7687 Forces respecting IsVisible on people 2022-09-13 09:12:38 +02:00
Claus Vium
ba026716c1 Merge pull request #8213 from nyanmisaka/pause-cpu
Fix high single thread usage in throttler
2022-09-13 08:07:04 +02:00
Joshua M. Boniface
125ee88311 Merge pull request #8321 from strugee/fix-systemd-whitespace 2022-09-11 16:55:21 -04:00
nyanmisaka
c53f6a2890 Fix high single thread usage in throttler
this requires jellyfin-ffmpeg >= 5.0.1-8
2022-09-09 21:14:02 +08:00
Bond-009
649b4c49e0 Merge pull request #8327 from RealGreenDragon/subtitle-extraction-timeout-10.8.z 2022-09-09 12:51:25 +02:00
Cody Robibero
848ea703bc Merge pull request #8298 from lomion0815/fix-data-stream 2022-09-05 08:51:48 -06:00
AJ Jordan
0adadff3e7 Fix systemd not breaking whitespace in env vars
This is particularly important for JELLYFIN_ADDITIONAL_OPTS, where the
user is most likely to want to specify more than one word.
2022-08-27 16:20:06 -04:00
MagicGreenDragon
ffdc3a6734 Increased subtitle extraction timeout to 30 min 2022-08-27 18:10:42 +02:00
lomion0815
a51cd4f8db Improved error log as suggested by crobibero in the PR #8298 review 2022-08-24 21:01:32 +02:00
Bond-009
af87706379 Merge pull request #8214 from nielsvanvelzen/optional-userid 2022-08-22 18:25:20 +02:00
Niels van Velzen
8422ab687b Update Jellyfin.Api/Controllers/UniversalAudioController.cs
Co-authored-by: Bond-009 <bond.009@outlook.com>
2022-08-22 17:47:59 +02:00
markus
64753cfc7f Streams with CodecType "data" (like "epg" streams in DVB recordings) get ignored. This results in wrong stream specifiers for all subsequential streams. This fix correctly handles "data" streams without any further processing. 2022-08-22 14:58:30 +02:00
Claus Vium
632fb05f46 Merge pull request #8280 from thornbill/fix-analyze-duration-priority
Fix ffmpeg analyze duration env var taking priority over media source
2022-08-18 08:08:58 +02:00
Claus Vium
527ed0607d Merge pull request #8189 from lukefor/getitems-outofrange
Fix GetItems IndexOutOfRangeException when IDs do not exist
2022-08-18 08:07:51 +02:00
Luke F
b59daab273 Tab -> space 2022-08-18 00:26:55 +01:00
Luke F
8f28d52929 Code review - simplify SortItemsByRequest to a single roughly-equivalent linq expression 2022-08-18 00:15:57 +01:00
Luke F
749b263c48 Merge remote-tracking branch 'upstream/release-10.8.z' into getitems-outofrange 2022-08-18 00:14:01 +01:00
Bill Thornton
80c68b8948 Fix ffmpeg analyze duration env var taking priority over media source 2022-08-17 15:04:51 -04:00
Claus Vium
a5687793c9 Revert "Revert "refactor: use season number and episode number for NextUp ordering instead of SortName"" 2022-08-15 14:10:42 +02:00
Joshua Boniface
b344771f8a Bump version to 10.8.4 2022-08-13 21:51:50 -04:00
Joshua Boniface
3ff78b687d Revert "Restore "Merge pull request #8087 from cvium/generic_subtitleparser""
This reverts commit 5bcab0f0f8.
2022-08-13 21:51:23 -04:00
Joshua M. Boniface
d260f30810 Merge pull request #8257 from joshuaboniface/fix-dotnetargs 2022-08-13 21:45:57 -04:00
Cody Robibero
7ffdde9a0b Merge pull request #8212 from SenorSmartyPants/Add384ResolutionText
Add resolution text for 384 sized video
2022-08-13 18:34:17 -07:00
Joshua M. Boniface
e14194bfe2 Fix remaining instances in root package configs 2022-08-13 21:23:01 -04:00
Joshua M. Boniface
3bf1a7e445 Use separate args for dotnet publish commands
Fixes #8245
2022-08-13 21:18:28 -04:00
Bond-009
1faee43b11 Merge pull request #8182 from Shadowghost/fix-sub-characterset 2022-08-12 19:47:42 +02:00
Joshua M. Boniface
31f9938e3a Merge pull request #8234 from crobibero/dotnet-6.0.8 2022-08-11 22:46:31 -04:00
Cody Robibero
ae9fd4ab35 update remaining dependencies 2022-08-09 17:57:51 -06:00
Cody Robibero
71ed7f7676 update to dotnet 6.0.8 2022-08-09 17:57:21 -06:00
SenorSmartyPants
3b6e003029 Add 404p Resolution Text 2022-08-09 12:09:29 -05:00
Claus Vium
9357d610b1 Merge pull request #8209 from Shadowghost/fix-playback
Fix series query including missing episodes when it should not
2022-08-08 22:57:56 +02:00
Joshua M. Boniface
1d4755894e Merge pull request #8219 from nyanmisaka/fedora-hardening
Move Fedora service hardening options to override config
2022-08-07 21:10:03 -04:00
nyanmisaka
2320f06666 Move Fedora service hardening options to override config 2022-08-07 18:01:26 +08:00
Niels van Velzen
8296f07a39 Make userId truly optional in UniversalAudioController 2022-08-06 14:17:04 +02:00
SenorSmartyPants
30f6263806 Add resolution text for 384 sized video 2022-08-05 23:32:22 -05:00
Shadowghost
a9249393e1 Fix series query including missing episodes when it should not 2022-08-05 19:38:33 +02:00
Shadowghost
f49a051a5f Respect timestamps when extracting subtitles 2022-08-02 13:21:10 +02:00
Joshua Boniface
5bcab0f0f8 Restore "Merge pull request #8087 from cvium/generic_subtitleparser"
After tagging v10.8.3, this can be restored to how it was and corrected
as required in a separate PR.

This reverts commit 494ed7e4d2.
2022-08-01 20:40:54 -04:00
Joshua Boniface
c5a2ff8ac4 Bump version to 10.8.3 2022-08-01 20:20:00 -04:00
Joshua Boniface
494ed7e4d2 Revert "Merge pull request #8087 from cvium/generic_subtitleparser"
This PR was causing breakage in installs - ref #8198

This reverts commit 7323ccfc23, reversing
changes made to 77a007a24d.
2022-08-01 20:19:16 -04:00
Luke F
3bd2cc9860 Resolve a System.IndexOutOfRangeException when requesting IDs that do not exist via /Users/.../Items. Previously it was possible for the 'index' values in 'positions' to refer beyond 'size'.
[ERR] Error processing request. URL "GET" "/Users/.../Items".
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at MediaBrowser.Controller.Entities.Folder.SortItemsByRequest(InternalItemsQuery query, IReadOnlyList`1 items)
   at MediaBrowser.Controller.Entities.Folder.GetItems(InternalItemsQuery query)
   at Jellyfin.Api.Controllers.ItemsController.GetItems
2022-07-29 20:43:38 +01:00
Shadowghost
feb035b9e0 Extract external subs from container before determining character set 2022-07-27 10:08:53 +02:00
85 changed files with 454 additions and 337 deletions

View File

@@ -157,6 +157,7 @@
- [jonas-resch](https://github.com/jonas-resch)
- [vgambier](https://github.com/vgambier)
- [MinecraftPlaye](https://github.com/MinecraftPlaye)
- [RealGreenDragon](https://github.com/RealGreenDragon)
# Emby Contributors

View File

@@ -72,7 +72,7 @@ COPY . .
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# because of changes in docker and systemd we need to not build in parallel at the moment
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 "-p:DebugSymbols=false;DebugType=none"
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 -p:DebugSymbols=false -p:DebugType=none
FROM app

View File

@@ -64,7 +64,7 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# Discard objs - may cause failures if exists
RUN find . -type d -name obj | xargs -r rm -r
# Build
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm "-p:DebugSymbols=false;DebugType=none"
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm -p:DebugSymbols=false -p:DebugType=none
FROM app

View File

@@ -55,7 +55,7 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# Discard objs - may cause failures if exists
RUN find . -type d -name obj | xargs -r rm -r
# Build
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 "-p:DebugSymbols=false;DebugType=none"
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 -p:DebugSymbols=false -p:DebugType=none
FROM app

View File

@@ -36,7 +36,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Naming</PackageId>
<VersionPrefix>10.8.2</VersionPrefix>
<VersionPrefix>10.8.5</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -15,7 +15,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="TagLibSharp" Version="2.2.0" />
<PackageReference Include="TagLibSharp" Version="2.3.0" />
</ItemGroup>
<PropertyGroup>

View File

@@ -83,7 +83,6 @@ using MediaBrowser.Controller.SyncPlay;
using MediaBrowser.Controller.TV;
using MediaBrowser.LocalMetadata.Savers;
using MediaBrowser.MediaEncoding.BdInfo;
using MediaBrowser.MediaEncoding.Subtitles;
using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Globalization;
@@ -635,8 +634,7 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IAuthService, AuthService>();
serviceCollection.AddSingleton<IQuickConnect, QuickConnectManager>();
serviceCollection.AddSingleton<ISubtitleParser, SubtitleEditParser>();
serviceCollection.AddSingleton<ISubtitleEncoder, SubtitleEncoder>();
serviceCollection.AddSingleton<ISubtitleEncoder, MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>();
serviceCollection.AddSingleton<IAttachmentExtractor, MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor>();

View File

@@ -182,7 +182,7 @@ namespace Emby.Server.Implementations.Dto
if (options.ContainsField(ItemFields.People))
{
AttachPeople(dto, item);
AttachPeople(dto, item, user);
}
if (options.ContainsField(ItemFields.PrimaryImageAspectRatio))
@@ -503,7 +503,8 @@ namespace Emby.Server.Implementations.Dto
/// </summary>
/// <param name="dto">The dto.</param>
/// <param name="item">The item.</param>
private void AttachPeople(BaseItemDto dto, BaseItem item)
/// <param name="user">The requesting user.</param>
private void AttachPeople(BaseItemDto dto, BaseItem item, User user = null)
{
// Ordering by person type to ensure actors and artists are at the front.
// This is taking advantage of the fact that they both begin with A
@@ -560,6 +561,9 @@ namespace Emby.Server.Implementations.Dto
return null;
}
}).Where(i => i != null)
.Where(i => user == null ?
true :
i.IsVisible(user))
.GroupBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
.Select(x => x.First())
.ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);

View File

@@ -29,10 +29,10 @@
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.9" />
<PackageReference Include="Mono.Nat" Version="3.0.3" />
<PackageReference Include="prometheus-net.DotNetRuntime" Version="4.2.4" />
<PackageReference Include="sharpcompress" Version="0.32.1" />
<PackageReference Include="sharpcompress" Version="0.32.2" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="3.1.0" />
<PackageReference Include="DotNet.Glob" Version="3.1.3" />
</ItemGroup>

View File

@@ -2766,7 +2766,8 @@ namespace Emby.Server.Implementations.Library
public List<Person> GetPeopleItems(InternalPeopleQuery query)
{
return _itemRepository.GetPeopleNames(query).Select(i =>
return _itemRepository.GetPeopleNames(query)
.Select(i =>
{
try
{
@@ -2777,7 +2778,12 @@ namespace Emby.Server.Implementations.Library
_logger.LogError(ex, "Error getting person");
return null;
}
}).Where(i => i != null).ToList();
})
.Where(i => i != null)
.Where(i => query.User == null ?
true :
i.IsVisible(query.User))
.ToList();
}
public List<string> GetPeopleNames(InternalPeopleQuery query)

View File

@@ -135,20 +135,15 @@ namespace Emby.Server.Implementations.TV
return GetResult(episodes, request);
}
public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IReadOnlyList<string> seriesKeys, DtoOptions dtoOptions)
private IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IReadOnlyList<string> seriesKeys, DtoOptions dtoOptions)
{
// Avoid implicitly captured closure
var currentUser = user;
var allNextUp = seriesKeys
.Select(i => GetNextUp(i, currentUser, dtoOptions, false));
var allNextUp = seriesKeys.Select(i => GetNextUp(i, user, dtoOptions, false));
if (request.EnableRewatching)
{
allNextUp = allNextUp.Concat(
seriesKeys.Select(i => GetNextUp(i, currentUser, dtoOptions, true))
)
.OrderByDescending(i => i.Item1);
seriesKeys.Select(i => GetNextUp(i, user, dtoOptions, true)))
.OrderByDescending(i => i.LastWatchedDate);
}
// If viewing all next up for all series, remove first episodes
@@ -161,23 +156,18 @@ namespace Emby.Server.Implementations.TV
{
if (request.DisableFirstEpisode)
{
return i.Item1 != DateTime.MinValue;
return i.LastWatchedDate != DateTime.MinValue;
}
if (alwaysEnableFirstEpisode || (i.Item1 != DateTime.MinValue && i.Item1.Date >= request.NextUpDateCutoff))
if (alwaysEnableFirstEpisode || (i.LastWatchedDate != DateTime.MinValue && i.LastWatchedDate.Date >= request.NextUpDateCutoff))
{
anyFound = true;
return true;
}
if (!anyFound && i.Item1 == DateTime.MinValue)
{
return true;
}
return false;
return !anyFound && i.LastWatchedDate == DateTime.MinValue;
})
.Select(i => i.Item2())
.Select(i => i.GetEpisodeFunction())
.Where(i => i != null);
}
@@ -195,14 +185,14 @@ namespace Emby.Server.Implementations.TV
/// Gets the next up.
/// </summary>
/// <returns>Task{Episode}.</returns>
private Tuple<DateTime, Func<Episode>> GetNextUp(string seriesKey, User user, DtoOptions dtoOptions, bool rewatching)
private (DateTime LastWatchedDate, Func<Episode> GetEpisodeFunction) GetNextUp(string seriesKey, User user, DtoOptions dtoOptions, bool rewatching)
{
var lastQuery = new InternalItemsQuery(user)
{
AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { BaseItemKind.Episode },
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Descending) },
OrderBy = new[] { (ItemSortBy.ParentIndexNumber, SortOrder.Descending), (ItemSortBy.IndexNumber, SortOrder.Descending) },
IsPlayed = true,
Limit = 1,
ParentIndexNumberNotEquals = 0,
@@ -216,24 +206,23 @@ namespace Emby.Server.Implementations.TV
if (rewatching)
{
// find last watched by date played, not by newest episode watched
lastQuery.OrderBy = new[] { (ItemSortBy.DatePlayed, SortOrder.Descending) };
lastQuery.OrderBy = new[] { (ItemSortBy.DatePlayed, SortOrder.Descending), (ItemSortBy.ParentIndexNumber, SortOrder.Descending), (ItemSortBy.IndexNumber, SortOrder.Descending) };
}
var lastWatchedEpisode = _libraryManager.GetItemList(lastQuery).Cast<Episode>().FirstOrDefault();
Func<Episode> getEpisode = () =>
Episode GetEpisode()
{
var nextQuery = new InternalItemsQuery(user)
{
AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { BaseItemKind.Episode },
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
OrderBy = new[] { (ItemSortBy.ParentIndexNumber, SortOrder.Ascending), (ItemSortBy.IndexNumber, SortOrder.Ascending) },
Limit = 1,
IsPlayed = rewatching,
IsVirtualItem = false,
ParentIndexNumberNotEquals = 0,
MinSortName = lastWatchedEpisode?.SortName,
DtoOptions = dtoOptions
};
@@ -297,7 +286,7 @@ namespace Emby.Server.Implementations.TV
}
return nextEpisode;
};
}
if (lastWatchedEpisode != null)
{
@@ -305,11 +294,11 @@ namespace Emby.Server.Implementations.TV
var lastWatchedDate = userData.LastPlayedDate ?? DateTime.MinValue.AddDays(1);
return new Tuple<DateTime, Func<Episode>>(lastWatchedDate, getEpisode);
return (lastWatchedDate, GetEpisode);
}
// Return the first episode
return new Tuple<DateTime, Func<Episode>>(DateTime.MinValue, getEpisode);
return (DateTime.MinValue, GetEpisode);
}
private static QueryResult<BaseItem> GetResult(IEnumerable<BaseItem> items, NextUpQuery query)

View File

@@ -98,7 +98,10 @@ namespace Jellyfin.Api.Controllers
Limit = limit ?? 0
});
return new QueryResult<BaseItemDto>(peopleItems.Select(person => _dtoService.GetItemByNameDto(person, dtoOptions, null, user)).ToArray());
return new QueryResult<BaseItemDto>(
peopleItems
.Select(person => _dtoService.GetItemByNameDto(person, dtoOptions, null, user))
.ToArray());
}
/// <summary>

View File

@@ -117,7 +117,13 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableRedirection = true)
{
var deviceProfile = GetDeviceProfile(container, transcodingContainer, audioCodec, transcodingProtocol, breakOnNonKeyFrames, transcodingAudioChannels, maxAudioSampleRate, maxAudioBitDepth, maxAudioChannels);
(await _authorizationContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).DeviceId = deviceId;
var authorizationInfo = await _authorizationContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
authorizationInfo.DeviceId = deviceId;
if (!userId.HasValue || userId.Value.Equals(Guid.Empty))
{
userId = authorizationInfo.UserId;
}
var authInfo = await _authorizationContext.GetAuthorizationInfo(Request).ConfigureAwait(false);

View File

@@ -654,7 +654,7 @@ namespace Jellyfin.Api.Helpers
{
if (EnableThrottling(state))
{
transcodingJob.TranscodingThrottler = new TranscodingThrottler(transcodingJob, new Logger<TranscodingThrottler>(new LoggerFactory()), _serverConfigurationManager, _fileSystem);
transcodingJob.TranscodingThrottler = new TranscodingThrottler(transcodingJob, new Logger<TranscodingThrottler>(new LoggerFactory()), _serverConfigurationManager, _fileSystem, _mediaEncoder);
transcodingJob.TranscodingThrottler.Start();
}
}

View File

@@ -17,7 +17,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="6.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="6.0.9" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.3.1" />

View File

@@ -2,6 +2,7 @@
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.IO;
using Microsoft.Extensions.Logging;
@@ -17,6 +18,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos
private readonly ILogger<TranscodingThrottler> _logger;
private readonly IConfigurationManager _config;
private readonly IFileSystem _fileSystem;
private readonly IMediaEncoder _mediaEncoder;
private Timer? _timer;
private bool _isPaused;
@@ -27,12 +29,14 @@ namespace Jellyfin.Api.Models.PlaybackDtos
/// <param name="logger">Instance of the <see cref="ILogger{TranscodingThrottler}"/> interface.</param>
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
public TranscodingThrottler(TranscodingJobDto job, ILogger<TranscodingThrottler> logger, IConfigurationManager config, IFileSystem fileSystem)
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
public TranscodingThrottler(TranscodingJobDto job, ILogger<TranscodingThrottler> logger, IConfigurationManager config, IFileSystem fileSystem, IMediaEncoder mediaEncoder)
{
_job = job;
_logger = logger;
_config = config;
_fileSystem = fileSystem;
_mediaEncoder = mediaEncoder;
}
/// <summary>
@@ -55,7 +59,8 @@ namespace Jellyfin.Api.Models.PlaybackDtos
try
{
await _job.Process!.StandardInput.WriteLineAsync().ConfigureAwait(false);
var resumeKey = _mediaEncoder.IsPkeyPauseSupported ? "u" : Environment.NewLine;
await _job.Process!.StandardInput.WriteAsync(resumeKey).ConfigureAwait(false);
_isPaused = false;
}
catch (Exception ex)
@@ -125,11 +130,13 @@ namespace Jellyfin.Api.Models.PlaybackDtos
{
if (!_isPaused)
{
_logger.LogDebug("Sending pause command to ffmpeg");
var pauseKey = _mediaEncoder.IsPkeyPauseSupported ? "p" : "c";
_logger.LogDebug("Sending pause command [{Key}] to ffmpeg", pauseKey);
try
{
await _job.Process!.StandardInput.WriteAsync("c").ConfigureAwait(false);
await _job.Process!.StandardInput.WriteAsync(pauseKey).ConfigureAwait(false);
_isPaused = true;
}
catch (Exception ex)

View File

@@ -18,7 +18,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Data</PackageId>
<VersionPrefix>10.8.2</VersionPrefix>
<VersionPrefix>10.8.5</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -18,8 +18,8 @@
<ItemGroup>
<PackageReference Include="BlurHashSharp" Version="1.2.0" />
<PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.2.0" />
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.79" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.1-preview.79" />
<PackageReference Include="SkiaSharp" Version="2.88.2" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.2" />
<PackageReference Include="SkiaSharp.Svg" Version="1.60.0" />
</ItemGroup>

View File

@@ -27,13 +27,13 @@
<ItemGroup>
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.7">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.7">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -37,8 +37,8 @@
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.7" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="6.0.7" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.9" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="prometheus-net" Version="6.0.0" />
<PackageReference Include="prometheus-net.AspNetCore" Version="6.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />

View File

@@ -8,7 +8,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Common</PackageId>
<VersionPrefix>10.8.2</VersionPrefix>
<VersionPrefix>10.8.5</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -892,29 +892,7 @@ namespace MediaBrowser.Controller.Entities
private static BaseItem[] SortItemsByRequest(InternalItemsQuery query, IReadOnlyList<BaseItem> items)
{
var ids = query.ItemIds;
int size = items.Count;
// ids can potentially contain non-unique guids, but query result cannot,
// so we include only first occurrence of each guid
var positions = new Dictionary<Guid, int>(size);
int index = 0;
for (int i = 0; i < ids.Length; i++)
{
if (positions.TryAdd(ids[i], index))
{
index++;
}
}
var newItems = new BaseItem[size];
for (int i = 0; i < size; i++)
{
var item = items[i];
newItems[positions[item.Id]] = item;
}
return newItems;
return items.OrderBy(i => Array.IndexOf(query.ItemIds, i.Id)).ToArray();
}
public QueryResult<BaseItem> GetItems(InternalItemsQuery query)

View File

@@ -258,10 +258,14 @@ namespace MediaBrowser.Controller.Entities.TV
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { BaseItemKind.Episode, BaseItemKind.Season },
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
DtoOptions = options,
IsMissing = user?.DisplayMissingEpisodes
DtoOptions = options
};
if (user == null || !user.DisplayMissingEpisodes)
{
query.IsMissing = false;
}
var allItems = LibraryManager.GetItemList(query);
var allSeriesEpisodes = allItems.OfType<Episode>().ToList();

View File

@@ -8,7 +8,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Controller</PackageId>
<VersionPrefix>10.8.2</VersionPrefix>
<VersionPrefix>10.8.5</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -1152,16 +1152,15 @@ namespace MediaBrowser.Controller.MediaEncoding
if (state.SubtitleStream.IsExternal)
{
var subtitlePath = state.SubtitleStream.Path;
var charsetParam = string.Empty;
if (!string.IsNullOrEmpty(state.SubtitleStream.Language))
{
var charenc = _subtitleEncoder.GetSubtitleFileCharacterSet(
subtitlePath,
state.SubtitleStream.Language,
state.MediaSource.Protocol,
CancellationToken.None).GetAwaiter().GetResult();
state.SubtitleStream,
state.SubtitleStream.Language,
state.MediaSource,
CancellationToken.None).GetAwaiter().GetResult();
if (!string.IsNullOrEmpty(charenc))
{
@@ -1173,7 +1172,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return string.Format(
CultureInfo.InvariantCulture,
"subtitles=f='{0}'{1}{2}{3}{4}{5}",
_mediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
_mediaEncoder.EscapeSubtitleFilterPath(state.SubtitleStream.Path),
charsetParam,
alphaParam,
sub2videoParam,
@@ -4977,14 +4976,14 @@ namespace MediaBrowser.Controller.MediaEncoding
// The default value of -probesize is more than enough, so leave it as is.
var ffmpegAnalyzeDuration = _config.GetFFmpegAnalyzeDuration() ?? string.Empty;
if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration))
{
analyzeDurationArgument = "-analyzeduration " + ffmpegAnalyzeDuration;
}
else if (state.MediaSource.AnalyzeDurationMs.HasValue)
if (state.MediaSource.AnalyzeDurationMs > 0)
{
analyzeDurationArgument = "-analyzeduration " + (state.MediaSource.AnalyzeDurationMs.Value * 1000).ToString(CultureInfo.InvariantCulture);
}
else if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration))
{
analyzeDurationArgument = "-analyzeduration " + ffmpegAnalyzeDuration;
}
if (!string.IsNullOrEmpty(analyzeDurationArgument))
{
@@ -5536,7 +5535,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return index;
}
if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal))
if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal))
{
index++;
}

View File

@@ -37,6 +37,12 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <returns>The version of encoder.</returns>
Version EncoderVersion { get; }
/// <summary>
/// Whether p key pausing is supported.
/// </summary>
/// <value><c>true</c> if p key pausing is supported, <c>false</c> otherwise.</value>
bool IsPkeyPauseSupported { get; }
/// <summary>
/// Gets a value indicating whether the configured Vaapi device is from AMD(radeonsi/r600 Mesa driver).
/// </summary>

View File

@@ -6,7 +6,8 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.MediaEncoding
{
@@ -37,11 +38,11 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <summary>
/// Gets the subtitle language encoding parameter.
/// </summary>
/// <param name="path">The path.</param>
/// <param name="subtitleStream">The subtitle stream.</param>
/// <param name="language">The language.</param>
/// <param name="protocol">The protocol.</param>
/// <param name="mediaSource">The media source.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>System.String.</returns>
Task<string> GetSubtitleFileCharacterSet(string path, string language, MediaProtocol protocol, CancellationToken cancellationToken);
Task<string> GetSubtitleFileCharacterSet(MediaStream subtitleStream, string language, MediaSourceInfo mediaSource, CancellationToken cancellationToken);
}
}

View File

@@ -153,7 +153,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
string output;
try
{
output = GetProcessOutput(_encoderPath, "-version", false);
output = GetProcessOutput(_encoderPath, "-version", false, null);
}
catch (Exception ex)
{
@@ -234,7 +234,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
string output;
try
{
output = GetProcessOutput(_encoderPath, "-version", false);
output = GetProcessOutput(_encoderPath, "-version", false, null);
}
catch (Exception ex)
{
@@ -341,7 +341,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
try
{
var output = GetProcessOutput(_encoderPath, "-v verbose -hide_banner -init_hw_device vaapi=va:" + renderNodePath, true);
var output = GetProcessOutput(_encoderPath, "-v verbose -hide_banner -init_hw_device vaapi=va:" + renderNodePath, true, null);
return output.Contains(driverName, StringComparison.Ordinal);
}
catch (Exception ex)
@@ -356,7 +356,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
string? output = null;
try
{
output = GetProcessOutput(_encoderPath, "-hwaccels", false);
output = GetProcessOutput(_encoderPath, "-hwaccels", false, null);
}
catch (Exception ex)
{
@@ -384,7 +384,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
string output;
try
{
output = GetProcessOutput(_encoderPath, "-h filter=" + filter, false);
output = GetProcessOutput(_encoderPath, "-h filter=" + filter, false, null);
}
catch (Exception ex)
{
@@ -402,13 +402,34 @@ namespace MediaBrowser.MediaEncoding.Encoder
return false;
}
public bool CheckSupportedRuntimeKey(string keyDesc)
{
if (string.IsNullOrEmpty(keyDesc))
{
return false;
}
string output;
try
{
output = GetProcessOutput(_encoderPath, "-hide_banner -f lavfi -i nullsrc=s=1x1:d=500 -f null -", true, "?");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error checking supported runtime key");
return false;
}
return output.Contains(keyDesc, StringComparison.Ordinal);
}
private IEnumerable<string> GetCodecs(Codec codec)
{
string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
string output;
try
{
output = GetProcessOutput(_encoderPath, "-" + codecstr, false);
output = GetProcessOutput(_encoderPath, "-" + codecstr, false, null);
}
catch (Exception ex)
{
@@ -439,7 +460,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
string output;
try
{
output = GetProcessOutput(_encoderPath, "-filters", false);
output = GetProcessOutput(_encoderPath, "-filters", false, null);
}
catch (Exception ex)
{
@@ -477,7 +498,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return dict;
}
private string GetProcessOutput(string path, string arguments, bool readStdErr)
private string GetProcessOutput(string path, string arguments, bool readStdErr, string? testKey)
{
using (var process = new Process()
{
@@ -487,6 +508,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false,
RedirectStandardInput = !string.IsNullOrEmpty(testKey),
RedirectStandardOutput = true,
RedirectStandardError = true
}
@@ -496,6 +518,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
process.Start();
if (!string.IsNullOrEmpty(testKey))
{
process.StandardInput.Write(testKey);
}
return readStdErr ? process.StandardError.ReadToEnd() : process.StandardOutput.ReadToEnd();
}
}

View File

@@ -67,6 +67,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
private List<string> _filters = new List<string>();
private IDictionary<int, bool> _filtersWithOption = new Dictionary<int, bool>();
private bool _isPkeyPauseSupported = false;
private bool _isVaapiDeviceAmd = false;
private bool _isVaapiDeviceInteliHD = false;
private bool _isVaapiDeviceInteli965 = false;
@@ -100,6 +102,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
public Version EncoderVersion => _ffmpegVersion;
public bool IsPkeyPauseSupported => _isPkeyPauseSupported;
public bool IsVaapiDeviceAmd => _isVaapiDeviceAmd;
public bool IsVaapiDeviceInteliHD => _isVaapiDeviceInteliHD;
@@ -154,6 +158,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
_threads = EncodingHelper.GetNumberOfThreads(null, options, null);
_isPkeyPauseSupported = validator.CheckSupportedRuntimeKey("p pause transcoding");
// Check the Vaapi device vendor
if (OperatingSystem.IsLinux()
&& SupportsHwaccel("vaapi")
@@ -376,15 +382,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
string analyzeDuration = string.Empty;
string ffmpegAnalyzeDuration = _config.GetFFmpegAnalyzeDuration() ?? string.Empty;
if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration))
{
analyzeDuration = "-analyzeduration " + ffmpegAnalyzeDuration;
}
else if (request.MediaSource.AnalyzeDurationMs > 0)
if (request.MediaSource.AnalyzeDurationMs > 0)
{
analyzeDuration = "-analyzeduration " +
(request.MediaSource.AnalyzeDurationMs * 1000).ToString();
}
else if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration))
{
analyzeDuration = "-analyzeduration " + ffmpegAnalyzeDuration;
}
var forceEnableLogging = request.MediaSource.Protocol != MediaProtocol.File;

View File

@@ -863,8 +863,13 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
}
else if (string.Equals(streamInfo.CodecType, "data", StringComparison.OrdinalIgnoreCase))
{
stream.Type = MediaStreamType.Data;
}
else
{
_logger.LogError("Codec Type {CodecType} unknown. The stream (index: {Index}) will be ignored. Warning: Subsequential streams will have a wrong stream specifier!", streamInfo.CodecType, streamInfo.Index);
return null;
}

View File

@@ -0,0 +1,19 @@
using Microsoft.Extensions.Logging;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
namespace MediaBrowser.MediaEncoding.Subtitles
{
/// <summary>
/// Advanced SubStation Alpha subtitle parser.
/// </summary>
public class AssParser : SubtitleEditParser<AdvancedSubStationAlpha>
{
/// <summary>
/// Initializes a new instance of the <see cref="AssParser"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public AssParser(ILogger logger) : base(logger)
{
}
}
}

View File

@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System.IO;
using System.Threading;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.MediaEncoding.Subtitles
@@ -11,15 +12,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// Parses the specified stream.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="fileExtension">The file extension.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>SubtitleTrackInfo.</returns>
SubtitleTrackInfo Parse(Stream stream, string fileExtension);
/// <summary>
/// Determines whether the file extension is supported by the parser.
/// </summary>
/// <param name="fileExtension">The file extension.</param>
/// <returns>A value indicating whether the file extension is supported.</returns>
bool SupportsFileExtension(string fileExtension);
SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken);
}
}

View File

@@ -0,0 +1,19 @@
using Microsoft.Extensions.Logging;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
namespace MediaBrowser.MediaEncoding.Subtitles
{
/// <summary>
/// SubRip subtitle parser.
/// </summary>
public class SrtParser : SubtitleEditParser<SubRip>
{
/// <summary>
/// Initializes a new instance of the <see cref="SrtParser"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public SrtParser(ILogger logger) : base(logger)
{
}
}
}

View File

@@ -0,0 +1,19 @@
using Microsoft.Extensions.Logging;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
namespace MediaBrowser.MediaEncoding.Subtitles
{
/// <summary>
/// SubStation Alpha subtitle parser.
/// </summary>
public class SsaParser : SubtitleEditParser<SubStationAlpha>
{
/// <summary>
/// Initializes a new instance of the <see cref="SsaParser"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public SsaParser(ILogger logger) : base(logger)
{
}
}
}

View File

@@ -1,14 +1,12 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using Jellyfin.Extensions;
using MediaBrowser.Model.MediaInfo;
using Microsoft.Extensions.Logging;
using Nikse.SubtitleEdit.Core.Common;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
using ILogger = Microsoft.Extensions.Logging.ILogger;
using SubtitleFormat = Nikse.SubtitleEdit.Core.SubtitleFormats.SubtitleFormat;
namespace MediaBrowser.MediaEncoding.Subtitles
@@ -16,57 +14,31 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// <summary>
/// SubStation Alpha subtitle parser.
/// </summary>
public class SubtitleEditParser : ISubtitleParser
/// <typeparam name="T">The <see cref="SubtitleFormat" />.</typeparam>
public abstract class SubtitleEditParser<T> : ISubtitleParser
where T : SubtitleFormat, new()
{
private readonly ILogger<SubtitleEditParser> _logger;
private readonly Dictionary<string, SubtitleFormat[]> _subtitleFormats;
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="SubtitleEditParser"/> class.
/// Initializes a new instance of the <see cref="SubtitleEditParser{T}"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public SubtitleEditParser(ILogger<SubtitleEditParser> logger)
protected SubtitleEditParser(ILogger logger)
{
_logger = logger;
_subtitleFormats = GetSubtitleFormats()
.Where(subtitleFormat => !string.IsNullOrEmpty(subtitleFormat.Extension))
.GroupBy(subtitleFormat => subtitleFormat.Extension.TrimStart('.'), StringComparer.OrdinalIgnoreCase)
.ToDictionary(g => g.Key, g => g.ToArray(), StringComparer.OrdinalIgnoreCase);
}
/// <inheritdoc />
public SubtitleTrackInfo Parse(Stream stream, string fileExtension)
public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
{
var subtitle = new Subtitle();
var subRip = new T();
var lines = stream.ReadAllLines().ToList();
if (!_subtitleFormats.TryGetValue(fileExtension, out var subtitleFormats))
subRip.LoadSubtitle(subtitle, lines, "untitled");
if (subRip.ErrorCount > 0)
{
throw new ArgumentException($"Unsupported file extension: {fileExtension}", nameof(fileExtension));
}
foreach (var subtitleFormat in subtitleFormats)
{
_logger.LogDebug(
"Trying to parse '{FileExtension}' subtitle using the {SubtitleFormatParser} format parser",
fileExtension,
subtitleFormat.Name);
subtitleFormat.LoadSubtitle(subtitle, lines, fileExtension);
if (subtitleFormat.ErrorCount == 0)
{
break;
}
_logger.LogError(
"{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFormatParser} format parser",
subtitleFormat.ErrorCount,
fileExtension,
subtitleFormat.Name);
}
if (subtitle.Paragraphs.Count == 0)
{
throw new ArgumentException("Unsupported format: " + fileExtension);
_logger.LogError("{ErrorCount} errors encountered while parsing subtitle", subRip.ErrorCount);
}
var trackInfo = new SubtitleTrackInfo();
@@ -85,36 +57,5 @@ namespace MediaBrowser.MediaEncoding.Subtitles
trackInfo.TrackEvents = trackEvents;
return trackInfo;
}
/// <inheritdoc />
public bool SupportsFileExtension(string fileExtension)
=> _subtitleFormats.ContainsKey(fileExtension);
private IEnumerable<SubtitleFormat> GetSubtitleFormats()
{
var subtitleFormats = new List<SubtitleFormat>();
var assembly = typeof(SubtitleFormat).Assembly;
foreach (var type in assembly.GetTypes())
{
if (!type.IsSubclassOf(typeof(SubtitleFormat)) || type.IsAbstract)
{
continue;
}
try
{
// It shouldn't be null, but the exception is caught if it is
var subtitleFormat = (SubtitleFormat)Activator.CreateInstance(type, true)!;
subtitleFormats.Add(subtitleFormat);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to create instance of the subtitle format {SubtitleFormatType}", type.Name);
}
}
return subtitleFormats;
}
}
}

View File

@@ -35,7 +35,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private readonly IMediaEncoder _mediaEncoder;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly ISubtitleParser _subtitleParser;
/// <summary>
/// The _semaphoreLocks.
@@ -49,8 +48,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
IFileSystem fileSystem,
IMediaEncoder mediaEncoder,
IHttpClientFactory httpClientFactory,
IMediaSourceManager mediaSourceManager,
ISubtitleParser subtitleParser)
IMediaSourceManager mediaSourceManager)
{
_logger = logger;
_appPaths = appPaths;
@@ -58,7 +56,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_mediaEncoder = mediaEncoder;
_httpClientFactory = httpClientFactory;
_mediaSourceManager = mediaSourceManager;
_subtitleParser = subtitleParser;
}
private string SubtitleCachePath => Path.Combine(_appPaths.DataPath, "subtitles");
@@ -76,7 +73,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
try
{
var trackInfo = _subtitleParser.Parse(stream, inputFormat);
var reader = GetReader(inputFormat);
var trackInfo = reader.Parse(stream, cancellationToken);
FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps);
@@ -235,21 +233,54 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec)
.TrimStart('.');
// Fallback to ffmpeg conversion
if (!_subtitleParser.SupportsFileExtension(currentFormat))
if (!TryGetReader(currentFormat, out _))
{
// Convert
var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, ".srt");
await ConvertTextSubtitleToSrt(subtitleStream.Path, subtitleStream.Language, mediaSource, outputPath, cancellationToken).ConfigureAwait(false);
await ConvertTextSubtitleToSrt(subtitleStream, mediaSource, outputPath, cancellationToken).ConfigureAwait(false);
return new SubtitleInfo(outputPath, MediaProtocol.File, "srt", true);
}
// It's possible that the subtitleStream and mediaSource don't share the same protocol (e.g. .STRM file with local subs)
// It's possbile that the subtitleStream and mediaSource don't share the same protocol (e.g. .STRM file with local subs)
return new SubtitleInfo(subtitleStream.Path, _mediaSourceManager.GetPathProtocol(subtitleStream.Path), currentFormat, true);
}
private bool TryGetReader(string format, [NotNullWhen(true)] out ISubtitleParser? value)
{
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
{
value = new SrtParser(_logger);
return true;
}
if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase))
{
value = new SsaParser(_logger);
return true;
}
if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase))
{
value = new AssParser(_logger);
return true;
}
value = null;
return false;
}
private ISubtitleParser GetReader(string format)
{
if (TryGetReader(format, out var reader))
{
return reader;
}
throw new ArgumentException("Unsupported format: " + format);
}
private bool TryGetWriter(string format, [NotNullWhen(true)] out ISubtitleWriter? value)
{
if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase))
@@ -320,13 +351,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// <summary>
/// Converts the text subtitle to SRT.
/// </summary>
/// <param name="inputPath">The input path.</param>
/// <param name="language">The language.</param>
/// <param name="subtitleStream">The subtitle stream.</param>
/// <param name="mediaSource">The input mediaSource.</param>
/// <param name="outputPath">The output path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
private async Task ConvertTextSubtitleToSrt(string inputPath, string language, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken)
private async Task ConvertTextSubtitleToSrt(MediaStream subtitleStream, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken)
{
var semaphore = GetLock(outputPath);
@@ -336,7 +366,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
if (!File.Exists(outputPath))
{
await ConvertTextSubtitleToSrtInternal(inputPath, language, mediaSource, outputPath, cancellationToken).ConfigureAwait(false);
await ConvertTextSubtitleToSrtInternal(subtitleStream, mediaSource, outputPath, cancellationToken).ConfigureAwait(false);
}
}
finally
@@ -348,8 +378,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// <summary>
/// Converts the text subtitle to SRT internal.
/// </summary>
/// <param name="inputPath">The input path.</param>
/// <param name="language">The language.</param>
/// <param name="subtitleStream">The subtitle stream.</param>
/// <param name="mediaSource">The input mediaSource.</param>
/// <param name="outputPath">The output path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
@@ -357,8 +386,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// <exception cref="ArgumentNullException">
/// The <c>inputPath</c> or <c>outputPath</c> is <c>null</c>.
/// </exception>
private async Task ConvertTextSubtitleToSrtInternal(string inputPath, string language, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken)
private async Task ConvertTextSubtitleToSrtInternal(MediaStream subtitleStream, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken)
{
var inputPath = subtitleStream.Path;
if (string.IsNullOrEmpty(inputPath))
{
throw new ArgumentNullException(nameof(inputPath));
@@ -371,7 +401,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)));
var encodingParam = await GetSubtitleFileCharacterSet(inputPath, language, mediaSource.Protocol, cancellationToken).ConfigureAwait(false);
var encodingParam = await GetSubtitleFileCharacterSet(subtitleStream, subtitleStream.Language, mediaSource, cancellationToken).ConfigureAwait(false);
// FFmpeg automatically convert character encoding when it is UTF-16
// If we specify character encoding, it rejects with "do not specify a character encoding" and "Unable to recode subtitle event"
@@ -389,18 +419,18 @@ namespace MediaBrowser.MediaEncoding.Subtitles
int exitCode;
using (var process = new Process
{
StartInfo = new ProcessStartInfo
{
StartInfo = new ProcessStartInfo
{
CreateNoWindow = true,
UseShellExecute = false,
FileName = _mediaEncoder.EncoderPath,
Arguments = string.Format(CultureInfo.InvariantCulture, "{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath),
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
},
EnableRaisingEvents = true
})
CreateNoWindow = true,
UseShellExecute = false,
FileName = _mediaEncoder.EncoderPath,
Arguments = string.Format(CultureInfo.InvariantCulture, "{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath),
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
},
EnableRaisingEvents = true
})
{
_logger.LogInformation("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
@@ -540,7 +570,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var processArgs = string.Format(
CultureInfo.InvariantCulture,
"-i {0} -map 0:{1} -an -vn -c:s {2} \"{3}\"",
"-i {0} -copyts -map 0:{1} -an -vn -c:s {2} \"{3}\"",
inputPath,
subtitleStreamIndex,
outputCodec,
@@ -549,18 +579,18 @@ namespace MediaBrowser.MediaEncoding.Subtitles
int exitCode;
using (var process = new Process
{
StartInfo = new ProcessStartInfo
{
StartInfo = new ProcessStartInfo
{
CreateNoWindow = true,
UseShellExecute = false,
FileName = _mediaEncoder.EncoderPath,
Arguments = processArgs,
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
},
EnableRaisingEvents = true
})
CreateNoWindow = true,
UseShellExecute = false,
FileName = _mediaEncoder.EncoderPath,
Arguments = processArgs,
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
},
EnableRaisingEvents = true
})
{
_logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments);
@@ -575,7 +605,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
throw;
}
var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(5)).ConfigureAwait(false);
var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(30)).ConfigureAwait(false);
if (!ranToCompletion)
{
@@ -698,9 +728,19 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
/// <inheritdoc />
public async Task<string> GetSubtitleFileCharacterSet(string path, string language, MediaProtocol protocol, CancellationToken cancellationToken)
public async Task<string> GetSubtitleFileCharacterSet(MediaStream subtitleStream, string language, MediaSourceInfo mediaSource, CancellationToken cancellationToken)
{
using (var stream = await GetStream(path, protocol, cancellationToken).ConfigureAwait(false))
var subtitleCodec = subtitleStream.Codec;
var path = subtitleStream.Path;
if (path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase))
{
path = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + subtitleCodec);
await ExtractTextSubtitle(mediaSource, subtitleStream, subtitleCodec, path, cancellationToken)
.ConfigureAwait(false);
}
using (var stream = await GetStream(path, mediaSource.Protocol, cancellationToken).ConfigureAwait(false))
{
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName ?? string.Empty;
@@ -723,12 +763,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
switch (protocol)
{
case MediaProtocol.Http:
{
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(new Uri(path), cancellationToken)
.ConfigureAwait(false);
return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
}
{
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(new Uri(path), cancellationToken)
.ConfigureAwait(false);
return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
}
case MediaProtocol.File:
return AsyncFile.OpenRead(path);

View File

@@ -594,6 +594,10 @@ namespace MediaBrowser.Model.Entities
<= 426 when Height <= 240 => IsInterlaced ? "240i" : "240p",
// 640x360 (16:9 square pixel format)
<= 640 when Height <= 360 => IsInterlaced ? "360i" : "360p",
// 682x384 (16:9 square pixel format)
<= 682 when Height <= 384 => IsInterlaced ? "384i" : "384p",
// 720x404 (16:9 square pixel format)
<= 720 when Height <= 404 => IsInterlaced ? "404i" : "404p",
// 854x480 (16:9 square pixel format)
<= 854 when Height <= 480 => IsInterlaced ? "480i" : "480p",
// 960x544 (16:9 square pixel format)

View File

@@ -23,6 +23,11 @@ namespace MediaBrowser.Model.Entities
/// <summary>
/// The embedded image.
/// </summary>
EmbeddedImage
EmbeddedImage,
/// <summary>
/// The data.
/// </summary>
Data
}
}

View File

@@ -8,7 +8,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Model</PackageId>
<VersionPrefix>10.8.2</VersionPrefix>
<VersionPrefix>10.8.5</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>
@@ -34,13 +34,13 @@
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
<PackageReference Include="MimeTypes" Version="2.4.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Globalization" Version="4.3.0" />
<PackageReference Include="System.Text.Json" Version="6.0.5" />
<PackageReference Include="System.Text.Json" Version="6.0.6" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,4 +1,4 @@
using System.Reflection;
[assembly: AssemblyVersion("10.8.2")]
[assembly: AssemblyFileVersion("10.8.2")]
[assembly: AssemblyVersion("10.8.5")]
[assembly: AssemblyFileVersion("10.8.5")]

View File

@@ -1,7 +1,7 @@
---
# We just wrap `build` so this is really it
name: "jellyfin"
version: "10.8.2"
version: "10.8.5"
packages:
- debian.amd64
- debian.arm64

18
debian/changelog vendored
View File

@@ -1,3 +1,21 @@
jellyfin-server (10.8.5-1) unstable; urgency=medium
* New upstream version 10.8.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.5
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 24 Sep 2022 22:01:56 -0400
jellyfin-server (10.8.4-1) unstable; urgency=medium
* New upstream version 10.8.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.4
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 13 Aug 2022 21:51:45 -0400
jellyfin-server (10.8.3-1) unstable; urgency=medium
* New upstream version 10.8.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.3
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 01 Aug 2022 20:19:48 -0400
jellyfin-server (10.8.2-1) unstable; urgency=medium
* New upstream version 10.8.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.2

View File

@@ -8,7 +8,7 @@ EnvironmentFile = /etc/default/jellyfin
User = jellyfin
Group = jellyfin
WorkingDirectory = /var/lib/jellyfin
ExecStart = /usr/bin/jellyfin ${JELLYFIN_WEB_OPT} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} ${JELLYFIN_ADDITIONAL_OPTS}
ExecStart = /usr/bin/jellyfin $JELLYFIN_WEB_OPT $JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLYFIN_NOWEBAPP_OPT $JELLYFIN_ADDITIONAL_OPTS
Restart = on-failure
TimeoutSec = 15
SuccessExitStatus=0 143

View File

@@ -5,7 +5,7 @@ Homepage: https://jellyfin.org
Standards-Version: 3.9.2
Package: jellyfin
Version: 10.8.2
Version: 10.8.5
Maintainer: Jellyfin Packaging Team <packaging@jellyfin.org>
Depends: jellyfin-server, jellyfin-web
Description: Provides the Jellyfin Free Software Media System

2
debian/rules vendored
View File

@@ -40,7 +40,7 @@ override_dh_clistrip:
override_dh_auto_build:
dotnet publish -maxcpucount:1 --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) \
"-p:DebugSymbols=false;DebugType=none" Jellyfin.Server
-p:DebugSymbols=false -p:DebugType=none Jellyfin.Server
override_dh_auto_clean:
dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true

View File

@@ -13,7 +13,7 @@ RUN yum update -yq \
&& yum install -yq @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git wget
# Install DotNET SDK
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0e83f50a-0619-45e6-8f16-dc4f41d1bb16/e0de908b2f070ef9e7e3b6ddea9d268c/dotnet-sdk-6.0.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/8159607a-e686-4ead-ac99-b4c97290a5fd/ec6070b1b2cc0651ebe57cf1bd411315/dotnet-sdk-6.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -10,4 +10,4 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# because of changes in docker and systemd we need to not build in parallel at the moment
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-x64 "-p:DebugSymbols=false;DebugType=none"
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-x64 -p:DebugSymbols=false -p:DebugType=none

View File

@@ -10,4 +10,4 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# because of changes in docker and systemd we need to not build in parallel at the moment
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm64 "-p:DebugSymbols=false;DebugType=none"
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm64 -p:DebugSymbols=false -p:DebugType=none

View File

@@ -10,4 +10,4 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# because of changes in docker and systemd we need to not build in parallel at the moment
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm "-p:DebugSymbols=false;DebugType=none"
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm -p:DebugSymbols=false -p:DebugType=none

View File

@@ -12,7 +12,7 @@ RUN dnf update -yq \
&& dnf install -yq @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel systemd wget make
# Install DotNET SDK
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0e83f50a-0619-45e6-8f16-dc4f41d1bb16/e0de908b2f070ef9e7e3b6ddea9d268c/dotnet-sdk-6.0.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/8159607a-e686-4ead-ac99-b4c97290a5fd/ec6070b1b2cc0651ebe57cf1bd411315/dotnet-sdk-6.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -17,7 +17,7 @@ RUN apt-get update -yqq \
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
# Install dotnet repository
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0e83f50a-0619-45e6-8f16-dc4f41d1bb16/e0de908b2f070ef9e7e3b6ddea9d268c/dotnet-sdk-6.0.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/8159607a-e686-4ead-ac99-b4c97290a5fd/ec6070b1b2cc0651ebe57cf1bd411315/dotnet-sdk-6.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update -yqq \
mmv build-essential lsb-release
# Install dotnet repository
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0e83f50a-0619-45e6-8f16-dc4f41d1bb16/e0de908b2f070ef9e7e3b6ddea9d268c/dotnet-sdk-6.0.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/8159607a-e686-4ead-ac99-b4c97290a5fd/ec6070b1b2cc0651ebe57cf1bd411315/dotnet-sdk-6.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update -yqq \
mmv build-essential lsb-release
# Install dotnet repository
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0e83f50a-0619-45e6-8f16-dc4f41d1bb16/e0de908b2f070ef9e7e3b6ddea9d268c/dotnet-sdk-6.0.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/8159607a-e686-4ead-ac99-b4c97290a5fd/ec6070b1b2cc0651ebe57cf1bd411315/dotnet-sdk-6.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ else
fi
# Build archives
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true"
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output dist/jellyfin-server_${version}/ -p:DebugSymbols=false -p:DebugType=none -p:UseAppHost=true
tar -czf jellyfin-server_${version}_linux-amd64.tar.gz -C dist jellyfin-server_${version}
rm -rf dist/jellyfin-server_${version}

View File

@@ -16,7 +16,7 @@ else
fi
# Build archives
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-musl-x64 --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true"
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-musl-x64 --output dist/jellyfin-server_${version}/ -p:DebugSymbols=false -p:DebugType=none -p:UseAppHost=true
tar -czf jellyfin-server_${version}_linux-amd64-musl.tar.gz -C dist jellyfin-server_${version}
rm -rf dist/jellyfin-server_${version}

View File

@@ -16,7 +16,7 @@ else
fi
# Build archives
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-arm64 --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true"
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-arm64 --output dist/jellyfin-server_${version}/ -p:DebugSymbols=false -p:DebugType=none -p:UseAppHost=true
tar -czf jellyfin-server_${version}_linux-arm64.tar.gz -C dist jellyfin-server_${version}
rm -rf dist/jellyfin-server_${version}

View File

@@ -16,7 +16,7 @@ else
fi
# Build archives
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-arm --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true"
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-arm --output dist/jellyfin-server_${version}/ -p:DebugSymbols=false -p:DebugType=none -p:UseAppHost=true
tar -czf jellyfin-server_${version}_linux-armhf.tar.gz -C dist jellyfin-server_${version}
rm -rf dist/jellyfin-server_${version}

View File

@@ -16,7 +16,7 @@ else
fi
# Build archives
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true"
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output dist/jellyfin-server_${version}/ -p:DebugSymbols=false -p:DebugType=none -p:UseAppHost=true
tar -czf jellyfin-server_${version}_macos-amd64.tar.gz -C dist jellyfin-server_${version}
rm -rf dist/jellyfin-server_${version}

View File

@@ -16,7 +16,7 @@ else
fi
# Build archives
dotnet publish Jellyfin.Server --configuration Release --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=false"
dotnet publish Jellyfin.Server --configuration Release --output dist/jellyfin-server_${version}/ -p:DebugSymbols=false -p:DebugType=none -p:UseAppHost=false
tar -czf jellyfin-server_${version}_portable.tar.gz -C dist jellyfin-server_${version}
rm -rf dist/jellyfin-server_${version}

View File

@@ -23,7 +23,7 @@ fi
output_dir="dist/jellyfin-server_${version}"
# Build binary
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output ${output_dir}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true"
dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output ${output_dir}/ -p:DebugSymbols=false -p:DebugType=none -p:UseAppHost=true
# Prepare addins
addin_build_dir="$( mktemp -d )"

View File

@@ -5,3 +5,49 @@
[Service]
#User = jellyfin
#EnvironmentFile = /etc/sysconfig/jellyfin
# Service hardening options
# These were added in PR #6953 to solve issue #6952, but some combination of
# them causes "restart.sh" functionality to break with the following error:
# sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the
# 'nosuid' option set or an NFS file system without root privileges?
# See issue #7503 for details on the troubleshooting that went into this.
# Since these were added for NixOS specifically and are above and beyond
# what 99% of systemd units do, they have been moved here as optional
# additional flags to set for maximum system security and can be enabled at
# the administrator's or package maintainer's discretion.
# Uncomment these only if you know what you're doing, and doing so may cause
# bugs with in-server Restart and potentially other functionality as well.
#NoNewPrivileges=true
#SystemCallArchitectures=native
#RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
#RestrictNamespaces=false
#RestrictRealtime=true
#RestrictSUIDSGID=true
#ProtectClock=true
#ProtectControlGroups=false
#ProtectHostname=true
#ProtectKernelLogs=false
#ProtectKernelModules=false
#ProtectKernelTunables=false
#LockPersonality=true
#PrivateTmp=false
#PrivateDevices=false
#PrivateUsers=true
#RemoveIPC=true
#SystemCallFilter=~@clock
#SystemCallFilter=~@aio
#SystemCallFilter=~@chown
#SystemCallFilter=~@cpu-emulation
#SystemCallFilter=~@debug
#SystemCallFilter=~@keyring
#SystemCallFilter=~@memlock
#SystemCallFilter=~@module
#SystemCallFilter=~@mount
#SystemCallFilter=~@obsolete
#SystemCallFilter=~@privileged
#SystemCallFilter=~@raw-io
#SystemCallFilter=~@reboot
#SystemCallFilter=~@setuid
#SystemCallFilter=~@swap
#SystemCallErrorNumber=EPERM

View File

@@ -8,44 +8,10 @@ EnvironmentFile = /etc/sysconfig/jellyfin
User = jellyfin
Group = jellyfin
WorkingDirectory = /var/lib/jellyfin
ExecStart = /usr/bin/jellyfin ${JELLYFIN_WEB_OPT} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} ${JELLYFIN_ADDITIONAL_OPTS}
ExecStart = /usr/bin/jellyfin $JELLYFIN_WEB_OPT $JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLYFIN_NOWEBAPP_OPT $JELLYFIN_ADDITIONAL_OPTS
Restart = on-failure
TimeoutSec = 15
SuccessExitStatus=0 143
NoNewPrivileges=true
SystemCallArchitectures=native
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
RestrictNamespaces=false
RestrictRealtime=true
RestrictSUIDSGID=true
ProtectClock=true
ProtectControlGroups=false
ProtectHostname=true
ProtectKernelLogs=false
ProtectKernelModules=false
ProtectKernelTunables=false
LockPersonality=true
PrivateTmp=false
PrivateDevices=false
PrivateUsers=true
RemoveIPC=true
SystemCallFilter=~@clock
SystemCallFilter=~@aio
SystemCallFilter=~@chown
SystemCallFilter=~@cpu-emulation
SystemCallFilter=~@debug
SystemCallFilter=~@keyring
SystemCallFilter=~@memlock
SystemCallFilter=~@module
SystemCallFilter=~@mount
SystemCallFilter=~@obsolete
SystemCallFilter=~@privileged
SystemCallFilter=~@raw-io
SystemCallFilter=~@reboot
SystemCallFilter=~@setuid
SystemCallFilter=~@swap
SystemCallErrorNumber=EPERM
[Install]
WantedBy = multi-user.target

View File

@@ -7,7 +7,7 @@
%endif
Name: jellyfin
Version: 10.8.2
Version: 10.8.5
Release: 1%{?dist}
Summary: The Free Software Media System
License: GPLv2
@@ -68,7 +68,7 @@ export DOTNET_CLI_TELEMETRY_OPTOUT=1
export PATH=$PATH:/usr/local/bin
# cannot use --output due to https://github.com/dotnet/sdk/issues/22220
dotnet publish --configuration Release --self-contained --runtime %{dotnet_runtime} \
"-p:DebugSymbols=false;DebugType=none" Jellyfin.Server
-p:DebugSymbols=false -p:DebugType=none Jellyfin.Server
%install
@@ -176,6 +176,12 @@ fi
%systemd_postun_with_restart jellyfin.service
%changelog
* Sat Sep 24 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.8.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.5
* Sat Aug 13 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.8.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.4
* Mon Aug 01 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.8.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.3
* Mon Aug 01 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.8.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.8.2
* Sun Jun 26 2022 Jellyfin Packaging Team <packaging@jellyfin.org>

View File

@@ -13,7 +13,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Extensions</PackageId>
<VersionPrefix>10.8.2</VersionPrefix>
<VersionPrefix>10.8.5</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -21,7 +21,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -15,9 +15,9 @@
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.17.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.9" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>

View File

@@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>

View File

@@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">

View File

@@ -7,8 +7,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>

View File

@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -22,7 +22,7 @@
<PackageReference Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.17.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">

View File

@@ -15,7 +15,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests
{
using (var stream = File.OpenRead("Test Data/example.ass"))
{
var parsed = new SubtitleEditParser(new NullLogger<SubtitleEditParser>()).Parse(stream, "ass");
var parsed = new AssParser(new NullLogger<AssParser>()).Parse(stream, CancellationToken.None);
Assert.Single(parsed.TrackEvents);
var trackEvent = parsed.TrackEvents[0];

View File

@@ -15,7 +15,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests
{
using (var stream = File.OpenRead("Test Data/example.srt"))
{
var parsed = new SubtitleEditParser(new NullLogger<SubtitleEditParser>()).Parse(stream, "srt");
var parsed = new SrtParser(new NullLogger<SrtParser>()).Parse(stream, CancellationToken.None);
Assert.Equal(2, parsed.TrackEvents.Count);
var trackEvent1 = parsed.TrackEvents[0];
@@ -37,7 +37,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests
{
using (var stream = File.OpenRead("Test Data/example2.srt"))
{
var parsed = new SubtitleEditParser(new NullLogger<SubtitleEditParser>()).Parse(stream, "srt");
var parsed = new SrtParser(new NullLogger<SrtParser>()).Parse(stream, CancellationToken.None);
Assert.Equal(2, parsed.TrackEvents.Count);
var trackEvent1 = parsed.TrackEvents[0];

View File

@@ -13,7 +13,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests
{
public class SsaParserTests
{
private readonly SubtitleEditParser _parser = new SubtitleEditParser(new NullLogger<SubtitleEditParser>());
private readonly SsaParser _parser = new SsaParser(new NullLogger<AssParser>());
[Theory]
[MemberData(nameof(Parse_MultipleDialogues_TestData))]
@@ -21,7 +21,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests
{
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(ssa)))
{
SubtitleTrackInfo subtitleTrackInfo = _parser.Parse(stream, "ssa");
SubtitleTrackInfo subtitleTrackInfo = _parser.Parse(stream, CancellationToken.None);
Assert.Equal(expectedSubtitleTrackEvents.Count, subtitleTrackInfo.TrackEvents.Count);
@@ -76,7 +76,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests
{
using (var stream = File.OpenRead("Test Data/example.ssa"))
{
var parsed = _parser.Parse(stream, "ssa");
var parsed = _parser.Parse(stream, CancellationToken.None);
Assert.Single(parsed.TrackEvents);
var trackEvent = parsed.TrackEvents[0];

View File

@@ -127,14 +127,14 @@ namespace Jellyfin.Model.Tests.Entities
[InlineData(2560, 1080, true, "1080i")]
[InlineData(4096, 3072, false, "4K")]
[InlineData(8192, 6144, false, "8K")]
[InlineData(512, 384, false, "480p")]
[InlineData(512, 384, false, "384p")]
[InlineData(576, 336, false, "360p")]
[InlineData(576, 336, true, "360i")]
[InlineData(624, 352, false, "360p")]
[InlineData(640, 352, false, "360p")]
[InlineData(640, 480, false, "480p")]
[InlineData(704, 396, false, "480p")]
[InlineData(720, 404, false, "480p")]
[InlineData(704, 396, false, "404p")]
[InlineData(720, 404, false, "404p")]
[InlineData(720, 480, false, "480p")]
[InlineData(720, 576, false, "576p")]
[InlineData(768, 576, false, "576p")]

View File

@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">

View File

@@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">

View File

@@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>

View File

@@ -13,7 +13,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">

View File

@@ -21,7 +21,7 @@
<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">

View File

@@ -9,9 +9,9 @@
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.17.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.9" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>

View File

@@ -10,9 +10,9 @@
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.17.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.9" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>

View File

@@ -13,7 +13,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">