Compare commits

...

41 Commits

Author SHA1 Message Date
Joshua M. Boniface
dbbf97e588 Fix version in spec 2020-04-13 00:24:43 -04:00
Joshua M. Boniface
4e9df69ffd Merge pull request #2847 from mark-monteiro/fix-build
Fix compilation error in HttpListenerHost
2020-04-12 21:35:43 -04:00
Mark Monteiro
7f38ef4c3c Fix compilation error in HttpListenerHost 2020-04-12 20:49:54 -04:00
Joshua M. Boniface
16549dead9 Bump version to 10.5.4 2020-04-12 19:24:56 -04:00
Joshua M. Boniface
9bd1a9d19c Merge pull request #2715 from nyanmisaka/libfdk-aac
Prefer to use libfdk_aac encoder for better audio quality when it is available

(cherry picked from commit bf92694f8b)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:19:00 -04:00
Joshua M. Boniface
67194994f9 Merge pull request #2783 from JustAMan/better-cancel-msg
Add logging of URL being processed when logging an error

(cherry picked from commit 2be6550db4)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:18:22 -04:00
Vasily
c249e15f48 Merge pull request #2782 from JustAMan/fix-ssa-delivery
Fix support for attachments with baseURL set

(cherry picked from commit 6386b9b1b9)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 16:51:11 -04:00
Anthony Lavado
48ba5a9a30 Merge pull request #2779 from KristupasSavickas/fix-docker-arm-ffmpeg-path
Fix ffmpeg path on ARM docker image

(cherry picked from commit 6d98c0b62a)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 16:50:27 -04:00
Bond-009
dd13f8d16a Merge pull request #2821 from nyanmisaka/mpeg4
Fix MPEG4 broken on VAAPI

(cherry picked from commit 84dba64644)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 15:53:12 -04:00
dkanada
b43a8a56dc Merge pull request #2796 from JustAMan/fix-transcode-reasons
Make codec check in profile examine profile type first

(cherry picked from commit aeedd06f51)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 15:52:39 -04:00
Bond-009
3ec18f085e Merge pull request #2785 from nyanmisaka/mpge4-profile15
Fix MPEG4 packback error regression on vaapi

(cherry picked from commit b16b58bc57)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 15:51:47 -04:00
dkanada
f2728b5a92 Merge pull request #2758 from Bond-009/plugininstalled
Remove PluginInstalled

(cherry picked from commit 0cd7cd611e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 15:50:09 -04:00
Bond-009
ee47a75f9f Merge pull request #2721 from PrplHaz4/patch-2
Separate Channels permissions from All Libraries

(cherry picked from commit 3a98ad8255)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 15:49:32 -04:00
Joshua M. Boniface
66e7e8bcd2 Make the portable packages build the right tag
Will change for 10.5.4, but quickfix for now
2020-04-05 15:20:08 -04:00
Joshua M. Boniface
0de3a9465e Fix version in RPM spec 2020-04-05 14:58:16 -04:00
Vasily
b2f7417365 Merge pull request #2559 from whooo/295-fix
Add descriptive TV episode titles for DLNA browsing

(cherry picked from commit a37b69a493)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:51:29 -04:00
Vasily
bf0c07abfe Merge pull request #2503 from nyanmisaka/vaapi
Fix various bugs in HWA subtitle burn-in

(cherry picked from commit 9aefb41512)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:51:08 -04:00
Bond-009
3a4cd01b13 Merge pull request #2740 from JustAMan/fix-livetv
Fix GetLocalApiUrl for cases with https enabled

(cherry picked from commit b3283e37f2)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:44:41 -04:00
Anthony Lavado
7059761806 Merge pull request #2730 from Bond-009/plugincrash
Try to not crash on unsupported plugin load

(cherry picked from commit c9919f4633)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:44:12 -04:00
dkanada
2cde59af44 Merge pull request #2723 from jairbubbles/updateSkiaForArm
Update Jellyfin.SkiaSharp.NativeAssets.LinuxArm to version 1.68.1

(cherry picked from commit 58900bb57e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:43:51 -04:00
Anthony Lavado
52a850cc9b Merge pull request #2720 from dkanada/music
Fix custom musicbrainz servers

(cherry picked from commit 8c8a396cd6)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:43:32 -04:00
dkanada
54435a1243 Merge pull request #2712 from joshuaboniface/fix-ldap-issues
Revert #2146 ordering change

(cherry picked from commit 9e82e7c847)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:42:56 -04:00
Bond-009
899be44388 Merge pull request #2674 from JustAMan/fix-attachments-scan
Make variables binding correspond with column names

(cherry picked from commit 10050a55a5)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:42:30 -04:00
dkanada
354079862e Merge pull request #2668 from mark-monteiro/fix-application-host-dispose
Fix ApplicationHost Dispose() method

(cherry picked from commit 622106467e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:41:53 -04:00
Bond-009
01db9af821 Merge pull request #2655 from lfoust/tvdbruntimefix
Fix FormatException when mapping TVDB series

(cherry picked from commit 632323969f)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:41:28 -04:00
Bond-009
9da2635d86 Merge pull request #2653 from iwalton3/fix-embedded-subtitles
Fix embedded mkv subtitles.

(cherry picked from commit 1345e699fa)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:40:59 -04:00
Joshua M. Boniface
4caa597cde Bump version to 10.5.3
Include quick robustness fix in Docker container clone too.
2020-04-05 12:40:29 -04:00
dkanada
da34bd940e Merge pull request #2478 from JustAMan/fix-search-order
Fix ordering of search results

(cherry picked from commit 0d9787dfb4)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 15:25:11 -04:00
Joshua M. Boniface
54efde4073 Merge pull request #2642 from mark-monteiro/fix-extras
Add missing null check when retrieving extras

(cherry picked from commit 425bd2b01b)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 15:24:54 -04:00
Joshua M. Boniface
02cfa15582 Quickly fix failing curl in ARM Dockerfile 2020-03-22 15:02:03 -04:00
Joshua M. Boniface
0e171d794c Bump version to 10.5.2 2020-03-22 12:13:59 -04:00
dkanada
d5f2384375 Merge pull request #2617 from Shawmon/wasm-mimetype
add wasm mimetype

(cherry picked from commit af5d3e8eae)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 11:48:18 -04:00
dkanada
816b3f5c2e Merge pull request #2622 from Artiume/patch-5
Fix Release 10.5.z
2020-03-21 16:26:16 +09:00
artiume
a234388552 Fix arm64 2020-03-17 10:34:25 -04:00
artiume
30d38bd5c6 Update armhf 2020-03-17 10:33:06 -04:00
artiume
9f49fe2e99 Fix Release 10.5.z 2020-03-17 09:38:22 -04:00
Joshua M. Boniface
f720a0fca2 Fix mangled Dockerfiles 2020-03-16 09:30:01 -04:00
Joshua M. Boniface
aadff77531 Merge pull request #2607 from joshuaboniface/fix-fedora
Correct BuildRequires and NodeJS for Fedora/CentOS

(cherry picked from commit ef4dfd4461)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:06:22 -04:00
dkanada
89fc5aa11a Merge pull request #2582 from Bond-009/subs
Fix subtitles

(cherry picked from commit 6960f0af67)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:05:41 -04:00
dkanada
cb91595a24 Merge pull request #2541 from joshuaboniface/fix-docker-arm
Fix curl for Jellyfin GPG key

(cherry picked from commit bf34105af3)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:05:13 -04:00
Joshua M. Boniface
6233bae7f0 Bump version to 10.5.1 2020-03-15 23:04:07 -04:00
31 changed files with 396 additions and 288 deletions

View File

@@ -127,6 +127,7 @@
- [xosdy](https://github.com/xosdy) - [xosdy](https://github.com/xosdy)
- [XVicarious](https://github.com/XVicarious) - [XVicarious](https://github.com/XVicarious)
- [YouKnowBlom](https://github.com/YouKnowBlom) - [YouKnowBlom](https://github.com/YouKnowBlom)
- [KristupasSavickas](https://github.com/KristupasSavickas)
# Emby Contributors # Emby Contributors

View File

@@ -2,10 +2,11 @@ ARG DOTNET_VERSION=3.1
ARG FFMPEG_VERSION=latest ARG FFMPEG_VERSION=latest
FROM node:alpine as web-builder FROM node:alpine as web-builder
ARG JELLYFIN_WEB_VERSION=master ARG JELLYFIN_WEB_VERSION=10.5.4
RUN apk add curl git \ RUN apk add curl git \
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && git clone --branch release-10.5.z --single-branch https://github.com/jellyfin/jellyfin-web.git \
&& cd jellyfin-web-* \ && cd jellyfin-web \
&& git checkout tags/v${JELLYFIN_WEB_VERSION} \
&& yarn install \ && yarn install \
&& yarn build \ && yarn build \
&& mv dist /dist && mv dist /dist

View File

@@ -6,10 +6,11 @@ ARG DOTNET_VERSION=3.1
FROM node:alpine as web-builder FROM node:alpine as web-builder
ARG JELLYFIN_WEB_VERSION=master ARG JELLYFIN_WEB_VERSION=10.5.4
RUN apk add curl git \ RUN apk add curl git \
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && git clone --branch release-10.5.z --single-branch https://github.com/jellyfin/jellyfin-web.git \
&& cd jellyfin-web-* \ && cd jellyfin-web \
&& git checkout tags/v${JELLYFIN_WEB_VERSION} \
&& yarn install \ && yarn install \
&& yarn build \ && yarn build \
&& mv dist /dist && mv dist /dist
@@ -38,8 +39,8 @@ ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
RUN apt-get update \ RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg curl && \ && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg curl && \
curl -s https://repo.jellyfin.org/debian/jellyfin_team.gpg.key | apt-key add - && \ curl -ks https://repo.jellyfin.org/debian/jellyfin_team.gpg.key | apt-key add - && \
curl -s https://keyserver.ubuntu.com/pks/lookup?op=get\&search=0x6587ffd6536b8826e88a62547876ae518cbcf2f2 | apt-key add - && \ curl -ks https://keyserver.ubuntu.com/pks/lookup?op=get\&search=0x6587ffd6536b8826e88a62547876ae518cbcf2f2 | apt-key add - && \
echo 'deb [arch=armhf] https://repo.jellyfin.org/debian buster main' > /etc/apt/sources.list.d/jellyfin.list && \ echo 'deb [arch=armhf] https://repo.jellyfin.org/debian buster main' > /etc/apt/sources.list.d/jellyfin.list && \
echo "deb http://ppa.launchpad.net/ubuntu-raspi2/ppa/ubuntu bionic main">> /etc/apt/sources.list.d/raspbins.list && \ echo "deb http://ppa.launchpad.net/ubuntu-raspi2/ppa/ubuntu bionic main">> /etc/apt/sources.list.d/raspbins.list && \
apt-get update && \ apt-get update && \
@@ -69,4 +70,4 @@ VOLUME /cache /config /media
ENTRYPOINT ["./jellyfin/jellyfin", \ ENTRYPOINT ["./jellyfin/jellyfin", \
"--datadir", "/config", \ "--datadir", "/config", \
"--cachedir", "/cache", \ "--cachedir", "/cache", \
"--ffmpeg", "/usr/lib/jellyfin-ffmpeg"] "--ffmpeg", "/usr/lib/jellyfin-ffmpeg/ffmpeg"]

View File

@@ -6,10 +6,11 @@ ARG DOTNET_VERSION=3.1
FROM node:alpine as web-builder FROM node:alpine as web-builder
ARG JELLYFIN_WEB_VERSION=master ARG JELLYFIN_WEB_VERSION=10.5.4
RUN apk add curl git \ RUN apk add curl git \
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && git clone --branch release-10.5.z --single-branch https://github.com/jellyfin/jellyfin-web.git \
&& cd jellyfin-web-* \ && cd jellyfin-web \
&& git checkout tags/v${JELLYFIN_WEB_VERSION} \
&& yarn install \ && yarn install \
&& yarn build \ && yarn build \
&& mv dist /dist && mv dist /dist

View File

@@ -436,6 +436,29 @@ namespace Emby.Dlna.Didl
return number + " - " + item.Name; return number + " - " + item.Name;
} }
} }
else if (item is Episode ep)
{
var parent = ep.GetParent();
var name = parent.Name + " - ";
if (ep.ParentIndexNumber.HasValue)
{
name += "S" + ep.ParentIndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
}
else if (!item.IndexNumber.HasValue)
{
return name + " - " + item.Name;
}
name += "E" + ep.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
if (ep.IndexNumberEnd.HasValue)
{
name += "-" + ep.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture);
}
name += " - " + item.Name;
return name;
}
return item.Name; return item.Name;
} }

View File

@@ -1016,48 +1016,12 @@ namespace Emby.Server.Implementations
AuthenticatedAttribute.AuthService = AuthService; AuthenticatedAttribute.AuthService = AuthService;
} }
private async void PluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> args)
{
string dir = Path.Combine(ApplicationPaths.PluginsPath, args.Argument.name);
var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.AllDirectories)
.Select(Assembly.LoadFrom)
.SelectMany(x => x.ExportedTypes)
.Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && !x.IsGenericType)
.ToArray();
int oldLen = _allConcreteTypes.Length;
Array.Resize(ref _allConcreteTypes, oldLen + types.Length);
types.CopyTo(_allConcreteTypes, oldLen);
var plugins = types.Where(x => x.IsAssignableFrom(typeof(IPlugin)))
.Select(CreateInstanceSafe)
.Where(x => x != null)
.Cast<IPlugin>()
.Select(LoadPlugin)
.Where(x => x != null)
.ToArray();
oldLen = _plugins.Length;
Array.Resize(ref _plugins, oldLen + plugins.Length);
plugins.CopyTo(_plugins, oldLen);
var entries = types.Where(x => x.IsAssignableFrom(typeof(IServerEntryPoint)))
.Select(CreateInstanceSafe)
.Where(x => x != null)
.Cast<IServerEntryPoint>()
.ToList();
await Task.WhenAll(StartEntryPoints(entries, true)).ConfigureAwait(false);
await Task.WhenAll(StartEntryPoints(entries, false)).ConfigureAwait(false);
}
/// <summary> /// <summary>
/// Finds the parts. /// Finds the parts.
/// </summary> /// </summary>
public void FindParts() public void FindParts()
{ {
InstallationManager = ServiceProvider.GetService<IInstallationManager>(); InstallationManager = ServiceProvider.GetService<IInstallationManager>();
InstallationManager.PluginInstalled += PluginInstalled;
if (!ServerConfigurationManager.Configuration.IsPortAuthorized) if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
{ {
@@ -1165,7 +1129,7 @@ namespace Emby.Server.Implementations
{ {
exportedTypes = ass.GetExportedTypes(); exportedTypes = ass.GetExportedTypes();
} }
catch (TypeLoadException ex) catch (FileNotFoundException ex)
{ {
Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName); Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName);
continue; continue;
@@ -1517,18 +1481,10 @@ namespace Emby.Server.Implementations
public string GetLocalApiUrl(ReadOnlySpan<char> host) public string GetLocalApiUrl(ReadOnlySpan<char> host)
{ {
var url = new StringBuilder(64); var url = new StringBuilder(64);
if (EnableHttps) url.Append(EnableHttps ? "https://" : "http://")
{ .Append(host)
url.Append("https://");
}
else
{
url.Append("http://");
}
url.Append(host)
.Append(':') .Append(':')
.Append(HttpPort); .Append(EnableHttps ? HttpsPort : HttpPort);
string baseUrl = ServerConfigurationManager.Configuration.BaseUrl; string baseUrl = ServerConfigurationManager.Configuration.BaseUrl;
if (baseUrl.Length != 0) if (baseUrl.Length != 0)
@@ -1801,7 +1757,7 @@ namespace Emby.Server.Implementations
} }
_userRepository?.Dispose(); _userRepository?.Dispose();
_displayPreferencesRepository.Dispose(); _displayPreferencesRepository?.Dispose();
} }
_userRepository = null; _userRepository = null;

View File

@@ -2914,29 +2914,30 @@ namespace Emby.Server.Implementations.Data
private string GetOrderByText(InternalItemsQuery query) private string GetOrderByText(InternalItemsQuery query)
{ {
var orderBy = query.OrderBy; var orderBy = query.OrderBy;
if (string.IsNullOrEmpty(query.SearchTerm)) bool hasSimilar = query.SimilarTo != null;
bool hasSearch = !string.IsNullOrEmpty(query.SearchTerm);
if (hasSimilar || hasSearch)
{ {
int oldLen = orderBy.Count; List<(string, SortOrder)> prepend = new List<(string, SortOrder)>(4);
if (oldLen == 0 && query.SimilarTo != null) if (hasSearch)
{ {
var arr = new (string, SortOrder)[oldLen + 2]; prepend.Add(("SearchScore", SortOrder.Descending));
orderBy.CopyTo(arr, 0); prepend.Add((ItemSortBy.SortName, SortOrder.Ascending));
arr[oldLen] = ("SimilarityScore", SortOrder.Descending);
arr[oldLen + 1] = (ItemSortBy.Random, SortOrder.Ascending);
query.OrderBy = arr;
}
}
else
{
query.OrderBy = new[]
{
("SearchScore", SortOrder.Descending),
(ItemSortBy.SortName, SortOrder.Ascending)
};
} }
if (hasSimilar)
{
prepend.Add(("SimilarityScore", SortOrder.Descending));
prepend.Add((ItemSortBy.Random, SortOrder.Ascending));
}
if (orderBy.Count == 0) var arr = new (string, SortOrder)[prepend.Count + orderBy.Count];
prepend.CopyTo(arr, 0);
orderBy.CopyTo(arr, prepend.Count);
orderBy = query.OrderBy = arr;
}
else if (orderBy.Count == 0)
{ {
return string.Empty; return string.Empty;
} }
@@ -6287,8 +6288,8 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
statement.TryBind("@Codec" + index, attachment.Codec); statement.TryBind("@Codec" + index, attachment.Codec);
statement.TryBind("@CodecTag" + index, attachment.CodecTag); statement.TryBind("@CodecTag" + index, attachment.CodecTag);
statement.TryBind("@Comment" + index, attachment.Comment); statement.TryBind("@Comment" + index, attachment.Comment);
statement.TryBind("@FileName" + index, attachment.FileName); statement.TryBind("@Filename" + index, attachment.FileName);
statement.TryBind("@MimeType" + index, attachment.MimeType); statement.TryBind("@MIMEType" + index, attachment.MimeType);
} }
statement.Reset(); statement.Reset();

View File

@@ -223,7 +223,7 @@ namespace Emby.Server.Implementations.HttpServer
} }
} }
private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace) private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace, string urlToLog)
{ {
try try
{ {
@@ -231,11 +231,11 @@ namespace Emby.Server.Implementations.HttpServer
if (logExceptionStackTrace) if (logExceptionStackTrace)
{ {
_logger.LogError(ex, "Error processing request"); _logger.LogError(ex, "Error processing request. URL: {Url}", urlToLog);
} }
else else
{ {
_logger.LogError("Error processing request: {Message}", ex.Message); _logger.LogError("Error processing request: {Message}. URL: {Url}", ex.Message.TrimEnd('.'), urlToLog);
} }
var httpRes = httpReq.Response; var httpRes = httpReq.Response;
@@ -255,7 +255,7 @@ namespace Emby.Server.Implementations.HttpServer
} }
catch (Exception errorEx) catch (Exception errorEx)
{ {
_logger.LogError(errorEx, "Error this.ProcessRequest(context)(Exception while writing error to the response)"); _logger.LogError(errorEx, "Error this.ProcessRequest(context)(Exception while writing error to the response). URL: {Url}", urlToLog);
} }
} }
@@ -440,7 +440,7 @@ namespace Emby.Server.Implementations.HttpServer
var stopWatch = new Stopwatch(); var stopWatch = new Stopwatch();
stopWatch.Start(); stopWatch.Start();
var httpRes = httpReq.Response; var httpRes = httpReq.Response;
string urlToLog = null; string urlToLog = GetUrlToLog(urlString);
string remoteIp = httpReq.RemoteIp; string remoteIp = httpReq.RemoteIp;
try try
@@ -486,8 +486,6 @@ namespace Emby.Server.Implementations.HttpServer
return; return;
} }
urlToLog = GetUrlToLog(urlString);
if (string.Equals(localPath, _baseUrlPrefix + "/", StringComparison.OrdinalIgnoreCase) if (string.Equals(localPath, _baseUrlPrefix + "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(localPath, _baseUrlPrefix, StringComparison.OrdinalIgnoreCase) || string.Equals(localPath, _baseUrlPrefix, StringComparison.OrdinalIgnoreCase)
|| string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase) || string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase)
@@ -519,22 +517,21 @@ namespace Emby.Server.Implementations.HttpServer
} }
else else
{ {
await ErrorHandler(new FileNotFoundException(), httpReq, false).ConfigureAwait(false); await ErrorHandler(new FileNotFoundException(), httpReq, false, urlToLog).ConfigureAwait(false);
} }
} }
catch (Exception ex) when (ex is SocketException || ex is IOException || ex is OperationCanceledException) catch (Exception ex) when (ex is SocketException || ex is IOException || ex is OperationCanceledException)
{ {
await ErrorHandler(ex, httpReq, false).ConfigureAwait(false); await ErrorHandler(ex, httpReq, false, urlToLog).ConfigureAwait(false);
} }
catch (SecurityException ex) catch (SecurityException ex)
{ {
await ErrorHandler(ex, httpReq, false).ConfigureAwait(false); await ErrorHandler(ex, httpReq, false, urlToLog).ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
var logException = !string.Equals(ex.GetType().Name, "SocketException", StringComparison.OrdinalIgnoreCase); var logException = !string.Equals(ex.GetType().Name, "SocketException", StringComparison.OrdinalIgnoreCase);
await ErrorHandler(ex, httpReq, logException, urlToLog).ConfigureAwait(false);
await ErrorHandler(ex, httpReq, logException).ConfigureAwait(false);
} }
finally finally
{ {

View File

@@ -1401,6 +1401,16 @@ namespace Emby.Server.Implementations.Session
user = _userManager.GetUserByName(request.Username); user = _userManager.GetUserByName(request.Username);
} }
if (enforcePassword)
{
user = await _userManager.AuthenticateUser(
request.Username,
request.Password,
request.PasswordSha1,
request.RemoteEndPoint,
true).ConfigureAwait(false);
}
if (user == null) if (user == null)
{ {
AuthenticationFailed?.Invoke(this, new GenericEventArgs<AuthenticationRequest>(request)); AuthenticationFailed?.Invoke(this, new GenericEventArgs<AuthenticationRequest>(request));
@@ -1413,16 +1423,6 @@ namespace Emby.Server.Implementations.Session
throw new SecurityException("User is not allowed access from this device."); throw new SecurityException("User is not allowed access from this device.");
} }
if (enforcePassword)
{
user = await _userManager.AuthenticateUser(
request.Username,
request.Password,
request.PasswordSha1,
request.RemoteEndPoint,
true).ConfigureAwait(false);
}
var token = GetAuthorizationToken(user, request.DeviceId, request.App, request.AppVersion, request.DeviceName); var token = GetAuthorizationToken(user, request.DeviceId, request.App, request.AppVersion, request.DeviceName);
var session = LogSessionActivity( var session = LogSessionActivity(

View File

@@ -14,7 +14,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="SkiaSharp" Version="1.68.1" /> <PackageReference Include="SkiaSharp" Version="1.68.1" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.1" /> <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.1" />
<PackageReference Include="Jellyfin.SkiaSharp.NativeAssets.LinuxArm" Version="1.68.0" /> <PackageReference Include="Jellyfin.SkiaSharp.NativeAssets.LinuxArm" Version="1.68.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -927,59 +927,67 @@ namespace MediaBrowser.Api.Playback.Hls
} }
else else
{ {
var gopArg = string.Empty;
var keyFrameArg = string.Format( var keyFrameArg = string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
" -force_key_frames:0 \"expr:gte(t,{0}+n_forced*{1})\"", " -force_key_frames:0 \"expr:gte(t,{0}+n_forced*{1})\"",
GetStartNumber(state) * state.SegmentLength, GetStartNumber(state) * state.SegmentLength,
state.SegmentLength); state.SegmentLength);
if (state.TargetFramerate.HasValue)
var framerate = state.VideoStream?.RealFrameRate;
if (framerate != null && framerate.HasValue)
{ {
// This is to make sure keyframe interval is limited to our segment, // This is to make sure keyframe interval is limited to our segment,
// as forcing keyframes is not enough. // as forcing keyframes is not enough.
// Example: we encoded half of desired length, then codec detected // Example: we encoded half of desired length, then codec detected
// scene cut and inserted a keyframe; next forced keyframe would // scene cut and inserted a keyframe; next forced keyframe would
// be created outside of segment, which breaks seeking. // be created outside of segment, which breaks seeking
keyFrameArg += string.Format( // -sc_threshold 0 is used to prevent the hardware encoder from post processing to break the set keyframe
gopArg = string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
" -g {0} -keyint_min {0}", " -g {0} -keyint_min {0} -sc_threshold 0",
(int)(state.SegmentLength * state.TargetFramerate) Math.Ceiling(state.SegmentLength * framerate.Value)
); );
} }
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()); args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset());
// Unable to force key frames to h264_qsv transcode // Unable to force key frames using these hw encoders, set key frames by GOP
if (string.Equals(codec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) if (string.Equals(codec, "h264_qsv", StringComparison.OrdinalIgnoreCase)
|| string.Equals(codec, "h264_nvenc", StringComparison.OrdinalIgnoreCase)
|| string.Equals(codec, "h264_amf", StringComparison.OrdinalIgnoreCase))
{ {
Logger.LogInformation("Bug Workaround: Disabling force_key_frames for h264_qsv"); args += " " + gopArg;
} }
else else
{ {
args += " " + keyFrameArg; args += " " + keyFrameArg + gopArg;
} }
//args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0"; //args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0";
// Add resolution params, if specified var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
if (!hasGraphicalSubs)
{
args += EncodingHelper.GetOutputSizeParam(state, encodingOptions, codec, true);
}
// This is for internal graphical subs // This is for graphical subs
if (hasGraphicalSubs) if (hasGraphicalSubs)
{ {
args += EncodingHelper.GetGraphicalSubtitleParam(state, encodingOptions, codec); args += EncodingHelper.GetGraphicalSubtitleParam(state, encodingOptions, codec);
} }
// Add resolution params, if specified
//args += " -flags -global_header"; else
{
args += EncodingHelper.GetOutputSizeParam(state, encodingOptions, codec);
} }
if (args.IndexOf("-copyts", StringComparison.OrdinalIgnoreCase) == -1) // -start_at_zero is necessary to use with -ss when seeking,
// otherwise the target position cannot be determined.
if (!(state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream))
{ {
args += " -copyts"; args += " -start_at_zero";
}
//args += " -flags -global_header";
} }
if (!string.IsNullOrEmpty(state.OutputVideoSync)) if (!string.IsNullOrEmpty(state.OutputVideoSync))
@@ -1024,7 +1032,7 @@ namespace MediaBrowser.Api.Playback.Hls
} }
return string.Format( return string.Format(
"{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -f hls -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {6} -individual_header_trailer 0 -hls_segment_type {7} -start_number {8} -hls_segment_filename \"{9}\" -hls_playlist_type vod -hls_list_size 0 -y \"{10}\"", "{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -copyts -avoid_negative_ts disabled -f hls -max_delay 5000000 -hls_time {6} -individual_header_trailer 0 -hls_segment_type {7} -start_number {8} -hls_segment_filename \"{9}\" -hls_playlist_type vod -hls_list_size 0 -y \"{10}\"",
inputModifier, inputModifier,
EncodingHelper.GetInputArgument(state, encodingOptions), EncodingHelper.GetInputArgument(state, encodingOptions),
threads, threads,

View File

@@ -573,8 +573,7 @@ namespace MediaBrowser.Api.Playback
{ {
attachment.DeliveryUrl = string.Format( attachment.DeliveryUrl = string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
"{0}/Videos/{1}/{2}/Attachments/{3}", "/Videos/{0}/{1}/Attachments/{2}",
ServerConfigurationManager.Configuration.BaseUrl,
item.Id, item.Id,
mediaSource.Id, mediaSource.Id,
attachment.Index); attachment.Index);

View File

@@ -213,7 +213,10 @@ namespace MediaBrowser.Api.UserLibrary
request.IncludeItemTypes = "Playlist"; request.IncludeItemTypes = "Playlist";
} }
bool isInEnabledFolder = user.Policy.EnabledFolders.Any(i => new Guid(i) == item.Id); bool isInEnabledFolder = user.Policy.EnabledFolders.Any(i => new Guid(i) == item.Id)
// Assume all folders inside an EnabledChannel are enabled
|| user.Policy.EnabledChannels.Any(i => new Guid(i) == item.Id);
var collectionFolders = _libraryManager.GetCollectionFolders(item); var collectionFolders = _libraryManager.GetCollectionFolders(item);
foreach (var collectionFolder in collectionFolders) foreach (var collectionFolder in collectionFolders)
{ {
@@ -225,7 +228,7 @@ namespace MediaBrowser.Api.UserLibrary
} }
} }
if (!(item is UserRootFolder) && !user.Policy.EnableAllFolders && !isInEnabledFolder) if (!(item is UserRootFolder) && !user.Policy.EnableAllFolders && !isInEnabledFolder && !user.Policy.EnableAllChannels)
{ {
Logger.LogWarning("{UserName} is not permitted to access Library {ItemName}.", user.Name, item.Name); Logger.LogWarning("{UserName} is not permitted to access Library {ItemName}.", user.Name, item.Name);
return new QueryResult<BaseItem> return new QueryResult<BaseItem>

View File

@@ -178,6 +178,7 @@ namespace MediaBrowser.Controller.Entities
[JsonIgnore] [JsonIgnore]
public int? TotalBitrate { get; set; } public int? TotalBitrate { get; set; }
[JsonIgnore] [JsonIgnore]
public ExtraType? ExtraType { get; set; } public ExtraType? ExtraType { get; set; }
@@ -2883,7 +2884,7 @@ namespace MediaBrowser.Controller.Entities
public IEnumerable<BaseItem> GetExtras(IReadOnlyCollection<ExtraType> extraTypes) public IEnumerable<BaseItem> GetExtras(IReadOnlyCollection<ExtraType> extraTypes)
{ {
return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i != null && extraTypes.Contains(i.ExtraType.Value)); return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i?.ExtraType != null && extraTypes.Contains(i.ExtraType.Value));
} }
public IEnumerable<BaseItem> GetTrailers() public IEnumerable<BaseItem> GetTrailers()

View File

@@ -78,8 +78,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (!string.IsNullOrEmpty(hwType) if (!string.IsNullOrEmpty(hwType)
&& encodingOptions.EnableHardwareEncoding && encodingOptions.EnableHardwareEncoding
&& codecMap.ContainsKey(hwType) && codecMap.ContainsKey(hwType))
&& CheckVaapi(state, hwType, encodingOptions))
{ {
var preferredEncoder = codecMap[hwType]; var preferredEncoder = codecMap[hwType];
@@ -93,23 +92,6 @@ namespace MediaBrowser.Controller.MediaEncoding
return defaultEncoder; return defaultEncoder;
} }
private bool CheckVaapi(EncodingJobInfo state, string hwType, EncodingOptions encodingOptions)
{
if (!string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase))
{
// No vaapi requested, return OK.
return true;
}
if (string.IsNullOrEmpty(encodingOptions.VaapiDevice))
{
// No device specified, return OK.
return true;
}
return IsVaapiSupported(state);
}
private bool IsVaapiSupported(EncodingJobInfo state) private bool IsVaapiSupported(EncodingJobInfo state)
{ {
var videoStream = state.VideoStream; var videoStream = state.VideoStream;
@@ -424,7 +406,13 @@ namespace MediaBrowser.Controller.MediaEncoding
if (string.Equals(codec, "aac", StringComparison.OrdinalIgnoreCase)) if (string.Equals(codec, "aac", StringComparison.OrdinalIgnoreCase))
{ {
return "aac -strict experimental"; // Use libfdk_aac for better audio quality if using custom build of FFmpeg which has fdk_aac support
if (_mediaEncoder.SupportsEncoder("libfdk_aac"))
{
return "libfdk_aac";
}
return "aac";
} }
if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase)) if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase))
@@ -460,16 +448,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (state.IsVideoRequest if (state.IsVideoRequest
&& string.Equals(encodingOptions.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)) && string.Equals(encodingOptions.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
{ {
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; arg.Append("-hwaccel vaapi -hwaccel_output_format vaapi")
var hwOutputFormat = "vaapi";
if (hasGraphicalSubs)
{
hwOutputFormat = "yuv420p";
}
arg.Append("-hwaccel vaapi -hwaccel_output_format ")
.Append(hwOutputFormat)
.Append(" -vaapi_device ") .Append(" -vaapi_device ")
.Append(encodingOptions.VaapiDevice) .Append(encodingOptions.VaapiDevice)
.Append(' '); .Append(' ');
@@ -481,19 +460,25 @@ namespace MediaBrowser.Controller.MediaEncoding
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions);
var outputVideoCodec = GetVideoEncoder(state, encodingOptions); var outputVideoCodec = GetVideoEncoder(state, encodingOptions);
if (encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv", StringComparison.OrdinalIgnoreCase)) var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
if (!hasTextSubs)
{ {
if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)) // While using QSV encoder
if ((outputVideoCodec ?? string.Empty).IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1)
{
// While using QSV decoder
if ((videoDecoder ?? string.Empty).IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1)
{ {
arg.Append("-hwaccel qsv "); arg.Append("-hwaccel qsv ");
} }
// While using SW decoder
else else
{ {
arg.Append("-init_hw_device qsv=hw -filter_hw_device hw "); arg.Append("-init_hw_device qsv=hw -filter_hw_device hw ");
} }
} }
}
arg.Append(videoDecoder + " ");
} }
arg.Append("-i ") arg.Append("-i ")
@@ -503,17 +488,6 @@ namespace MediaBrowser.Controller.MediaEncoding
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode
&& state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
{ {
if (state.VideoStream != null && state.VideoStream.Width.HasValue)
{
// This is hacky but not sure how to get the exact subtitle resolution
int height = Convert.ToInt32(state.VideoStream.Width.Value / 16.0 * 9.0);
arg.Append(" -canvas_size ")
.Append(state.VideoStream.Width.Value.ToString(CultureInfo.InvariantCulture))
.Append(':')
.Append(height.ToString(CultureInfo.InvariantCulture));
}
var subtitlePath = state.SubtitleStream.Path; var subtitlePath = state.SubtitleStream.Path;
if (string.Equals(Path.GetExtension(subtitlePath), ".sub", StringComparison.OrdinalIgnoreCase)) if (string.Equals(Path.GetExtension(subtitlePath), ".sub", StringComparison.OrdinalIgnoreCase))
@@ -1546,9 +1520,12 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
/// <summary> /// <summary>
/// Gets the internal graphical subtitle param. /// Gets the graphical subtitle param.
/// </summary> /// </summary>
public string GetGraphicalSubtitleParam(EncodingJobInfo state, EncodingOptions options, string outputVideoCodec) public string GetGraphicalSubtitleParam(
EncodingJobInfo state,
EncodingOptions options,
string outputVideoCodec)
{ {
var outputSizeParam = string.Empty; var outputSizeParam = string.Empty;
@@ -1562,53 +1539,77 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"'); outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"');
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) var index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase);
{
var index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase);
if (index != -1) if (index != -1)
{ {
outputSizeParam = "," + outputSizeParam.Substring(index); outputSizeParam = "," + outputSizeParam.Substring(index);
} }
}
else else
{ {
var index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = "," + outputSizeParam.Substring(index);
}
else
{
index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = "," + outputSizeParam.Substring(index);
}
else
{
index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase);
if (index != -1) if (index != -1)
{ {
outputSizeParam = "," + outputSizeParam.Substring(index); outputSizeParam = "," + outputSizeParam.Substring(index);
} }
} }
} }
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
&& outputSizeParam.Length == 0)
{
outputSizeParam = ",format=nv12|vaapi,hwupload";
// Add parameters to use VAAPI with burn-in subttiles (GH issue #642)
if (state.SubtitleStream != null
&& state.SubtitleStream.IsTextSubtitleStream
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode) {
outputSizeParam += ",hwmap=mode=read+write+direct";
} }
} }
var videoSizeParam = string.Empty; var videoSizeParam = string.Empty;
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
// Setup subtitle scaling // Setup subtitle scaling
if (state.VideoStream != null && state.VideoStream.Width.HasValue && state.VideoStream.Height.HasValue) if (state.VideoStream != null && state.VideoStream.Width.HasValue && state.VideoStream.Height.HasValue)
{ {
// force_original_aspect_ratio=decrease
// Enable decreasing output video width or height if necessary to keep the original aspect ratio
videoSizeParam = string.Format( videoSizeParam = string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
"scale={0}:{1}", "scale={0}:{1}:force_original_aspect_ratio=decrease",
state.VideoStream.Width.Value, state.VideoStream.Width.Value,
state.VideoStream.Height.Value); state.VideoStream.Height.Value);
//For QSV, feed it into hardware encoder now // For QSV, feed it into hardware encoder now
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
{ {
videoSizeParam += ",hwupload=extra_hw_frames=64"; videoSizeParam += ",hwupload=extra_hw_frames=64";
} }
// For VAAPI and CUVID decoder
// these encoders cannot automatically adjust the size of graphical subtitles to fit the output video,
// thus needs to be manually adjusted.
if ((IsVaapiSupported(state) && string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|| (videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1)
{
var videoStream = state.VideoStream;
var inputWidth = videoStream?.Width;
var inputHeight = videoStream?.Height;
var (width, height) = GetFixedOutputSize(inputWidth, inputHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight);
if (width.HasValue && height.HasValue)
{
videoSizeParam = string.Format(
CultureInfo.InvariantCulture,
"scale={0}:{1}:force_original_aspect_ratio=decrease",
width.Value,
height.Value);
}
}
} }
var mapPrefix = state.SubtitleStream.IsExternal ? var mapPrefix = state.SubtitleStream.IsExternal ?
@@ -1619,12 +1620,35 @@ namespace MediaBrowser.Controller.MediaEncoding
? 0 ? 0
: state.SubtitleStream.Index; : state.SubtitleStream.Index;
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
// Setup default filtergraph utilizing FFMpeg overlay() and FFMpeg scale() (see the return of this function for index reference) // Setup default filtergraph utilizing FFMpeg overlay() and FFMpeg scale() (see the return of this function for index reference)
var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\""; var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\"";
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) // When the input may or may not be hardware VAAPI decodable
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
/*
[base]: HW scaling video to OutputSize
[sub]: SW scaling subtitle to FixedOutputSize
[base][sub]: SW overlay
*/
outputSizeParam = outputSizeParam.TrimStart(',');
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3},hwdownload[base];[base][sub]overlay,format=nv12,hwupload\"";
}
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first
else if (IsVaapiSupported(state) && string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)
&& string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
{
/*
[base]: SW scaling video to OutputSize
[sub]: SW scaling subtitle to FixedOutputSize
[base][sub]: SW overlay
*/
outputSizeParam = outputSizeParam.TrimStart(',');
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3}[base];[base][sub]overlay\"";
}
else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
{ {
/* /*
QSV in FFMpeg can now setup hardware overlay for transcodes. QSV in FFMpeg can now setup hardware overlay for transcodes.
@@ -1688,7 +1712,8 @@ namespace MediaBrowser.Controller.MediaEncoding
return (Convert.ToInt32(outputWidth), Convert.ToInt32(outputHeight)); return (Convert.ToInt32(outputWidth), Convert.ToInt32(outputHeight));
} }
public List<string> GetScalingFilters(int? videoWidth, public List<string> GetScalingFilters(EncodingJobInfo state,
int? videoWidth,
int? videoHeight, int? videoHeight,
Video3DFormat? threedFormat, Video3DFormat? threedFormat,
string videoDecoder, string videoDecoder,
@@ -1707,7 +1732,9 @@ namespace MediaBrowser.Controller.MediaEncoding
requestedMaxWidth, requestedMaxWidth,
requestedMaxHeight); requestedMaxHeight);
if ((string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) || string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase)) var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
if (string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) || (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) && !hasTextSubs)
&& width.HasValue && width.HasValue
&& height.HasValue) && height.HasValue)
{ {
@@ -1737,7 +1764,7 @@ namespace MediaBrowser.Controller.MediaEncoding
filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv)); filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv));
} }
} }
else if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1 else if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1
&& width.HasValue && width.HasValue
&& height.HasValue) && height.HasValue)
{ {
@@ -1941,8 +1968,7 @@ namespace MediaBrowser.Controller.MediaEncoding
public string GetOutputSizeParam( public string GetOutputSizeParam(
EncodingJobInfo state, EncodingJobInfo state,
EncodingOptions options, EncodingOptions options,
string outputVideoCodec, string outputVideoCodec)
bool allowTimeStampCopy = true)
{ {
// http://sonnati.wordpress.com/2012/10/19/ffmpeg-the-swiss-army-knife-of-internet-streaming-part-vi/ // http://sonnati.wordpress.com/2012/10/19/ffmpeg-the-swiss-army-knife-of-internet-streaming-part-vi/
@@ -1951,42 +1977,61 @@ namespace MediaBrowser.Controller.MediaEncoding
var videoStream = state.VideoStream; var videoStream = state.VideoStream;
var filters = new List<string>(); var filters = new List<string>();
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
var hwType = options.HardwareAccelerationType ?? string.Empty; var inputWidth = videoStream?.Width;
if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !options.EnableHardwareEncoding ) var inputHeight = videoStream?.Height;
{ var threeDFormat = state.MediaSource.Video3DFormat;
filters.Add("hwdownload");
// If transcoding from 10 bit, transform colour spaces too var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
if (!string.IsNullOrEmpty(videoStream.PixelFormat)
&& videoStream.PixelFormat.IndexOf("p10", StringComparison.OrdinalIgnoreCase) != -1
&& string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
{
filters.Add("format=p010le");
filters.Add("format=nv12");
}
else
{
filters.Add("format=nv12");
}
}
// When the input may or may not be hardware VAAPI decodable
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{ {
filters.Add("format=nv12|vaapi"); filters.Add("format=nv12|vaapi");
filters.Add("hwupload"); filters.Add("hwupload");
} }
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); // When the input may or may not be hardware QSV decodable
else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
// If we are software decoding, and hardware encoding {
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) if (!hasTextSubs)
&& (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)))
{ {
filters.Add("format=nv12|qsv"); filters.Add("format=nv12|qsv");
filters.Add("hwupload=extra_hw_frames=64"); filters.Add("hwupload=extra_hw_frames=64");
} }
}
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first
else if (IsVaapiSupported(state) && string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)
&& string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
{
var codec = videoStream.Codec.ToLowerInvariant();
var isColorDepth10 = !string.IsNullOrEmpty(videoStream.Profile) && (videoStream.Profile.Contains("Main 10", StringComparison.OrdinalIgnoreCase)
|| videoStream.Profile.Contains("High 10", StringComparison.OrdinalIgnoreCase));
// Assert 10-bit hardware VAAPI decodable
if (isColorDepth10 && (string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase)
|| string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase)
|| string.Equals(codec, "vp9", StringComparison.OrdinalIgnoreCase)))
{
/*
Download data from GPU to CPU as p010le format.
Colorspace conversion is unnecessary here as libx264 will handle it.
If this step is missing, it will fail on AMD but not on intel.
*/
filters.Add("hwdownload");
filters.Add("format=p010le");
}
// Assert 8-bit hardware VAAPI decodable
else if (!isColorDepth10)
{
filters.Add("hwdownload");
filters.Add("format=nv12");
}
}
// Add hardware deinterlace filter before scaling filter
if (state.DeInterlace("h264", true)) if (state.DeInterlace("h264", true))
{ {
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
@@ -1994,13 +2039,19 @@ namespace MediaBrowser.Controller.MediaEncoding
filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_vaapi")); filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_vaapi"));
} }
else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
{
if (!hasTextSubs)
{ {
filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_qsv")); filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_qsv"));
} }
} }
}
if ((state.DeInterlace("h264", true) || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true)) // Add software deinterlace filter before scaling filter
&& !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) if (((state.DeInterlace("h264", true) || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true))
&& !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|| (hasTextSubs && state.DeInterlace("h264", true) && string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)))
{ {
var inputFramerate = videoStream?.RealFrameRate; var inputFramerate = videoStream?.RealFrameRate;
@@ -2015,11 +2066,21 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
} }
var inputWidth = videoStream?.Width; // Add scaling filter: scale_*=format=nv12 or scale_*=w=*:h=*:format=nv12 or scale=expr
var inputHeight = videoStream?.Height; filters.AddRange(GetScalingFilters(state, inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight));
var threeDFormat = state.MediaSource.Video3DFormat;
filters.AddRange(GetScalingFilters(inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight)); // Add parameters to use VAAPI with burn-in text subttiles (GH issue #642)
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
if (state.SubtitleStream != null
&& state.SubtitleStream.IsTextSubtitleStream
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
{
// Test passed on Intel and AMD gfx
filters.Add("hwmap=mode=read+write");
filters.Add("format=nv12");
}
}
var output = string.Empty; var output = string.Empty;
@@ -2037,11 +2098,6 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
filters.Add("hwmap"); filters.Add("hwmap");
} }
if (allowTimeStampCopy)
{
output += " -copyts";
}
} }
if (filters.Count > 0) if (filters.Count > 0)
@@ -2218,7 +2274,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
inputModifier += " " + videoDecoder; inputModifier += " " + videoDecoder;
if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1) if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1)
{ {
var videoStream = state.VideoStream; var videoStream = state.VideoStream;
var inputWidth = videoStream?.Width; var inputWidth = videoStream?.Width;
@@ -2227,7 +2283,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var (width, height) = GetFixedOutputSize(inputWidth, inputHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight); var (width, height) = GetFixedOutputSize(inputWidth, inputHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight);
if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1 if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1
&& width.HasValue && width.HasValue
&& height.HasValue) && height.HasValue)
{ {
@@ -2525,6 +2581,12 @@ namespace MediaBrowser.Controller.MediaEncoding
case "h264": case "h264":
if (_mediaEncoder.SupportsDecoder("h264_cuvid") && encodingOptions.HardwareDecodingCodecs.Contains("h264", StringComparer.OrdinalIgnoreCase)) if (_mediaEncoder.SupportsDecoder("h264_cuvid") && encodingOptions.HardwareDecodingCodecs.Contains("h264", StringComparer.OrdinalIgnoreCase))
{ {
// cuvid decoder does not support 10-bit input
if ((videoStream.BitDepth ?? 8) > 8)
{
encodingOptions.HardwareDecodingCodecs = Array.Empty<string>();
return null;
}
return "-c:v h264_cuvid "; return "-c:v h264_cuvid ";
} }
break; break;
@@ -2772,14 +2834,27 @@ namespace MediaBrowser.Controller.MediaEncoding
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
var hasCopyTs = false; var hasCopyTs = false;
// Add resolution params, if specified // Add resolution params, if specified
if (!hasGraphicalSubs) if (!hasGraphicalSubs)
{ {
var outputSizeParam = GetOutputSizeParam(state, encodingOptions, videoCodec); var outputSizeParam = GetOutputSizeParam(state, encodingOptions, videoCodec);
args += outputSizeParam; args += outputSizeParam;
hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1; hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
} }
// This is for graphical subs
if (hasGraphicalSubs)
{
var graphicalSubtitleParam = GetGraphicalSubtitleParam(state, encodingOptions, videoCodec);
args += graphicalSubtitleParam;
hasCopyTs = graphicalSubtitleParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
}
if (state.RunTimeTicks.HasValue && state.BaseRequest.CopyTimestamps) if (state.RunTimeTicks.HasValue && state.BaseRequest.CopyTimestamps)
{ {
if (!hasCopyTs) if (!hasCopyTs)
@@ -2787,13 +2862,12 @@ namespace MediaBrowser.Controller.MediaEncoding
args += " -copyts"; args += " -copyts";
} }
args += " -avoid_negative_ts disabled -start_at_zero"; args += " -avoid_negative_ts disabled";
}
// This is for internal graphical subs if (!(state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream))
if (hasGraphicalSubs)
{ {
args += GetGraphicalSubtitleParam(state, encodingOptions, videoCodec); args += " -start_at_zero";
}
} }
var qualityParam = GetVideoQualityParam(state, videoCodec, encodingOptions, defaultPreset); var qualityParam = GetVideoQualityParam(state, videoCodec, encodingOptions, defaultPreset);
@@ -2899,6 +2973,5 @@ namespace MediaBrowser.Controller.MediaEncoding
string.Empty, string.Empty,
string.Empty).Trim(); string.Empty).Trim();
} }
} }
} }

View File

@@ -42,6 +42,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
"libvpx", "libvpx",
"libvpx-vp9", "libvpx-vp9",
"aac", "aac",
"libfdk_aac",
"libmp3lame", "libmp3lame",
"libopus", "libopus",
"libvorbis", "libvorbis",

View File

@@ -188,6 +188,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
using (var stream = await GetStream(path, protocol, cancellationToken).ConfigureAwait(false)) using (var stream = await GetStream(path, protocol, cancellationToken).ConfigureAwait(false))
{ {
var result = CharsetDetector.DetectFromStream(stream).Detected; var result = CharsetDetector.DetectFromStream(stream).Detected;
stream.Position = 0;
if (result != null) if (result != null)
{ {
@@ -730,6 +731,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{ {
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName; var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName;
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
if ((path.EndsWith(".ass") || path.EndsWith(".ssa"))
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
{
charset = "";
}
_logger.LogDebug("charset {0} detected for {Path}", charset ?? "null", path); _logger.LogDebug("charset {0} detected for {Path}", charset ?? "null", path);
return charset; return charset;
@@ -745,6 +754,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{ {
Url = path, Url = path,
CancellationToken = cancellationToken, CancellationToken = cancellationToken,
// Needed for seeking
BufferContent = true BufferContent = true
}; };

View File

@@ -26,12 +26,12 @@ namespace MediaBrowser.Model.Dlna
public bool SupportsVideoCodec(string codec) public bool SupportsVideoCodec(string codec)
{ {
return ContainerProfile.ContainsContainer(VideoCodec, codec); return Type == DlnaProfileType.Video && ContainerProfile.ContainsContainer(VideoCodec, codec);
} }
public bool SupportsAudioCodec(string codec) public bool SupportsAudioCodec(string codec)
{ {
return ContainerProfile.ContainsContainer(AudioCodec, codec); return (Type == DlnaProfileType.Audio || Type == DlnaProfileType.Video) && ContainerProfile.ContainsContainer(AudioCodec, codec);
} }
} }
} }

View File

@@ -65,6 +65,7 @@ namespace MediaBrowser.Model.Net
{ ".m3u8", "application/x-mpegURL" }, { ".m3u8", "application/x-mpegURL" },
{ ".mobi", "application/x-mobipocket-ebook" }, { ".mobi", "application/x-mobipocket-ebook" },
{ ".xml", "application/xml" }, { ".xml", "application/xml" },
{ ".wasm", "application/wasm" },
// Type image // Type image
{ ".jpg", "image/jpeg" }, { ".jpg", "image/jpeg" },

View File

@@ -32,7 +32,11 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz
{ {
if (value < Plugin.DefaultRateLimit && _server == Plugin.DefaultServer) if (value < Plugin.DefaultRateLimit && _server == Plugin.DefaultServer)
{ {
RateLimit = Plugin.DefaultRateLimit; _rateLimit = Plugin.DefaultRateLimit;
}
else
{
_rateLimit = value;
} }
} }
} }

View File

@@ -344,7 +344,11 @@ namespace MediaBrowser.Providers.TV.TheTVDB
series.ProductionYear = date.Year; series.ProductionYear = date.Year;
} }
series.RunTimeTicks = TimeSpan.FromMinutes(Convert.ToDouble(tvdbSeries.Runtime)).Ticks; if (!string.IsNullOrEmpty(tvdbSeries.Runtime) && double.TryParse(tvdbSeries.Runtime, out double runtime))
{
series.RunTimeTicks = TimeSpan.FromMinutes(runtime).Ticks;
}
foreach (var genre in tvdbSeries.Genre) foreach (var genre in tvdbSeries.Genre)
{ {
series.AddGenre(genre); series.AddGenre(genre);

View File

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

View File

@@ -1,7 +1,7 @@
--- ---
# We just wrap `build` so this is really it # We just wrap `build` so this is really it
name: "jellyfin" name: "jellyfin"
version: "10.5.0" version: "10.5.4"
packages: packages:
- debian-package-x64 - debian-package-x64
- debian-package-armhf - debian-package-armhf

View File

@@ -17,7 +17,7 @@ RUN yum install -y @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fo
# Install recent NodeJS and Yarn # Install recent NodeJS and Yarn
RUN curl -fSsLo /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo \ RUN curl -fSsLo /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo \
&& rpm -i https://rpm.nodesource.com/pub_8.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm \ && rpm -i https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm \
&& yum install -y yarn && yum install -y yarn
# Install DotNET SDK # Install DotNET SDK

View File

@@ -1,3 +1,27 @@
jellyfin (10.5.4-1) unstable; urgency=medium
* New upstream version 10.5.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.4
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 12 Apr 2020 15:53:47 -0400
jellyfin (10.5.3-1) unstable; urgency=medium
* New upstream version 10.5.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.3
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 05 Apr 2020 12:36:25 -0400
jellyfin (10.5.2-1) unstable; urgency=medium
* New upstream version 10.5.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.2
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 22 Mar 2020 12:06:40 -0400
jellyfin (10.5.1-1) unstable; urgency=medium
* New upstream version 10.5.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.1
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 15 Mar 2020 23:03:59 -0400
jellyfin (10.5.0-1) unstable; urgency=medium jellyfin (10.5.0-1) unstable; urgency=medium
* New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 * New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0

View File

@@ -7,7 +7,7 @@
%endif %endif
Name: jellyfin Name: jellyfin
Version: 10.5.0 Version: 10.5.4
Release: 1%{?dist} Release: 1%{?dist}
Summary: The Free Software Media Browser Summary: The Free Software Media Browser
License: GPLv2 License: GPLv2
@@ -26,13 +26,13 @@ Source16: jellyfin-firewalld.xml
%{?systemd_requires} %{?systemd_requires}
BuildRequires: systemd BuildRequires: systemd
Requires(pre): shadow-utils Requires(pre): shadow-utils
BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel, git
%if 0%{?fedora} %if 0%{?fedora}
BuildRequires: nodejs-yarn BuildRequires: nodejs-yarn, git
%else %else
# Requirements not packaged in main repos # Requirements not packaged in main repos
# From https://rpm.nodesource.com/pub_8.x/el/7/x86_64/ # From https://rpm.nodesource.com/pub_10.x/el/7/x86_64/
BuildRequires: nodejs >= 8 yarn BuildRequires: nodejs >= 10 yarn
%endif %endif
Requires: libcurl, fontconfig, freetype, openssl, glibc libicu Requires: libcurl, fontconfig, freetype, openssl, glibc libicu
# Requirements not packaged in main repos # Requirements not packaged in main repos
@@ -159,6 +159,14 @@ fi
%systemd_postun_with_restart jellyfin.service %systemd_postun_with_restart jellyfin.service
%changelog %changelog
* Sun Apr 12 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.5.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.4
* Sun Apr 05 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.5.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.3
* Sun Mar 22 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.5.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.2
* Sun Mar 15 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.5.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.1
* Fri Oct 11 2019 Jellyfin Packaging Team <packaging@jellyfin.org> * Fri Oct 11 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 - New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0
* Sat Aug 31 2019 Jellyfin Packaging Team <packaging@jellyfin.org> * Sat Aug 31 2019 Jellyfin Packaging Team <packaging@jellyfin.org>

View File

@@ -13,9 +13,7 @@ web_build_dir="$( mktemp -d )"
web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web"
git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/
pushd ${web_build_dir} pushd ${web_build_dir}
if [[ -n ${web_branch} ]]; then git checkout tags/v10.5.3
checkout -b origin/${web_branch}
fi
yarn install yarn install
mkdir -p ${web_target} mkdir -p ${web_target}
mv dist/* ${web_target}/ mv dist/* ${web_target}/

View File

@@ -13,9 +13,7 @@ web_build_dir="$( mktemp -d )"
web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web"
git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/
pushd ${web_build_dir} pushd ${web_build_dir}
if [[ -n ${web_branch} ]]; then git checkout tags/v10.5.3
checkout -b origin/${web_branch}
fi
yarn install yarn install
mkdir -p ${web_target} mkdir -p ${web_target}
mv dist/* ${web_target}/ mv dist/* ${web_target}/

View File

@@ -13,9 +13,7 @@ web_build_dir="$( mktemp -d )"
web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web"
git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/
pushd ${web_build_dir} pushd ${web_build_dir}
if [[ -n ${web_branch} ]]; then git checkout tags/v10.5.3
checkout -b origin/${web_branch}
fi
yarn install yarn install
mkdir -p ${web_target} mkdir -p ${web_target}
mv dist/* ${web_target}/ mv dist/* ${web_target}/

View File

@@ -19,9 +19,7 @@ web_build_dir="$( mktemp -d )"
web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web"
git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/
pushd ${web_build_dir} pushd ${web_build_dir}
if [[ -n ${web_branch} ]]; then git checkout tags/v10.5.3
checkout -b origin/${web_branch}
fi
yarn install yarn install
mkdir -p ${web_target} mkdir -p ${web_target}
mv dist/* ${web_target}/ mv dist/* ${web_target}/

View File

@@ -19,9 +19,7 @@ web_build_dir="$( mktemp -d )"
web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web"
git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/
pushd ${web_build_dir} pushd ${web_build_dir}
if [[ -n ${web_branch} ]]; then git checkout tags/v10.5.3
checkout -b origin/${web_branch}
fi
yarn install yarn install
mkdir -p ${web_target} mkdir -p ${web_target}
mv dist/* ${web_target}/ mv dist/* ${web_target}/