Merge branch 'master' into authenticationdb-efcore
# Conflicts: # Jellyfin.Server.Implementations/Security/AuthorizationContext.cs # MediaBrowser.Controller/Library/IUserManager.cs # MediaBrowser.Controller/Security/IAuthenticationRepository.cs # MediaBrowser.Controller/Session/ISessionManager.cs
This commit is contained in:
commit
45f478f63e
|
@ -7,7 +7,7 @@ parameters:
|
|||
default: "ubuntu-latest"
|
||||
- name: DotNetSdkVersion
|
||||
type: string
|
||||
default: 5.0.103
|
||||
default: 5.0.302
|
||||
|
||||
jobs:
|
||||
- job: CompatibilityCheck
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
parameters:
|
||||
LinuxImage: 'ubuntu-latest'
|
||||
RestoreBuildProjects: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
||||
DotNetSdkVersion: 5.0.103
|
||||
DotNetSdkVersion: 5.0.302
|
||||
|
||||
jobs:
|
||||
- job: Build
|
||||
|
|
|
@ -10,7 +10,7 @@ parameters:
|
|||
default: "tests/**/*Tests.csproj"
|
||||
- name: DotNetSdkVersion
|
||||
type: string
|
||||
default: 5.0.103
|
||||
default: 5.0.302
|
||||
|
||||
jobs:
|
||||
- job: Test
|
||||
|
|
|
@ -6,7 +6,7 @@ variables:
|
|||
- name: RestoreBuildProjects
|
||||
value: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
||||
- name: DotNetSdkVersion
|
||||
value: 5.0.103
|
||||
value: 5.0.302
|
||||
|
||||
pr:
|
||||
autoCancel: true
|
||||
|
|
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -17,6 +17,7 @@ assignees: ''
|
|||
- Browser: [e.g. Firefox 72, Chrome 80, Safari 13]
|
||||
- Jellyfin Version: [e.g. 10.4.3, nightly 20191231]
|
||||
- Playback: [Direct Play, Remux, Direct Stream, Transcode]
|
||||
- Hardware Acceleration: [e.g. none, VAAPI, NVENC, etc.]
|
||||
- Installed Plugins: [e.g. none, Fanart, Anime, etc.]
|
||||
- Reverse Proxy: [e.g. none, nginx, apache, etc.]
|
||||
- Base URL: [e.g. none, yes: /example]
|
||||
|
|
4
.github/stale.yml
vendored
4
.github/stale.yml
vendored
|
@ -23,3 +23,7 @@ markComment: >
|
|||
This bot exists to prevent issues from becoming stale and forgotten. Jellyfin is always moving forward, and bugs are often fixed as side effects of other changes. We therefore ask that bug report authors remain vigilant about their issues to ensure they are closed if fixed, or re-confirmed - perhaps with fresh logs or reproduction examples - regularly. If you have any questions you can reach us on [Matrix or Social Media](https://docs.jellyfin.org/general/getting-help.html).
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
|
||||
# Disable automatic closing of pull requests
|
||||
pulls:
|
||||
daysUntilClose: false
|
||||
|
|
10
.github/workflows/automation.yml
vendored
10
.github/workflows/automation.yml
vendored
|
@ -26,7 +26,7 @@ jobs:
|
|||
if: ${{ github.repository == 'jellyfin/jellyfin' }}
|
||||
steps:
|
||||
- name: Remove from 'Current Release' project
|
||||
uses: alex-page/github-project-automation-plus@v0.7.1
|
||||
uses: alex-page/github-project-automation-plus@v0.8.1
|
||||
if: (github.event.pull_request || github.event.issue.pull_request) && !contains(github.event.*.labels.*.name, 'stable backport')
|
||||
continue-on-error: true
|
||||
with:
|
||||
|
@ -35,7 +35,7 @@ jobs:
|
|||
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
||||
- name: Add to 'Release Next' project
|
||||
uses: alex-page/github-project-automation-plus@v0.7.1
|
||||
uses: alex-page/github-project-automation-plus@v0.8.1
|
||||
if: (github.event.pull_request || github.event.issue.pull_request) && github.event.action == 'opened'
|
||||
continue-on-error: true
|
||||
with:
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
|||
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
||||
- name: Add to 'Current Release' project
|
||||
uses: alex-page/github-project-automation-plus@v0.7.1
|
||||
uses: alex-page/github-project-automation-plus@v0.8.1
|
||||
if: (github.event.pull_request || github.event.issue.pull_request) && !contains(github.event.*.labels.*.name, 'stable backport')
|
||||
continue-on-error: true
|
||||
with:
|
||||
|
@ -58,7 +58,7 @@ jobs:
|
|||
run: echo "::set-output name=number::$(curl -s ${{ github.event.issue.comments_url }} | jq '.[] | select(.author_association == "MEMBER") | .author_association' | wc -l)"
|
||||
|
||||
- name: Move issue to needs triage
|
||||
uses: alex-page/github-project-automation-plus@v0.7.1
|
||||
uses: alex-page/github-project-automation-plus@v0.8.1
|
||||
if: github.event.issue.pull_request == '' && github.event.comment.author_association == 'MEMBER' && steps.member_comments.outputs.number <= 1
|
||||
continue-on-error: true
|
||||
with:
|
||||
|
@ -67,7 +67,7 @@ jobs:
|
|||
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
||||
- name: Add issue to triage project
|
||||
uses: alex-page/github-project-automation-plus@v0.7.1
|
||||
uses: alex-page/github-project-automation-plus@v0.8.1
|
||||
if: github.event.issue.pull_request == '' && github.event.action == 'opened'
|
||||
continue-on-error: true
|
||||
with:
|
||||
|
|
|
@ -212,3 +212,4 @@
|
|||
- [Tim Hobbs](https://github.com/timhobbs)
|
||||
- [SvenVandenbrande](https://github.com/SvenVandenbrande)
|
||||
- [olsh](https://github.com/olsh)
|
||||
- [gnuyent](https://github.com/gnuyent)
|
||||
|
|
14
Directory.Build.props
Normal file
14
Directory.Build.props
Normal file
|
@ -0,0 +1,14 @@
|
|||
<Project>
|
||||
<!-- Sets defaults for all projects in the repo -->
|
||||
|
||||
<PropertyGroup>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)/jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
26
Dockerfile
26
Dockerfile
|
@ -8,15 +8,7 @@ RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-
|
|||
&& npm ci --no-audit --unsafe-perm \
|
||||
&& mv dist /dist
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||
WORKDIR /repo
|
||||
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"
|
||||
|
||||
FROM debian:buster-slim
|
||||
FROM debian:buster-slim as app
|
||||
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND="noninteractive"
|
||||
|
@ -25,9 +17,6 @@ ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
|||
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
||||
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||
|
||||
COPY --from=builder /jellyfin /jellyfin
|
||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||
|
||||
# https://github.com/intel/compute-runtime/releases
|
||||
ARG GMMLIB_VERSION=20.3.2
|
||||
ARG IGC_VERSION=1.0.5435
|
||||
|
@ -73,6 +62,19 @@ ENV LC_ALL en_US.UTF-8
|
|||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||
WORKDIR /repo
|
||||
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"
|
||||
|
||||
FROM app
|
||||
|
||||
COPY --from=builder /jellyfin /jellyfin
|
||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||
|
||||
EXPOSE 8096
|
||||
VOLUME /cache /config /media
|
||||
ENTRYPOINT ["./jellyfin/jellyfin", \
|
||||
|
|
|
@ -13,19 +13,8 @@ RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-
|
|||
&& npm ci --no-audit --unsafe-perm \
|
||||
&& mv dist /dist
|
||||
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||
WORKDIR /repo
|
||||
COPY . .
|
||||
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"
|
||||
|
||||
|
||||
FROM multiarch/qemu-user-static:x86_64-arm as qemu
|
||||
FROM arm32v7/debian:buster-slim
|
||||
FROM arm32v7/debian:buster-slim as app
|
||||
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND="noninteractive"
|
||||
|
@ -61,14 +50,25 @@ RUN apt-get update \
|
|||
&& chmod 777 /cache /config /media \
|
||||
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
|
||||
COPY --from=builder /jellyfin /jellyfin
|
||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||
WORKDIR /repo
|
||||
COPY . .
|
||||
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"
|
||||
|
||||
FROM app
|
||||
|
||||
COPY --from=builder /jellyfin /jellyfin
|
||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||
|
||||
EXPOSE 8096
|
||||
VOLUME /cache /config /media
|
||||
ENTRYPOINT ["./jellyfin/jellyfin", \
|
||||
|
|
|
@ -13,18 +13,8 @@ RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-
|
|||
&& npm ci --no-audit --unsafe-perm \
|
||||
&& mv dist /dist
|
||||
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||
WORKDIR /repo
|
||||
COPY . .
|
||||
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"
|
||||
|
||||
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
|
||||
FROM arm64v8/debian:buster-slim
|
||||
FROM arm64v8/debian:buster-slim as app
|
||||
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND="noninteractive"
|
||||
|
@ -50,14 +40,25 @@ RUN apt-get update && apt-get install --no-install-recommends --no-install-sugge
|
|||
&& chmod 777 /cache /config /media \
|
||||
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
|
||||
COPY --from=builder /jellyfin /jellyfin
|
||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||
WORKDIR /repo
|
||||
COPY . .
|
||||
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"
|
||||
|
||||
FROM app
|
||||
|
||||
COPY --from=builder /jellyfin /jellyfin
|
||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||
|
||||
EXPOSE 8096
|
||||
VOLUME /cache /config /media
|
||||
ENTRYPOINT ["./jellyfin/jellyfin", \
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<AnalysisMode>AllDisabledByDefault</AnalysisMode>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace Emby.Dlna.Configuration
|
||||
|
@ -74,7 +72,7 @@ namespace Emby.Dlna.Configuration
|
|||
/// <summary>
|
||||
/// Gets or sets the default user account that the dlna server uses.
|
||||
/// </summary>
|
||||
public string DefaultUserId { get; set; }
|
||||
public string? DefaultUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether playTo device profiles should be created.
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
@ -140,7 +138,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||
/// </summary>
|
||||
/// <param name="profile">The <see cref="DeviceProfile"/>.</param>
|
||||
/// <returns>The <see cref="User"/>.</returns>
|
||||
private User GetUser(DeviceProfile profile)
|
||||
private User? GetUser(DeviceProfile profile)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(profile.UserId))
|
||||
{
|
||||
|
|
|
@ -288,21 +288,14 @@ namespace Emby.Dlna.ContentDirectory
|
|||
/// <returns>The xml feature list.</returns>
|
||||
private static string WriteFeatureListXml()
|
||||
{
|
||||
// TODO: clean this up
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
builder.Append("<Features xmlns=\"urn:schemas-upnp-org:av:avs\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:schemas-upnp-org:av:avs http://www.upnp.org/schemas/av/avs.xsd\">");
|
||||
|
||||
builder.Append("<Feature name=\"samsung.com_BASICVIEW\" version=\"1\">");
|
||||
builder.Append("<container id=\"I\" type=\"object.item.imageItem\"/>");
|
||||
builder.Append("<container id=\"A\" type=\"object.item.audioItem\"/>");
|
||||
builder.Append("<container id=\"V\" type=\"object.item.videoItem\"/>");
|
||||
builder.Append("</Feature>");
|
||||
|
||||
builder.Append("</Features>");
|
||||
|
||||
return builder.ToString();
|
||||
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
+ "<Features xmlns=\"urn:schemas-upnp-org:av:avs\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:schemas-upnp-org:av:avs http://www.upnp.org/schemas/av/avs.xsd\">"
|
||||
+ "<Feature name=\"samsung.com_BASICVIEW\" version=\"1\">"
|
||||
+ "<container id=\"I\" type=\"object.item.imageItem\"/>"
|
||||
+ "<container id=\"A\" type=\"object.item.audioItem\"/>"
|
||||
+ "<container id=\"V\" type=\"object.item.videoItem\"/>"
|
||||
+ "</Feature>"
|
||||
+ "</Features>";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
@ -8,9 +6,11 @@ namespace Emby.Dlna
|
|||
{
|
||||
public class ControlResponse
|
||||
{
|
||||
public ControlResponse()
|
||||
public ControlResponse(string xml, bool isSuccessful)
|
||||
{
|
||||
Headers = new Dictionary<string, string>();
|
||||
Xml = xml;
|
||||
IsSuccessful = isSuccessful;
|
||||
}
|
||||
|
||||
public IDictionary<string, string> Headers { get; }
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllDisabledByDefault</AnalysisMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Code Analyzers-->
|
||||
|
@ -31,10 +30,6 @@
|
|||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Images\logo120.jpg" />
|
||||
<EmbeddedResource Include="Images\logo120.png" />
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
@ -8,8 +6,10 @@ namespace Emby.Dlna
|
|||
{
|
||||
public class EventSubscriptionResponse
|
||||
{
|
||||
public EventSubscriptionResponse()
|
||||
public EventSubscriptionResponse(string content, string contentType)
|
||||
{
|
||||
Content = content;
|
||||
ContentType = contentType;
|
||||
Headers = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,7 @@ namespace Emby.Dlna.Eventing
|
|||
return GetEventSubscriptionResponse(subscriptionId, requestedTimeoutString, timeoutSeconds);
|
||||
}
|
||||
|
||||
return new EventSubscriptionResponse
|
||||
{
|
||||
Content = string.Empty,
|
||||
ContentType = "text/plain"
|
||||
};
|
||||
return new EventSubscriptionResponse(string.Empty, "text/plain");
|
||||
}
|
||||
|
||||
public EventSubscriptionResponse CreateEventSubscription(string notificationType, string requestedTimeoutString, string callbackUrl)
|
||||
|
@ -103,20 +99,12 @@ namespace Emby.Dlna.Eventing
|
|||
|
||||
_subscriptions.TryRemove(subscriptionId, out _);
|
||||
|
||||
return new EventSubscriptionResponse
|
||||
{
|
||||
Content = string.Empty,
|
||||
ContentType = "text/plain"
|
||||
};
|
||||
return new EventSubscriptionResponse(string.Empty, "text/plain");
|
||||
}
|
||||
|
||||
private EventSubscriptionResponse GetEventSubscriptionResponse(string subscriptionId, string requestedTimeoutString, int timeoutSeconds)
|
||||
{
|
||||
var response = new EventSubscriptionResponse
|
||||
{
|
||||
Content = string.Empty,
|
||||
ContentType = "text/plain"
|
||||
};
|
||||
var response = new EventSubscriptionResponse(string.Empty, "text/plain");
|
||||
|
||||
response.Headers["SID"] = subscriptionId;
|
||||
response.Headers["TIMEOUT"] = string.IsNullOrEmpty(requestedTimeoutString) ? ("SECOND-" + timeoutSeconds.ToString(_usCulture)) : requestedTimeoutString;
|
||||
|
|
|
@ -27,11 +27,9 @@ using MediaBrowser.Controller.TV;
|
|||
using MediaBrowser.Model.Dlna;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using MediaBrowser.Model.Net;
|
||||
using MediaBrowser.Model.System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Rssdp;
|
||||
using Rssdp.Infrastructure;
|
||||
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
|
||||
|
||||
namespace Emby.Dlna.Main
|
||||
{
|
||||
|
@ -204,8 +202,8 @@ namespace Emby.Dlna.Main
|
|||
{
|
||||
if (_communicationsServer == null)
|
||||
{
|
||||
var enableMultiSocketBinding = OperatingSystem.Id == OperatingSystemId.Windows ||
|
||||
OperatingSystem.Id == OperatingSystemId.Linux;
|
||||
var enableMultiSocketBinding = OperatingSystem.IsWindows() ||
|
||||
OperatingSystem.IsLinux();
|
||||
|
||||
_communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger, enableMultiSocketBinding)
|
||||
{
|
||||
|
@ -268,7 +266,12 @@ namespace Emby.Dlna.Main
|
|||
|
||||
try
|
||||
{
|
||||
_publisher = new SsdpDevicePublisher(_communicationsServer, _networkManager, OperatingSystem.Name, Environment.OSVersion.VersionString, _config.GetDlnaConfiguration().SendOnlyMatchedHost)
|
||||
_publisher = new SsdpDevicePublisher(
|
||||
_communicationsServer,
|
||||
_networkManager,
|
||||
MediaBrowser.Common.System.OperatingSystem.Name,
|
||||
Environment.OSVersion.VersionString,
|
||||
_config.GetDlnaConfiguration().SendOnlyMatchedHost)
|
||||
{
|
||||
LogFunction = LogMessage,
|
||||
SupportPnpRootDevice = false
|
||||
|
|
|
@ -1260,10 +1260,7 @@ namespace Emby.Dlna.PlayTo
|
|||
return;
|
||||
}
|
||||
|
||||
PlaybackStart?.Invoke(this, new PlaybackStartEventArgs
|
||||
{
|
||||
MediaInfo = mediaInfo
|
||||
});
|
||||
PlaybackStart?.Invoke(this, new PlaybackStartEventArgs(mediaInfo));
|
||||
}
|
||||
|
||||
private void OnPlaybackProgress(UBaseObject mediaInfo)
|
||||
|
@ -1273,27 +1270,17 @@ namespace Emby.Dlna.PlayTo
|
|||
return;
|
||||
}
|
||||
|
||||
PlaybackProgress?.Invoke(this, new PlaybackProgressEventArgs
|
||||
{
|
||||
MediaInfo = mediaInfo
|
||||
});
|
||||
PlaybackProgress?.Invoke(this, new PlaybackProgressEventArgs(mediaInfo));
|
||||
}
|
||||
|
||||
private void OnPlaybackStop(UBaseObject mediaInfo)
|
||||
{
|
||||
PlaybackStopped?.Invoke(this, new PlaybackStoppedEventArgs
|
||||
{
|
||||
MediaInfo = mediaInfo
|
||||
});
|
||||
PlaybackStopped?.Invoke(this, new PlaybackStoppedEventArgs(mediaInfo));
|
||||
}
|
||||
|
||||
private void OnMediaChanged(UBaseObject old, UBaseObject newMedia)
|
||||
{
|
||||
MediaChanged?.Invoke(this, new MediaChangedEventArgs
|
||||
{
|
||||
OldMediaInfo = old,
|
||||
NewMediaInfo = newMedia
|
||||
});
|
||||
MediaChanged?.Invoke(this, new MediaChangedEventArgs(old, newMedia));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
|
@ -8,6 +6,12 @@ namespace Emby.Dlna.PlayTo
|
|||
{
|
||||
public class MediaChangedEventArgs : EventArgs
|
||||
{
|
||||
public MediaChangedEventArgs(UBaseObject oldMediaInfo, UBaseObject newMediaInfo)
|
||||
{
|
||||
OldMediaInfo = oldMediaInfo;
|
||||
NewMediaInfo = newMediaInfo;
|
||||
}
|
||||
|
||||
public UBaseObject OldMediaInfo { get; set; }
|
||||
|
||||
public UBaseObject NewMediaInfo { get; set; }
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
@ -8,6 +6,11 @@ namespace Emby.Dlna.PlayTo
|
|||
{
|
||||
public class PlaybackProgressEventArgs : EventArgs
|
||||
{
|
||||
public PlaybackProgressEventArgs(UBaseObject mediaInfo)
|
||||
{
|
||||
MediaInfo = mediaInfo;
|
||||
}
|
||||
|
||||
public UBaseObject MediaInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
@ -8,6 +6,11 @@ namespace Emby.Dlna.PlayTo
|
|||
{
|
||||
public class PlaybackStartEventArgs : EventArgs
|
||||
{
|
||||
public PlaybackStartEventArgs(UBaseObject mediaInfo)
|
||||
{
|
||||
MediaInfo = mediaInfo;
|
||||
}
|
||||
|
||||
public UBaseObject MediaInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
@ -8,6 +6,11 @@ namespace Emby.Dlna.PlayTo
|
|||
{
|
||||
public class PlaybackStoppedEventArgs : EventArgs
|
||||
{
|
||||
public PlaybackStoppedEventArgs(UBaseObject mediaInfo)
|
||||
{
|
||||
MediaInfo = mediaInfo;
|
||||
}
|
||||
|
||||
public UBaseObject MediaInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,11 +95,7 @@ namespace Emby.Dlna.Service
|
|||
|
||||
var xml = builder.ToString().Replace("xmlns:m=", "xmlns:u=", StringComparison.Ordinal);
|
||||
|
||||
var controlResponse = new ControlResponse
|
||||
{
|
||||
Xml = xml,
|
||||
IsSuccessful = true
|
||||
};
|
||||
var controlResponse = new ControlResponse(xml, true);
|
||||
|
||||
controlResponse.Headers.Add("EXT", string.Empty);
|
||||
|
||||
|
|
|
@ -46,11 +46,7 @@ namespace Emby.Dlna.Service
|
|||
writer.WriteEndDocument();
|
||||
}
|
||||
|
||||
return new ControlResponse
|
||||
{
|
||||
Xml = builder.ToString(),
|
||||
IsSuccessful = false
|
||||
};
|
||||
return new ControlResponse(builder.ToString(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllDisabledByDefault</AnalysisMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -30,8 +29,4 @@
|
|||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Emby.Naming.AudioBook
|
|||
/// <param name="files">List of files composing the actual audiobook.</param>
|
||||
/// <param name="extras">List of extra files.</param>
|
||||
/// <param name="alternateVersions">Alternative version of files.</param>
|
||||
public AudioBookInfo(string name, int? year, List<AudioBookFileInfo> files, List<AudioBookFileInfo> extras, List<AudioBookFileInfo> alternateVersions)
|
||||
public AudioBookInfo(string name, int? year, IReadOnlyList<AudioBookFileInfo> files, IReadOnlyList<AudioBookFileInfo> extras, IReadOnlyList<AudioBookFileInfo> alternateVersions)
|
||||
{
|
||||
Name = name;
|
||||
Year = year;
|
||||
|
@ -39,18 +39,18 @@ namespace Emby.Naming.AudioBook
|
|||
/// Gets or sets the files.
|
||||
/// </summary>
|
||||
/// <value>The files.</value>
|
||||
public List<AudioBookFileInfo> Files { get; set; }
|
||||
public IReadOnlyList<AudioBookFileInfo> Files { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the extras.
|
||||
/// </summary>
|
||||
/// <value>The extras.</value>
|
||||
public List<AudioBookFileInfo> Extras { get; set; }
|
||||
public IReadOnlyList<AudioBookFileInfo> Extras { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the alternate versions.
|
||||
/// </summary>
|
||||
/// <value>The alternate versions.</value>
|
||||
public List<AudioBookFileInfo> AlternateVersions { get; set; }
|
||||
public IReadOnlyList<AudioBookFileInfo> AlternateVersions { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace Emby.Naming.AudioBook
|
|||
foreach (var audioFile in group)
|
||||
{
|
||||
var name = Path.GetFileNameWithoutExtension(audioFile.Path);
|
||||
if (name.Equals("audiobook") ||
|
||||
if (name.Equals("audiobook", StringComparison.OrdinalIgnoreCase) ||
|
||||
name.Contains(nameParserResult.Name, StringComparison.OrdinalIgnoreCase) ||
|
||||
name.Contains(nameWithReplacedDots, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace Emby.Naming.Common
|
|||
|
||||
CleanStrings = new[]
|
||||
{
|
||||
@"[ _\,\.\(\)\[\]\-](3d|sbs|tab|hsbs|htab|mvc|HDR|HDC|UHD|UltraHD|4k|ac3|dts|custom|dc|divx|divx5|dsr|dsrip|dutch|dvd|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|cd[1-9]|r3|r5|bd5|bd|se|svcd|swedish|german|read.nfo|nfofix|unrated|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|2160p|hrhd|hrhdtv|hddvd|bluray|blu-ray|x264|x265|h264|xvid|xvidvd|xxx|www.www|AAC|DTS|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
|
||||
@"[ _\,\.\(\)\[\]\-](3d|sbs|tab|hsbs|htab|mvc|HDR|HDC|UHD|UltraHD|4k|ac3|dts|custom|dc|divx|divx5|dsr|dsrip|dutch|dvd|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|cd[1-9]|r3|r5|bd5|bd|se|svcd|swedish|german|read.nfo|nfofix|unrated|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|2160p|hrhd|hrhdtv|hddvd|bluray|blu-ray|x264|x265|h264|h265|xvid|xvidvd|xxx|www.www|AAC|DTS|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
|
||||
@"(\[.*\])"
|
||||
};
|
||||
|
||||
|
@ -277,14 +277,14 @@ namespace Emby.Naming.Common
|
|||
IsNamed = true
|
||||
},
|
||||
|
||||
new EpisodeExpression("[\\\\/\\._ \\[\\(-]([0-9]+)x([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$")
|
||||
new EpisodeExpression(@"[\\\/\._ \[\(-]([0-9]+)x([0-9]+(?:(?:[a-i]|\.[1-9])(?![0-9]))?)([^\\\/]*)$")
|
||||
{
|
||||
SupportsAbsoluteEpisodeNumbers = true
|
||||
},
|
||||
|
||||
// Not a Kodi rule as well, but below rule also causes false positives for triple-digit episode names
|
||||
// [bar] Foo - 1 [baz] special case of below expression to prevent false positives with digits in the series name
|
||||
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[\s_]*-[\s_]*(?<epnumber>[0-9]+).*$")
|
||||
new EpisodeExpression(@".*[\\\/]?.*?(\[.*?\])+.*?(?<seriesname>[-\w\s]+?)[\s_]*-[\s_]*(?<epnumber>[0-9]+).*$")
|
||||
{
|
||||
IsNamed = true
|
||||
},
|
||||
|
@ -305,6 +305,12 @@ namespace Emby.Naming.Common
|
|||
|
||||
// *** End Kodi Standard Naming
|
||||
|
||||
// "Episode 16", "Episode 16 - Title"
|
||||
new EpisodeExpression(@"[Ee]pisode (?<epnumber>[0-9]+)(-(?<endingepnumber>[0-9]+))?[^\\\/]*$")
|
||||
{
|
||||
IsNamed = true
|
||||
},
|
||||
|
||||
new EpisodeExpression(@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]+)[xX](?<epnumber>[0-9]+)[^\\\/]*$")
|
||||
{
|
||||
IsNamed = true
|
||||
|
@ -362,12 +368,6 @@ namespace Emby.Naming.Common
|
|||
IsOptimistic = true,
|
||||
IsNamed = true
|
||||
},
|
||||
// "Episode 16", "Episode 16 - Title"
|
||||
new EpisodeExpression(@".*[\\\/][^\\\/]* (?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*[^\\\/]*$")
|
||||
{
|
||||
IsOptimistic = true,
|
||||
IsNamed = true
|
||||
}
|
||||
};
|
||||
|
||||
EpisodeWithoutSeasonExpressions = new[]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
|
||||
<PropertyGroup>
|
||||
|
@ -9,12 +9,11 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllDisabledByDefault</AnalysisMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Stability)'=='Unstable'">
|
||||
|
@ -50,8 +49,4 @@
|
|||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Emby.Naming.Audio;
|
||||
using Emby.Naming.Common;
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Emby.Naming.Video
|
|||
/// <param name="namingOptions">The naming options.</param>
|
||||
/// <param name="supportMultiVersion">Indication we should consider multi-versions of content.</param>
|
||||
/// <returns>Returns enumerable of <see cref="VideoInfo"/> which groups files together when related.</returns>
|
||||
public static IEnumerable<VideoInfo> Resolve(List<FileSystemMetadata> files, NamingOptions namingOptions, bool supportMultiVersion = true)
|
||||
public static IEnumerable<VideoInfo> Resolve(IEnumerable<FileSystemMetadata> files, NamingOptions namingOptions, bool supportMultiVersion = true)
|
||||
{
|
||||
var videoInfos = files
|
||||
.Select(i => VideoResolver.Resolve(i.FullName, i.IsDirectory, namingOptions))
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -77,7 +77,6 @@ namespace Emby.Notifications
|
|||
{
|
||||
_libraryManager.ItemAdded += OnLibraryManagerItemAdded;
|
||||
_appHost.HasPendingRestartChanged += OnAppHostHasPendingRestartChanged;
|
||||
_appHost.HasUpdateAvailableChanged += OnAppHostHasUpdateAvailableChanged;
|
||||
_activityManager.EntryCreated += OnActivityManagerEntryCreated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
@ -132,25 +131,6 @@ namespace Emby.Notifications
|
|||
return _config.GetConfiguration<NotificationOptions>("notifications");
|
||||
}
|
||||
|
||||
private async void OnAppHostHasUpdateAvailableChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (!_appHost.HasUpdateAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var type = NotificationType.ApplicationUpdateAvailable.ToString();
|
||||
|
||||
var notification = new NotificationRequest
|
||||
{
|
||||
Description = "Please see jellyfin.org for details.",
|
||||
NotificationType = type,
|
||||
Name = _localization.GetLocalizedString("NewVersionIsAvailable")
|
||||
};
|
||||
|
||||
await SendNotification(notification, null).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void OnLibraryManagerItemAdded(object? sender, ItemChangeEventArgs e)
|
||||
{
|
||||
if (!FilterItem(e.Item))
|
||||
|
@ -325,7 +305,6 @@ namespace Emby.Notifications
|
|||
|
||||
_libraryManager.ItemAdded -= OnLibraryManagerItemAdded;
|
||||
_appHost.HasPendingRestartChanged -= OnAppHostHasPendingRestartChanged;
|
||||
_appHost.HasUpdateAvailableChanged -= OnAppHostHasUpdateAvailableChanged;
|
||||
_activityManager.EntryCreated -= OnActivityManagerEntryCreated;
|
||||
|
||||
_disposed = true;
|
||||
|
|
|
@ -22,10 +22,6 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Code Analyzers-->
|
||||
|
|
|
@ -100,7 +100,6 @@ using Microsoft.Extensions.Configuration;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Prometheus.DotNetRuntime;
|
||||
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
|
||||
using WebSocketManager = Emby.Server.Implementations.HttpServer.WebSocketManager;
|
||||
|
||||
namespace Emby.Server.Implementations
|
||||
|
@ -147,13 +146,7 @@ namespace Emby.Server.Implementations
|
|||
return false;
|
||||
}
|
||||
|
||||
if (OperatingSystem.Id == OperatingSystemId.Windows
|
||||
|| OperatingSystem.Id == OperatingSystemId.Darwin)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return OperatingSystem.IsWindows() || OperatingSystem.IsMacOS();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -711,7 +704,7 @@ namespace Emby.Server.Implementations
|
|||
|
||||
logger.LogInformation("Environment Variables: {EnvVars}", relevantEnvVars);
|
||||
logger.LogInformation("Arguments: {Args}", commandLineArgs);
|
||||
logger.LogInformation("Operating system: {OS}", OperatingSystem.Name);
|
||||
logger.LogInformation("Operating system: {OS}", MediaBrowser.Common.System.OperatingSystem.Name);
|
||||
logger.LogInformation("Architecture: {Architecture}", RuntimeInformation.OSArchitecture);
|
||||
logger.LogInformation("64-Bit Process: {Is64Bit}", Environment.Is64BitProcess);
|
||||
logger.LogInformation("User Interactive: {IsUserInteractive}", Environment.UserInteractive);
|
||||
|
@ -1088,11 +1081,10 @@ namespace Emby.Server.Implementations
|
|||
ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
|
||||
InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
|
||||
CachePath = ApplicationPaths.CachePath,
|
||||
OperatingSystem = OperatingSystem.Id.ToString(),
|
||||
OperatingSystemDisplayName = OperatingSystem.Name,
|
||||
OperatingSystem = MediaBrowser.Common.System.OperatingSystem.Id.ToString(),
|
||||
OperatingSystemDisplayName = MediaBrowser.Common.System.OperatingSystem.Name,
|
||||
CanSelfRestart = CanSelfRestart,
|
||||
CanLaunchWebBrowser = CanLaunchWebBrowser,
|
||||
HasUpdateAvailable = HasUpdateAvailable,
|
||||
TranscodingTempPath = ConfigurationManager.GetTranscodePath(),
|
||||
ServerName = FriendlyName,
|
||||
LocalAddress = GetSmartApiUrl(source),
|
||||
|
@ -1108,16 +1100,16 @@ namespace Emby.Server.Implementations
|
|||
.Select(i => new WakeOnLanInfo(i))
|
||||
.ToList();
|
||||
|
||||
public PublicSystemInfo GetPublicSystemInfo(IPAddress source)
|
||||
public PublicSystemInfo GetPublicSystemInfo(IPAddress address)
|
||||
{
|
||||
return new PublicSystemInfo
|
||||
{
|
||||
Version = ApplicationVersionString,
|
||||
ProductName = ApplicationProductName,
|
||||
Id = SystemId,
|
||||
OperatingSystem = OperatingSystem.Id.ToString(),
|
||||
OperatingSystem = MediaBrowser.Common.System.OperatingSystem.Id.ToString(),
|
||||
ServerName = FriendlyName,
|
||||
LocalAddress = GetSmartApiUrl(source),
|
||||
LocalAddress = GetSmartApiUrl(address),
|
||||
StartupWizardCompleted = ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted
|
||||
};
|
||||
}
|
||||
|
@ -1126,7 +1118,7 @@ namespace Emby.Server.Implementations
|
|||
public bool ListenWithHttps => Certificate != null && ConfigurationManager.GetNetworkConfiguration().EnableHttps;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetSmartApiUrl(IPAddress ipAddress, int? port = null)
|
||||
public string GetSmartApiUrl(IPAddress remoteAddr, int? port = null)
|
||||
{
|
||||
// Published server ends with a /
|
||||
if (!string.IsNullOrEmpty(PublishedServerUrl))
|
||||
|
@ -1135,7 +1127,7 @@ namespace Emby.Server.Implementations
|
|||
return PublishedServerUrl.Trim('/');
|
||||
}
|
||||
|
||||
string smart = NetManager.GetBindInterface(ipAddress, out port);
|
||||
string smart = NetManager.GetBindInterface(remoteAddr, out port);
|
||||
// If the smartAPI doesn't start with http then treat it as a host or ip.
|
||||
if (smart.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
@ -1198,14 +1190,14 @@ namespace Emby.Server.Implementations
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetLocalApiUrl(string host, string scheme = null, int? port = null)
|
||||
public string GetLocalApiUrl(string hostname, string scheme = null, int? port = null)
|
||||
{
|
||||
// NOTE: If no BaseUrl is set then UriBuilder appends a trailing slash, but if there is no BaseUrl it does
|
||||
// not. For consistency, always trim the trailing slash.
|
||||
return new UriBuilder
|
||||
{
|
||||
Scheme = scheme ?? (ListenWithHttps ? Uri.UriSchemeHttps : Uri.UriSchemeHttp),
|
||||
Host = host,
|
||||
Host = hostname,
|
||||
Port = port ?? (ListenWithHttps ? HttpsPort : HttpPort),
|
||||
Path = ConfigurationManager.GetNetworkConfiguration().BaseUrl
|
||||
}.ToString().TrimEnd('/');
|
||||
|
@ -1242,26 +1234,6 @@ namespace Emby.Server.Implementations
|
|||
|
||||
protected abstract void ShutdownInternal();
|
||||
|
||||
public event EventHandler HasUpdateAvailableChanged;
|
||||
|
||||
private bool _hasUpdateAvailable;
|
||||
|
||||
public bool HasUpdateAvailable
|
||||
{
|
||||
get => _hasUpdateAvailable;
|
||||
set
|
||||
{
|
||||
var fireEvent = value && !_hasUpdateAvailable;
|
||||
|
||||
_hasUpdateAvailable = value;
|
||||
|
||||
if (fireEvent)
|
||||
{
|
||||
HasUpdateAvailableChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Assembly> GetApiPluginAssemblies()
|
||||
{
|
||||
var assemblies = _allConcreteTypes
|
||||
|
|
|
@ -82,12 +82,10 @@ namespace Emby.Server.Implementations.Collections
|
|||
|
||||
internal async Task<Folder> EnsureLibraryFolder(string path, bool createIfNeeded)
|
||||
{
|
||||
var existingFolders = FindFolders(path)
|
||||
.ToList();
|
||||
|
||||
if (existingFolders.Count > 0)
|
||||
var existingFolder = FindFolders(path).FirstOrDefault();
|
||||
if (existingFolder != null)
|
||||
{
|
||||
return existingFolders[0];
|
||||
return existingFolder;
|
||||
}
|
||||
|
||||
if (!createIfNeeded)
|
||||
|
@ -164,7 +162,7 @@ namespace Emby.Server.Implementations.Collections
|
|||
DateCreated = DateTime.UtcNow
|
||||
};
|
||||
|
||||
parentFolder.AddChild(collection, CancellationToken.None);
|
||||
parentFolder.AddChild(collection);
|
||||
|
||||
if (options.ItemIdList.Count > 0)
|
||||
{
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.XmlTv" Version="10.6.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.8" />
|
||||
<PackageReference Include="Mono.Nat" Version="3.0.1" />
|
||||
<PackageReference Include="prometheus-net.DotNetRuntime" Version="4.1.0" />
|
||||
<PackageReference Include="sharpcompress" Version="0.28.3" />
|
||||
|
@ -44,12 +44,13 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release'">true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<!-- https://github.com/microsoft/ApplicationInsights-dotnet/issues/2047 -->
|
||||
<NoWarn>AD0001</NoWarn>
|
||||
<AnalysisMode Condition=" '$(Configuration)' == 'Debug' ">AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release'">
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Code Analyzers-->
|
||||
|
|
|
@ -11,7 +11,6 @@ using MediaBrowser.Common.Configuration;
|
|||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
|
||||
|
||||
namespace Emby.Server.Implementations.IO
|
||||
{
|
||||
|
@ -24,7 +23,7 @@ namespace Emby.Server.Implementations.IO
|
|||
|
||||
private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>();
|
||||
private readonly string _tempPath;
|
||||
private static readonly bool _isEnvironmentCaseInsensitive = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
private static readonly bool _isEnvironmentCaseInsensitive = OperatingSystem.IsWindows();
|
||||
|
||||
public ManagedFileSystem(
|
||||
ILogger<ManagedFileSystem> logger,
|
||||
|
@ -402,7 +401,7 @@ namespace Emby.Server.Implementations.IO
|
|||
|
||||
public virtual void SetHidden(string path, bool isHidden)
|
||||
{
|
||||
if (OperatingSystem.Id != OperatingSystemId.Windows)
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -426,7 +425,7 @@ namespace Emby.Server.Implementations.IO
|
|||
|
||||
public virtual void SetAttributes(string path, bool isHidden, bool isReadOnly)
|
||||
{
|
||||
if (OperatingSystem.Id != OperatingSystemId.Windows)
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2540,9 +2540,10 @@ namespace Emby.Server.Implementations.Library
|
|||
{
|
||||
episodeInfo = resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming);
|
||||
// Resolve from parent folder if it's not the Season folder
|
||||
if (episodeInfo == null && episode.Parent.GetType() == typeof(Folder))
|
||||
var parent = episode.GetParent();
|
||||
if (episodeInfo == null && parent.GetType() == typeof(Folder))
|
||||
{
|
||||
episodeInfo = resolver.Resolve(episode.Parent.Path, true, null, null, isAbsoluteNaming);
|
||||
episodeInfo = resolver.Resolve(parent.Path, true, null, null, isAbsoluteNaming);
|
||||
if (episodeInfo != null)
|
||||
{
|
||||
// add the container
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "حذف سجل الأنشطة",
|
||||
"Default": "الإعدادات الافتراضية",
|
||||
"Undefined": "غير معرف",
|
||||
"Forced": "ملحقة"
|
||||
"Forced": "ملحقة",
|
||||
"TaskOptimizeDatabaseDescription": "يضغط قاعدة البيانات ويقتطع المساحة الحرة. تشغيل هذه المهمة بعد فحص المكتبة أو إجراء تغييرات أخرى تشير ضمنًا إلى أن تعديلات قاعدة البيانات قد تؤدي إلى تحسين الأداء.",
|
||||
"TaskOptimizeDatabase": "تحسين قاعدة البيانات"
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"CameraImageUploadedFrom": "Нова снимка от камера беше качена от {0}",
|
||||
"Channels": "Канали",
|
||||
"ChapterNameValue": "Глава {0}",
|
||||
"Collections": "Поредици",
|
||||
"Collections": "Колекции",
|
||||
"DeviceOfflineWithName": "{0} се разкачи",
|
||||
"DeviceOnlineWithName": "{0} е свързан",
|
||||
"FailedLoginAttemptWithUserName": "Неуспешен опит за влизане от {0}",
|
||||
|
@ -29,13 +29,13 @@
|
|||
"Inherit": "Наследяване",
|
||||
"ItemAddedWithName": "{0} е добавено към библиотеката",
|
||||
"ItemRemovedWithName": "{0} е премахнато от библиотеката",
|
||||
"LabelIpAddressValue": "ИП адрес: {0}",
|
||||
"LabelRunningTimeValue": "Стартирано от: {0}",
|
||||
"LabelIpAddressValue": "IP адрес: {0}",
|
||||
"LabelRunningTimeValue": "Продължителност: {0}",
|
||||
"Latest": "Последни",
|
||||
"MessageApplicationUpdated": "Сървърът е обновен",
|
||||
"MessageApplicationUpdatedTo": "Сървърът е обновен до {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Секцията {0} от сървърната конфигурация се актуализира",
|
||||
"MessageServerConfigurationUpdated": "Конфигурацията на сървъра се актуализира",
|
||||
"MessageApplicationUpdated": "Сървърът беше обновен",
|
||||
"MessageApplicationUpdatedTo": "Сървърът беше обновен до {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Секцията {0} от сървърната конфигурация беше актуализирана",
|
||||
"MessageServerConfigurationUpdated": "Конфигурацията на сървъра беше актуализирана",
|
||||
"MixedContent": "Смесено съдържание",
|
||||
"Movies": "Филми",
|
||||
"Music": "Музика",
|
||||
|
@ -118,5 +118,7 @@
|
|||
"Forced": "Принудително",
|
||||
"Default": "По подразбиране",
|
||||
"TaskCleanActivityLogDescription": "Изтрива записите в дневника с активност по стари от конфигурираната възраст.",
|
||||
"TaskCleanActivityLog": "Изчисти дневника с активност"
|
||||
"TaskCleanActivityLog": "Изчисти дневника с активност",
|
||||
"TaskOptimizeDatabaseDescription": "Прави базата данни по-компактна и освобождава място. Пускането на тази задача след сканиране на библиотеката или правене на други промени, свързани с модификации на базата данни, може да подобри производителността.",
|
||||
"TaskOptimizeDatabase": "Оптимизирай базата данни"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Buidar Registre d'Activitat",
|
||||
"Undefined": "Indefinit",
|
||||
"Forced": "Forçat",
|
||||
"Default": "Defecto"
|
||||
"Default": "Defecto",
|
||||
"TaskOptimizeDatabaseDescription": "Compacta la base de dades i trunca l'espai lliure. Executar aquesta tasca després d’escanejar la biblioteca o fer altres canvis que impliquin modificacions a la base de dades pot millorar el rendiment.",
|
||||
"TaskOptimizeDatabase": "Optimitzar la base de dades"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Smazat záznam aktivity",
|
||||
"Undefined": "Nedefinované",
|
||||
"Forced": "Vynucené",
|
||||
"Default": "Výchozí"
|
||||
"Default": "Výchozí",
|
||||
"TaskOptimizeDatabaseDescription": "Zmenší databázi a odstraní prázdné místo. Spuštění této úlohy po skenování knihovny či jiných změnách databáze může zlepšit výkon.",
|
||||
"TaskOptimizeDatabase": "Optimalizovat databázi"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Ryd Aktivitetslog",
|
||||
"Undefined": "Udefineret",
|
||||
"Forced": "Tvunget",
|
||||
"Default": "Standard"
|
||||
"Default": "Standard",
|
||||
"TaskOptimizeDatabaseDescription": "Kompakter database og forkorter fri plads. Ved at køre denne proces efter at scanne biblioteket eller efter at ændre noget som kunne have indflydelse på databasen, kan forbedre ydeevne.",
|
||||
"TaskOptimizeDatabase": "Optimér database"
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"AppDeviceValues": "App: {0}, Gerät: {1}",
|
||||
"Application": "Anwendung",
|
||||
"Artists": "Interpreten",
|
||||
"AuthenticationSucceededWithUserName": "{0} wurde angemeldet",
|
||||
"AuthenticationSucceededWithUserName": "{0} erfolgreich authentifiziert",
|
||||
"Books": "Bücher",
|
||||
"CameraImageUploadedFrom": "Ein neues Kamerafoto wurde von {0} hochgeladen",
|
||||
"Channels": "Kanäle",
|
||||
|
@ -16,7 +16,7 @@
|
|||
"Folders": "Verzeichnisse",
|
||||
"Genres": "Genres",
|
||||
"HeaderAlbumArtists": "Album-Interpreten",
|
||||
"HeaderContinueWatching": "Fortsetzen",
|
||||
"HeaderContinueWatching": "Weiterschauen",
|
||||
"HeaderFavoriteAlbums": "Lieblingsalben",
|
||||
"HeaderFavoriteArtists": "Lieblings-Interpreten",
|
||||
"HeaderFavoriteEpisodes": "Lieblingsepisoden",
|
||||
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Aktivitätsprotokoll aufräumen",
|
||||
"Undefined": "Undefiniert",
|
||||
"Forced": "Erzwungen",
|
||||
"Default": "Standard"
|
||||
"Default": "Standard",
|
||||
"TaskOptimizeDatabaseDescription": "Komprimiert die Datenbank und trimmt den freien Speicherplatz. Die Ausführung dieser Aufgabe nach dem Scannen der Bibliothek oder nach anderen Änderungen, die Datenbankänderungen implizieren, kann die Leistung verbessern.",
|
||||
"TaskOptimizeDatabase": "Datenbank optimieren"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Clean Activity Log",
|
||||
"Undefined": "Undefined",
|
||||
"Forced": "Forced",
|
||||
"Default": "Default"
|
||||
"Default": "Default",
|
||||
"TaskOptimizeDatabaseDescription": "Compacts database and truncates free space. Running this task after scanning the library or doing other changes that imply database modifications might improve performance.",
|
||||
"TaskOptimizeDatabase": "Optimise database"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Borrar log de actividades",
|
||||
"Undefined": "Indefinido",
|
||||
"Forced": "Forzado",
|
||||
"Default": "Por Defecto"
|
||||
"Default": "Por Defecto",
|
||||
"TaskOptimizeDatabaseDescription": "Compacta la base de datos y restaura el espacio libre. Ejecutar esta tarea después de actualizar las librerías o realizar otros cambios que impliquen modificar las bases de datos puede mejorar la performance.",
|
||||
"TaskOptimizeDatabase": "Optimización de base de datos"
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"ScheduledTaskFailedWithName": "{0} falló",
|
||||
"ScheduledTaskStartedWithName": "{0} iniciada",
|
||||
"ServerNameNeedsToBeRestarted": "{0} necesita ser reiniciado",
|
||||
"Shows": "Series de Televisión",
|
||||
"Shows": "Series",
|
||||
"Songs": "Canciones",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server se está cargando. Vuelve a intentarlo en breve.",
|
||||
"SubtitleDownloadFailureForItem": "Error al descargar subtítulos para {0}",
|
||||
|
|
|
@ -117,5 +117,7 @@
|
|||
"TaskCleanActivityLog": "Limpiar Registro de Actividades",
|
||||
"Undefined": "Sin definir",
|
||||
"Forced": "Forzado",
|
||||
"Default": "Por Defecto"
|
||||
"Default": "Por Defecto",
|
||||
"TaskOptimizeDatabaseDescription": "Compacta la base de datos y restaura el espacio libre. Ejecutar esta tarea después de actualizar las librerías o realizar otros cambios que impliquen modificar las bases de datos puede mejorar la performance.",
|
||||
"TaskOptimizeDatabase": "Optimización de base de datos"
|
||||
}
|
||||
|
|
|
@ -117,5 +117,7 @@
|
|||
"Default": "Oletus",
|
||||
"TaskCleanActivityLogDescription": "Poistaa määritettyä ikää vanhemmat tapahtumat toimintahistoriasta.",
|
||||
"TaskCleanActivityLog": "Tyhjennä toimintahistoria",
|
||||
"Undefined": "Määrittelemätön"
|
||||
"Undefined": "Määrittelemätön",
|
||||
"TaskOptimizeDatabaseDescription": "Tiivistää ja puhdistaa tietokannan. Tämän toiminnon suorittaminen kirjastojen skannauksen tai muiden tietokantaan liittyvien muutoksien jälkeen voi parantaa suorituskykyä.",
|
||||
"TaskOptimizeDatabase": "Optimoi tietokanta"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Nettoyer le journal d'activité",
|
||||
"Undefined": "Non défini",
|
||||
"Forced": "Forcé",
|
||||
"Default": "Par défaut"
|
||||
"Default": "Par défaut",
|
||||
"TaskOptimizeDatabaseDescription": "Réduit les espaces vides/inutiles et compacte la base de données. Utiliser cette fonction après une mise à jour de la bibliothèque ou toute autre modification de la base de données peut améliorer les performances du serveur.",
|
||||
"TaskOptimizeDatabase": "Optimiser la base de données"
|
||||
}
|
||||
|
|
|
@ -88,5 +88,34 @@
|
|||
"NotificationOptionVideoPlaybackStopped": "Reproducción de vídeo parada",
|
||||
"NotificationOptionVideoPlayback": "Reproducción de vídeo iniciada",
|
||||
"NotificationOptionUserLockedOut": "Usuario bloqueado",
|
||||
"NotificationOptionTaskFailed": "Falla na tarefa axendada"
|
||||
"NotificationOptionTaskFailed": "Falla na tarefa axendada",
|
||||
"TaskCleanTranscodeDescription": "Borra os arquivos de transcode anteriores a un día.",
|
||||
"TaskCleanTranscode": "Limpar Directorio de Transcode",
|
||||
"UserStoppedPlayingItemWithValues": "{0} rematou de reproducir {1} en {2}",
|
||||
"UserStartedPlayingItemWithValues": "{0} está reproducindo {1} en {2}",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Busca en internet por subtítulos que faltan baseado na configuración de metadatos.",
|
||||
"TaskDownloadMissingSubtitles": "Descargar subtítulos que faltan",
|
||||
"TaskRefreshChannelsDescription": "Refresca a información do canle de internet.",
|
||||
"TaskRefreshChannels": "Refrescar Canles",
|
||||
"TaskUpdatePluginsDescription": "Descarga e instala actualizacións para plugins que están configurados para actualizarse automáticamente.",
|
||||
"TaskRefreshPeopleDescription": "Actualiza os metadatos dos actores e directores na túa libraría multimedia.",
|
||||
"TaskRefreshPeople": "Refrescar Persoas",
|
||||
"TaskCleanLogsDescription": "Borra arquivos de rexistro que son mais antigos que {0} días.",
|
||||
"TaskRefreshLibraryDescription": "Escanea a tua libraría multimedia buscando novos arquivos e refrescando os metadatos.",
|
||||
"TaskRefreshLibrary": "Escanear Libraría Multimedia",
|
||||
"TaskRefreshChapterImagesDescription": "Crea previsualizacións para videos que teñen capítulos.",
|
||||
"TaskRefreshChapterImages": "Extraer Imaxes dos Capítulos",
|
||||
"TaskCleanCacheDescription": "Borra ficheiros da caché que xa non son necesarios para o sistema.",
|
||||
"TaskCleanCache": "Limpa Directorio de Caché",
|
||||
"TaskCleanActivityLogDescription": "Borra as entradas no rexistro de actividade anteriores á data configurada.",
|
||||
"TasksApplicationCategory": "Aplicación",
|
||||
"ValueSpecialEpisodeName": "Especial - {0}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} foi engadido a túa libraría multimedia",
|
||||
"TasksLibraryCategory": "Libraría",
|
||||
"TasksMaintenanceCategory": "Mantemento",
|
||||
"VersionNumber": "Versión {0}",
|
||||
"UserPolicyUpdatedWithName": "A política de usuario foi actualizada para {0}",
|
||||
"UserPasswordChangedWithName": "Cambiouse o contrasinal para o usuario {0}",
|
||||
"UserOnlineFromDevice": "{0} está en liña desde {1}",
|
||||
"UserOfflineFromDevice": "{0} desconectouse desde {1}"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Tevékenységnapló törlése",
|
||||
"Undefined": "Meghatározatlan",
|
||||
"Forced": "Kényszerített",
|
||||
"Default": "Alapértelmezett"
|
||||
"Default": "Alapértelmezett",
|
||||
"TaskOptimizeDatabaseDescription": "Tömöríti az adatbázist és csonkolja a szabad helyet. A feladat futtatása a könyvtár beolvasása után, vagy egyéb, adatbázis-módosítást igénylő változtatások végrehajtása javíthatja a teljesítményt.",
|
||||
"TaskOptimizeDatabase": "Adatbázis optimalizálása"
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"ScheduledTaskFailedWithName": "{0} fallito",
|
||||
"ScheduledTaskStartedWithName": "{0} avviati",
|
||||
"ServerNameNeedsToBeRestarted": "{0} deve essere riavviato",
|
||||
"Shows": "Programmi",
|
||||
"Shows": "Serie TV",
|
||||
"Songs": "Canzoni",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin server si sta avviando. Per favore riprova più tardi.",
|
||||
"SubtitleDownloadFailureForItem": "Impossibile scaricare i sottotitoli per {0}",
|
||||
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLogDescription": "Elimina gli inserimenti nel registro delle attività più vecchie dell’età configurata.",
|
||||
"Undefined": "Non Definito",
|
||||
"Forced": "Forzato",
|
||||
"Default": "Predefinito"
|
||||
"Default": "Predefinito",
|
||||
"TaskOptimizeDatabaseDescription": "Compatta Database e tronca spazi liberi. Eseguire questa azione dopo la scansione o dopo aver fatto altri cambiamenti inerenti il database potrebbe aumentarne la performance.",
|
||||
"TaskOptimizeDatabase": "Ottimizza Database"
|
||||
}
|
||||
|
|
|
@ -117,5 +117,7 @@
|
|||
"TaskCleanActivityLog": "アクティビティの履歴を消去",
|
||||
"Undefined": "未定義",
|
||||
"Forced": "強制",
|
||||
"Default": "デフォルト"
|
||||
"Default": "デフォルト",
|
||||
"TaskOptimizeDatabaseDescription": "データベースをコンパクトにして、空き領域を切り詰めます。メディアライブラリのスキャン後でこのタスクを実行するとパフォーマンスが向上する可能性があります。",
|
||||
"TaskOptimizeDatabase": "データベースの最適化"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskRefreshLibraryDescription": "Tasyğyşhanadağy jaña faildardy skanerleidі jäne metaderekterdı jañğyrtady.",
|
||||
"TaskRefreshChapterImagesDescription": "Sahnalary bar beineler üşın nobailar jasaidy.",
|
||||
"TaskCleanCacheDescription": "Jüiede qajet emes keştelgen faildardy joiady.",
|
||||
"TaskCleanActivityLogDescription": "Äreket jūrnalyndağy teñşelgen jasynan asqan jazbalary joiady."
|
||||
"TaskCleanActivityLogDescription": "Äreket jūrnalyndağy teñşelgen jasynan asqan jazbalary joiady.",
|
||||
"TaskOptimizeDatabaseDescription": "Derekqordy qysyp, bos oryndy qysqartady. Būl tapsyrmany tasyğyşhanany skanerlegennen keiın nemese derekqorğa meñzeitın basqa özgertuler ıstelgennen keiın oryndau önımdılıktı damytuy mümkın.",
|
||||
"TaskOptimizeDatabase": "Derekqordy oñtailandyru"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "활동내역청소",
|
||||
"Undefined": "일치하지 않음",
|
||||
"Forced": "강제하기",
|
||||
"Default": "기본 설정"
|
||||
"Default": "기본 설정",
|
||||
"TaskOptimizeDatabaseDescription": "데이터베이스를 압축하고 사용 가능한 공간을 늘립니다. 라이브러리를 검색한 후 이 작업을 실행하거나 데이터베이스 수정같은 비슷한 작업을 수행하면 성능이 향상될 수 있습니다.",
|
||||
"TaskOptimizeDatabase": "데이터베이스 최적화"
|
||||
}
|
||||
|
|
|
@ -117,5 +117,7 @@
|
|||
"TaskCleanActivityLogDescription": "Nodzēš darbību žurnāla ierakstus, kuri ir vecāki par doto vecumu.",
|
||||
"TaskCleanActivityLog": "Notīrīt Darbību Žurnālu",
|
||||
"Undefined": "Nenoteikts",
|
||||
"Default": "Noklusējums"
|
||||
"Default": "Noklusējums",
|
||||
"TaskOptimizeDatabaseDescription": "Saspiež datubāzi un atbrīvo atmiņu. Uzdevum palaišana pēc bibliotēku skenēšanas vai citām, ar datubāzi saistītām, izmaiņām iespējams uzlabos ātrdarbību.",
|
||||
"TaskOptimizeDatabase": "Optimizēt datubāzi"
|
||||
}
|
||||
|
|
|
@ -117,5 +117,7 @@
|
|||
"Favorites": "പ്രിയങ്കരങ്ങൾ",
|
||||
"Books": "പുസ്തകങ്ങൾ",
|
||||
"Genres": "വിഭാഗങ്ങൾ",
|
||||
"Channels": "ചാനലുകൾ"
|
||||
"Channels": "ചാനലുകൾ",
|
||||
"TaskOptimizeDatabaseDescription": "ഡാറ്റാബേസ് ചുരുക്കുകയും സ്വതന്ത്ര ഇടം വെട്ടിച്ചുരുക്കുകയും ചെയ്യുന്നു. ലൈബ്രറി സ്കാൻ ചെയ്തതിനുശേഷം അല്ലെങ്കിൽ ഡാറ്റാബേസ് പരിഷ്ക്കരണങ്ങളെ സൂചിപ്പിക്കുന്ന മറ്റ് മാറ്റങ്ങൾ ചെയ്തതിന് ശേഷം ഈ ടാസ്ക് പ്രവർത്തിപ്പിക്കുന്നത് പ്രകടനം മെച്ചപ്പെടുത്തും.",
|
||||
"TaskOptimizeDatabase": "ഡാറ്റാബേസ് ഒപ്റ്റിമൈസ് ചെയ്യുക"
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"Artists": "Artis",
|
||||
"AuthenticationSucceededWithUserName": "{0} berjaya disahkan",
|
||||
"Books": "Buku-buku",
|
||||
"CameraImageUploadedFrom": "Ada gambar dari kamera yang baru dimuat naik melalui {0}",
|
||||
"CameraImageUploadedFrom": "Gambar baharu telah dimuat naik melalui {0}",
|
||||
"Channels": "Saluran",
|
||||
"ChapterNameValue": "Bab {0}",
|
||||
"Collections": "Koleksi",
|
||||
|
@ -101,5 +101,13 @@
|
|||
"Forced": "Paksa",
|
||||
"Default": "Asal",
|
||||
"TaskCleanCache": "Bersihkan Direktori Cache",
|
||||
"TaskCleanActivityLogDescription": "Padamkan entri log aktiviti yang lebih tua daripada usia yang dikonfigurasi."
|
||||
"TaskCleanActivityLogDescription": "Padamkan entri log aktiviti yang lebih tua daripada usia yang dikonfigurasi.",
|
||||
"TaskRefreshPeople": "Segarkan Orang",
|
||||
"TaskCleanLogsDescription": "Padamkan fail log yang berumur lebih dari {0} hari.",
|
||||
"TaskCleanLogs": "Bersihkan Direktotri Log",
|
||||
"TaskRefreshLibraryDescription": "Imbas perpustakaan media untuk mencari fail-fail baru dan menyegarkan metadata.",
|
||||
"TaskRefreshLibrary": "Imbas Perpustakaan Media",
|
||||
"TaskRefreshChapterImagesDescription": "Membuat gambaran kecil untuk video yang mempunyai bab.",
|
||||
"TaskRefreshChapterImages": "Ekstrak Gambar-gambar Bab",
|
||||
"TaskCleanCacheDescription": "Menghapuskan fail cache yang tidak lagi diperlukan oleh sistem."
|
||||
}
|
||||
|
|
|
@ -118,5 +118,6 @@
|
|||
"Undefined": "Udefinert",
|
||||
"Forced": "Tvunget",
|
||||
"Default": "Standard",
|
||||
"TaskCleanActivityLogDescription": "Sletter oppføringer i aktivitetsloggen som er eldre enn den konfigurerte alderen."
|
||||
"TaskCleanActivityLogDescription": "Sletter oppføringer i aktivitetsloggen som er eldre enn den konfigurerte alderen.",
|
||||
"TaskOptimizeDatabase": "Optimiser database"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"Albums": "Albums",
|
||||
"AppDeviceValues": "App: {0}, Apparaat: {1}",
|
||||
"Application": "Applicatie",
|
||||
"Application": "Toepassing",
|
||||
"Artists": "Artiesten",
|
||||
"AuthenticationSucceededWithUserName": "{0} is succesvol geauthenticeerd",
|
||||
"Books": "Boeken",
|
||||
|
@ -25,7 +25,7 @@
|
|||
"HeaderLiveTV": "Live TV",
|
||||
"HeaderNextUp": "Volgende",
|
||||
"HeaderRecordingGroups": "Opnamegroepen",
|
||||
"HomeVideos": "Home video's",
|
||||
"HomeVideos": "Thuis video's",
|
||||
"Inherit": "Erven",
|
||||
"ItemAddedWithName": "{0} is toegevoegd aan de bibliotheek",
|
||||
"ItemRemovedWithName": "{0} is verwijderd uit de bibliotheek",
|
||||
|
@ -92,11 +92,11 @@
|
|||
"ValueHasBeenAddedToLibrary": "{0} is toegevoegd aan je mediabibliotheek",
|
||||
"ValueSpecialEpisodeName": "Speciaal - {0}",
|
||||
"VersionNumber": "Versie {0}",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Zoekt op het internet naar missende ondertitels gebaseerd op metadata configuratie.",
|
||||
"TaskDownloadMissingSubtitles": "Download missende ondertitels",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Zoekt op het internet naar missende ondertiteling gebaseerd op metadata configuratie.",
|
||||
"TaskDownloadMissingSubtitles": "Download missende ondertiteling",
|
||||
"TaskRefreshChannelsDescription": "Vernieuwt informatie van internet kanalen.",
|
||||
"TaskRefreshChannels": "Vernieuw Kanalen",
|
||||
"TaskCleanTranscodeDescription": "Verwijder transcode bestanden ouder dan 1 dag.",
|
||||
"TaskCleanTranscodeDescription": "Verwijdert transcode bestanden ouder dan 1 dag.",
|
||||
"TaskCleanLogs": "Log Folder Opschonen",
|
||||
"TaskCleanTranscode": "Transcode Folder Opschonen",
|
||||
"TaskUpdatePluginsDescription": "Download en installeert updates voor plugins waar automatisch updaten aan staat.",
|
||||
|
@ -108,15 +108,17 @@
|
|||
"TaskRefreshLibrary": "Scan Media Bibliotheek",
|
||||
"TaskRefreshChapterImagesDescription": "Maakt thumbnails aan voor videos met hoofdstukken.",
|
||||
"TaskRefreshChapterImages": "Hoofdstukafbeeldingen Uitpakken",
|
||||
"TaskCleanCacheDescription": "Verwijder gecachte bestanden die het systeem niet langer nodig heeft.",
|
||||
"TaskCleanCacheDescription": "Verwijdert gecachte bestanden die het systeem niet langer nodig heeft.",
|
||||
"TaskCleanCache": "Cache Folder Opschonen",
|
||||
"TasksChannelsCategory": "Internet Kanalen",
|
||||
"TasksApplicationCategory": "Applicatie",
|
||||
"TasksLibraryCategory": "Bibliotheek",
|
||||
"TasksMaintenanceCategory": "Onderhoud",
|
||||
"TaskCleanActivityLogDescription": "Verwijder activiteiten logs ouder dan de ingestelde tijd.",
|
||||
"TaskCleanActivityLogDescription": "Verwijdert activiteiten logs ouder dan de ingestelde tijd.",
|
||||
"TaskCleanActivityLog": "Leeg activiteiten logboek",
|
||||
"Undefined": "Niet gedefinieerd",
|
||||
"Forced": "Geforceerd",
|
||||
"Default": "Standaard"
|
||||
"Default": "Standaard",
|
||||
"TaskOptimizeDatabaseDescription": "Comprimeert de database en trimt vrije ruimte. Het uitvoeren van deze taak kan de prestaties verbeteren, na het scannen van de bibliotheek of andere aanpassingen die invloed hebben op de database.",
|
||||
"TaskOptimizeDatabase": "Database optimaliseren"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,6 @@
|
|||
"TaskCleanActivityLog": "Czyść dziennik aktywności",
|
||||
"Undefined": "Nieustalony",
|
||||
"Forced": "Wymuszony",
|
||||
"Default": "Domyślne"
|
||||
"Default": "Domyślne",
|
||||
"TaskOptimizeDatabase": "Optymalizuj bazę danych"
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
"NameSeasonUnknown": "Temporada Desconhecida",
|
||||
"NameSeasonNumber": "Temporada {0}",
|
||||
"NameInstallFailed": "Falha na instalação de {0}",
|
||||
"MusicVideos": "Videoclips",
|
||||
"MusicVideos": "Videoclipes",
|
||||
"Music": "Música",
|
||||
"MixedContent": "Conteúdo Misto",
|
||||
"MessageServerConfigurationUpdated": "A configuração do servidor foi actualizada",
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Очистить журнал активности",
|
||||
"Undefined": "Не определено",
|
||||
"Forced": "Форсир-ые",
|
||||
"Default": "По умолчанию"
|
||||
"Default": "По умолчанию",
|
||||
"TaskOptimizeDatabaseDescription": "Сжимает базу данных и обрезает свободное место. Выполнение этой задачи после сканирования библиотеки или внесения других изменений, предполагающих модификации базы данных, может повысить производительность.",
|
||||
"TaskOptimizeDatabase": "Оптимизировать базу данных"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Vyčistiť log aktivít",
|
||||
"Undefined": "Nedefinované",
|
||||
"Forced": "Vynútené",
|
||||
"Default": "Predvolené"
|
||||
"Default": "Predvolené",
|
||||
"TaskOptimizeDatabaseDescription": "Zmenší databázu a odstráni prázdne miesto. Spustenie tejto úlohy po skenovaní knižnice alebo po iných zmenách zahŕňajúcich úpravy databáze môže zlepšiť výkon.",
|
||||
"TaskOptimizeDatabase": "Optimalizovať databázu"
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"Folders": "Mape",
|
||||
"Genres": "Zvrsti",
|
||||
"HeaderAlbumArtists": "Izvajalci albuma",
|
||||
"HeaderContinueWatching": "Nadaljuj z ogledom",
|
||||
"HeaderContinueWatching": "Nadaljuj ogled",
|
||||
"HeaderFavoriteAlbums": "Priljubljeni albumi",
|
||||
"HeaderFavoriteArtists": "Priljubljeni izvajalci",
|
||||
"HeaderFavoriteEpisodes": "Priljubljene epizode",
|
||||
|
@ -90,7 +90,7 @@
|
|||
"UserStartedPlayingItemWithValues": "{0} predvaja {1} na {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} je nehal predvajati {1} na {2}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} je bil dodan vaši knjižnici",
|
||||
"ValueSpecialEpisodeName": "Posebna - {0}",
|
||||
"ValueSpecialEpisodeName": "Bonus - {0}",
|
||||
"VersionNumber": "Različica {0}",
|
||||
"TaskDownloadMissingSubtitles": "Prenesi manjkajoče podnapise",
|
||||
"TaskRefreshChannelsDescription": "Osveži podatke spletnih kanalov.",
|
||||
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLog": "Počisti dnevnik aktivnosti",
|
||||
"Undefined": "Nedoločen",
|
||||
"Forced": "Prisilno",
|
||||
"Default": "Privzeto"
|
||||
"Default": "Privzeto",
|
||||
"TaskOptimizeDatabaseDescription": "Stisne bazo podatkov in uredi prazen prostor. Zagon tega opravila po iskanju predstavnosti ali drugih spremembah ki vplivajo na bazo podatkov lahko izboljša hitrost delovanja.",
|
||||
"TaskOptimizeDatabase": "Optimiziraj bazo podatkov"
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
"Sync": "Sinkronizo",
|
||||
"SubtitleDownloadFailureFromForItem": "Titrat deshtuan të shkarkohen nga {0} për {1}",
|
||||
"StartupEmbyServerIsLoading": "Serveri Jellyfin po ngarkohet. Ju lutemi provoni përseri pas pak.",
|
||||
"Songs": "Këngë",
|
||||
"Shows": "Seriale",
|
||||
"Songs": "Këngët",
|
||||
"Shows": "Serialet",
|
||||
"ServerNameNeedsToBeRestarted": "{0} duhet të ristartoj",
|
||||
"ScheduledTaskStartedWithName": "{0} filloi",
|
||||
"ScheduledTaskFailedWithName": "{0} dështoi",
|
||||
|
@ -74,9 +74,9 @@
|
|||
"NameSeasonUnknown": "Sezon i panjohur",
|
||||
"NameSeasonNumber": "Sezoni {0}",
|
||||
"NameInstallFailed": "Instalimi i {0} dështoi",
|
||||
"MusicVideos": "Video muzikore",
|
||||
"MusicVideos": "Videot muzikore",
|
||||
"Music": "Muzikë",
|
||||
"Movies": "Filma",
|
||||
"Movies": "Filmat",
|
||||
"MixedContent": "Përmbajtje e përzier",
|
||||
"MessageServerConfigurationUpdated": "Konfigurimet e serverit u përditësuan",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Seksioni i konfigurimit të serverit {0} u përditësua",
|
||||
|
@ -97,20 +97,27 @@
|
|||
"HeaderFavoriteAlbums": "Albumet e preferuar",
|
||||
"HeaderContinueWatching": "Vazhdo të shikosh",
|
||||
"HeaderAlbumArtists": "Artistët e albumeve",
|
||||
"Genres": "Zhanre",
|
||||
"Folders": "Dosje",
|
||||
"Favorites": "Të preferuara",
|
||||
"Genres": "Zhanret",
|
||||
"Folders": "Skedarët",
|
||||
"Favorites": "Të preferuarat",
|
||||
"FailedLoginAttemptWithUserName": "Përpjekja për hyrje dështoi nga {0}",
|
||||
"DeviceOnlineWithName": "{0} u lidh",
|
||||
"DeviceOfflineWithName": "{0} u shkëput",
|
||||
"Collections": "Koleksione",
|
||||
"Collections": "Koleksionet",
|
||||
"ChapterNameValue": "Kapituj",
|
||||
"Channels": "Kanale",
|
||||
"Channels": "Kanalet",
|
||||
"CameraImageUploadedFrom": "Një foto e re nga kamera u ngarkua nga {0}",
|
||||
"Books": "Libra",
|
||||
"Books": "Librat",
|
||||
"AuthenticationSucceededWithUserName": "{0} u identifikua me sukses",
|
||||
"Artists": "Artistë",
|
||||
"Artists": "Artistët",
|
||||
"Application": "Aplikacioni",
|
||||
"AppDeviceValues": "Aplikacioni: {0}, Pajisja: {1}",
|
||||
"Albums": "Albume"
|
||||
"Albums": "Albumet",
|
||||
"TaskCleanActivityLogDescription": "Pastro të dhënat mbi aktivitetin më të vjetra sesa koha e përcaktuar.",
|
||||
"TaskCleanActivityLog": "Pastro të dhënat mbi aktivitetin",
|
||||
"Undefined": "I papërcaktuar",
|
||||
"Forced": "I detyruar",
|
||||
"Default": "Parazgjedhur",
|
||||
"TaskOptimizeDatabaseDescription": "Kompakton bazën e të dhënave dhe shkurton hapësirën e lirë. Drejtimi i kësaj detyre pasi skanoni bibliotekën ose bëni ndryshime të tjera që nënkuptojnë modifikime të bazës së të dhënave mund të përmirësojë performancën.",
|
||||
"TaskOptimizeDatabase": "Optimizo databazën"
|
||||
}
|
||||
|
|
|
@ -117,5 +117,7 @@
|
|||
"TaskCleanActivityLog": "செயல்பாட்டு பதிவை அழி",
|
||||
"Undefined": "வரையறுக்கப்படாத",
|
||||
"Forced": "கட்டாயப்படுத்தப்பட்டது",
|
||||
"Default": "இயல்புநிலை"
|
||||
"Default": "இயல்புநிலை",
|
||||
"TaskOptimizeDatabaseDescription": "தரவுத்தளத்தை சுருக்கி, இலவச இடத்தை குறைக்கிறது. நூலகத்தை ஸ்கேன் செய்தபின் அல்லது தரவுத்தள மாற்றங்களைக் குறிக்கும் பிற மாற்றங்களைச் செய்தபின் இந்த பணியை இயக்குவது செயல்திறனை மேம்படுத்தக்கூடும்.",
|
||||
"TaskOptimizeDatabase": "தரவுத்தளத்தை மேம்படுத்தவும்"
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
"NameInstallFailed": "{0} kurulumu başarısız",
|
||||
"NameSeasonNumber": "Sezon {0}",
|
||||
"NameSeasonUnknown": "Bilinmeyen Sezon",
|
||||
"NewVersionIsAvailable": "Jellyfin Sunucusunun yeni bir versiyonu indirmek için hazır.",
|
||||
"NewVersionIsAvailable": "Jellyfin Sunucusunun yeni bir sürümü indirmek için hazır.",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Uygulama güncellemesi mevcut",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Uygulama güncellemesi yüklendi",
|
||||
"NotificationOptionAudioPlayback": "Ses çalma başladı",
|
||||
|
@ -75,7 +75,7 @@
|
|||
"StartupEmbyServerIsLoading": "Jellyfin Sunucusu yükleniyor. Lütfen kısa süre sonra tekrar deneyin.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "{1} için alt yazılar {0} 'dan indirilemedi",
|
||||
"Sync": "Eşitle",
|
||||
"Sync": "Eşzamanlama",
|
||||
"System": "Sistem",
|
||||
"TvShows": "Diziler",
|
||||
"User": "Kullanıcı",
|
||||
|
@ -89,34 +89,36 @@
|
|||
"UserPolicyUpdatedWithName": "Kullanıcı politikası {0} için güncellendi",
|
||||
"UserStartedPlayingItemWithValues": "{0}, {2} cihazında {1} izliyor",
|
||||
"UserStoppedPlayingItemWithValues": "{0}, {2} cihazında {1} izlemeyi bitirdi",
|
||||
"ValueHasBeenAddedToLibrary": "Medya kitaplığınıza {0} eklendi",
|
||||
"ValueHasBeenAddedToLibrary": "Medya kütüphanenize {0} eklendi",
|
||||
"ValueSpecialEpisodeName": "Özel - {0}",
|
||||
"VersionNumber": "Versiyon {0}",
|
||||
"VersionNumber": "Sürüm {0}",
|
||||
"TaskCleanCache": "Geçici dosya klasörünü temizle",
|
||||
"TasksChannelsCategory": "İnternet kanalları",
|
||||
"TasksApplicationCategory": "Uygulama",
|
||||
"TasksLibraryCategory": "Kütüphane",
|
||||
"TasksMaintenanceCategory": "Onarım",
|
||||
"TasksMaintenanceCategory": "Bakım",
|
||||
"TaskRefreshPeopleDescription": "Medya kütüphanenizdeki videoların oyuncu ve yönetmen bilgilerini günceller.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Metadata ayarlarını baz alarak eksik altyazıları internette arar.",
|
||||
"TaskDownloadMissingSubtitles": "Eksik altyazıları indir",
|
||||
"TaskRefreshChannelsDescription": "Internet kanal bilgilerini yenile.",
|
||||
"TaskRefreshChannels": "Kanalları Yenile",
|
||||
"TaskCleanTranscodeDescription": "Bir günü dolmuş dönüştürme bilgisi içeren dosyaları siler.",
|
||||
"TaskCleanTranscodeDescription": "Bir günden daha eski dönüştürme dosyalarını siler.",
|
||||
"TaskCleanTranscode": "Dönüşüm Dizinini Temizle",
|
||||
"TaskUpdatePluginsDescription": "Otomatik güncellenmeye ayarlanmış eklentilerin güncellemelerini indirir ve kurar.",
|
||||
"TaskUpdatePlugins": "Eklentileri Güncelle",
|
||||
"TaskRefreshPeople": "Kullanıcıları Yenile",
|
||||
"TaskCleanLogsDescription": "{0} günden eski log dosyalarını siler.",
|
||||
"TaskCleanLogs": "Log Dizinini Temizle",
|
||||
"TaskRefreshLibraryDescription": "Medya kütüphanenize eklenen yeni dosyaları arar ve bilgileri yeniler.",
|
||||
"TaskCleanLogsDescription": "{0} günden eski günlük dosyalarını siler.",
|
||||
"TaskCleanLogs": "Günlük Dizinini Temizle",
|
||||
"TaskRefreshLibraryDescription": "Medya kütüphanenize eklenen yeni dosyaları arar ve ortam bilgilerini yeniler.",
|
||||
"TaskRefreshLibrary": "Medya Kütüphanesini Tara",
|
||||
"TaskRefreshChapterImagesDescription": "Sahnelere ayrılmış videolar için küçük resimler oluştur.",
|
||||
"TaskRefreshChapterImages": "Bölüm Resimlerini Çıkar",
|
||||
"TaskCleanCacheDescription": "Sistem tarafından artık ihtiyaç duyulmayan önbellek dosyalarını siler.",
|
||||
"TaskCleanActivityLog": "İşlem Günlüğünü Temizle",
|
||||
"TaskCleanActivityLogDescription": "Belirtilen sureden daha eski etkinlik log kayıtları silindi.",
|
||||
"TaskCleanActivityLog": "Etkinlik Günlüğünü Temizle",
|
||||
"TaskCleanActivityLogDescription": "Yapılandırılan tarihten daha eski olan etkinlik günlüğü girişlerini siler.",
|
||||
"Undefined": "Bilinmeyen",
|
||||
"Default": "Varsayılan",
|
||||
"Forced": "Zorla"
|
||||
"Forced": "Zorla",
|
||||
"TaskOptimizeDatabaseDescription": "Veritabanını sıkıştırır ve boş alanı keser. Kitaplığı taradıktan sonra veya veritabanında değişiklik anlamına gelen diğer işlemleri yaptıktan sonra bu görevi çalıştırmak performansı artırabilir.",
|
||||
"TaskOptimizeDatabase": "Veritabanını optimize et"
|
||||
}
|
||||
|
|
|
@ -117,5 +117,7 @@
|
|||
"TaskCleanActivityLog": "Xóa Nhật Ký Hoạt Động",
|
||||
"Undefined": "Không Xác Định",
|
||||
"Forced": "Bắt Buộc",
|
||||
"Default": "Mặc Định"
|
||||
"Default": "Mặc Định",
|
||||
"TaskOptimizeDatabaseDescription": "Thu gọn cơ sở dữ liệu và cắt bớt dung lượng trống. Chạy tác vụ này sau khi quét thư viện hoặc thực hiện các thay đổi khác ngụ ý sửa đổi cơ sở dữ liệu có thể cải thiện hiệu suất.",
|
||||
"TaskOptimizeDatabase": "Tối ưu hóa cơ sở dữ liệu"
|
||||
}
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"TaskCleanActivityLogDescription": "删除早于设置时间的活动日志条目。",
|
||||
"Undefined": "未定义",
|
||||
"Forced": "强制的",
|
||||
"Default": "默认"
|
||||
"Default": "默认",
|
||||
"TaskOptimizeDatabaseDescription": "压缩数据库并优化可用空间,在扫描库或执行其他数据库修改后运行此任务可能会提高性能。",
|
||||
"TaskOptimizeDatabase": "优化数据库"
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ namespace Emby.Server.Implementations.Localization
|
|||
public class LocalizationManager : ILocalizationManager
|
||||
{
|
||||
private const string DefaultCulture = "en-US";
|
||||
private const string RatingsPath = "Emby.Server.Implementations.Localization.Ratings.";
|
||||
private const string CulturesPath = "Emby.Server.Implementations.Localization.iso6392.txt";
|
||||
private const string CountriesPath = "Emby.Server.Implementations.Localization.countries.json";
|
||||
private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
|
||||
private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
|
||||
|
||||
|
@ -58,22 +61,19 @@ namespace Emby.Server.Implementations.Localization
|
|||
/// <returns><see cref="Task" />.</returns>
|
||||
public async Task LoadAll()
|
||||
{
|
||||
const string RatingsResource = "Emby.Server.Implementations.Localization.Ratings.";
|
||||
|
||||
// Extract from the assembly
|
||||
foreach (var resource in _assembly.GetManifestResourceNames())
|
||||
{
|
||||
if (!resource.StartsWith(RatingsResource, StringComparison.Ordinal))
|
||||
if (!resource.StartsWith(RatingsPath, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string countryCode = resource.Substring(RatingsResource.Length, 2);
|
||||
string countryCode = resource.Substring(RatingsPath.Length, 2);
|
||||
var dict = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
using (var str = _assembly.GetManifestResourceStream(resource))
|
||||
using (var reader = new StreamReader(str))
|
||||
{
|
||||
await using var str = _assembly.GetManifestResourceStream(resource);
|
||||
using var reader = new StreamReader(str);
|
||||
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
|
@ -95,7 +95,6 @@ namespace Emby.Server.Implementations.Localization
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
_allParentalRatings[countryCode] = dict;
|
||||
}
|
||||
|
@ -114,11 +113,8 @@ namespace Emby.Server.Implementations.Localization
|
|||
{
|
||||
List<CultureDto> list = new List<CultureDto>();
|
||||
|
||||
const string ResourcePath = "Emby.Server.Implementations.Localization.iso6392.txt";
|
||||
|
||||
using (var stream = _assembly.GetManifestResourceStream(ResourcePath))
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
await using var stream = _assembly.GetManifestResourceStream(CulturesPath);
|
||||
using var reader = new StreamReader(stream);
|
||||
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
|
@ -161,7 +157,6 @@ namespace Emby.Server.Implementations.Localization
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cultures = list;
|
||||
}
|
||||
|
@ -188,7 +183,7 @@ namespace Emby.Server.Implementations.Localization
|
|||
/// <inheritdoc />
|
||||
public IEnumerable<CountryInfo> GetCountries()
|
||||
{
|
||||
using StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
|
||||
using StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream(CountriesPath));
|
||||
|
||||
return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), _jsonOptions);
|
||||
}
|
||||
|
@ -350,8 +345,7 @@ namespace Emby.Server.Implementations.Localization
|
|||
|
||||
private async Task CopyInto(IDictionary<string, string> dictionary, string resourcePath)
|
||||
{
|
||||
using (var stream = _assembly.GetManifestResourceStream(resourcePath))
|
||||
{
|
||||
await using var stream = _assembly.GetManifestResourceStream(resourcePath);
|
||||
// If a Culture doesn't have a translation the stream will be null and it defaults to en-us further up the chain
|
||||
if (stream != null)
|
||||
{
|
||||
|
@ -367,7 +361,6 @@ namespace Emby.Server.Implementations.Localization
|
|||
_logger.LogError("Missing translation/culture resource: {ResourcePath}", resourcePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetResourceFilename(string culture)
|
||||
{
|
||||
|
|
|
@ -147,7 +147,7 @@ namespace Emby.Server.Implementations.Playlists
|
|||
|
||||
playlist.SetMediaType(options.MediaType);
|
||||
|
||||
parentFolder.AddChild(playlist, CancellationToken.None);
|
||||
parentFolder.AddChild(playlist);
|
||||
|
||||
await playlist.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ForceSave = true }, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
|
|
|
@ -55,9 +55,19 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||
_localization = localization;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the triggers that define when the task will run.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public string Name => _localization.GetLocalizedString("TaskRefreshChapterImages");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => _localization.GetLocalizedString("TaskRefreshChapterImagesDescription");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Category => _localization.GetLocalizedString("TasksLibraryCategory");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Key => "RefreshChapterImages";
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
{
|
||||
return new[]
|
||||
|
@ -162,26 +172,5 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => _localization.GetLocalizedString("TaskRefreshChapterImages");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => _localization.GetLocalizedString("TaskRefreshChapterImagesDescription");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Category => _localization.GetLocalizedString("TasksLibraryCategory");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Key => "RefreshChapterImages";
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsHidden => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsEnabled => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsLogged => true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||
throw new Exception($"Activity Log Retention days must be at least 0. Currently: {retentionDays}");
|
||||
}
|
||||
|
||||
var startDate = DateTime.UtcNow.AddDays(retentionDays.Value * -1);
|
||||
var startDate = DateTime.UtcNow.AddDays(-retentionDays.Value);
|
||||
return _activityManager.CleanAsync(startDate);
|
||||
}
|
||||
|
||||
|
|
|
@ -1380,7 +1380,7 @@ namespace Jellyfin.Api.Controllers
|
|||
}
|
||||
else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var outputFmp4HeaderArg = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) switch
|
||||
var outputFmp4HeaderArg = OperatingSystem.IsWindows() switch
|
||||
{
|
||||
// on Windows, the path of fmp4 header file needs to be configured
|
||||
true => " -hls_fmp4_init_filename \"" + outputPrefix + "-1" + outputExtension + "\"",
|
||||
|
@ -1496,7 +1496,7 @@ namespace Jellyfin.Api.Controllers
|
|||
args += " -ar " + state.OutputAudioSampleRate.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions, true);
|
||||
args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
|
|
@ -228,42 +228,6 @@ namespace Jellyfin.Api.Controllers
|
|||
return GetResult(items, user, limit, dtoOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instant playlist based on a given genre.
|
||||
/// </summary>
|
||||
/// <param name="id">The item id.</param>
|
||||
/// <param name="userId">Optional. Filter by user id, and attach user data.</param>
|
||||
/// <param name="limit">Optional. The maximum number of records to return.</param>
|
||||
/// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
|
||||
/// <param name="enableImages">Optional. Include image information in output.</param>
|
||||
/// <param name="enableUserData">Optional. Include user data.</param>
|
||||
/// <param name="imageTypeLimit">Optional. The max number of images to return, per image type.</param>
|
||||
/// <param name="enableImageTypes">Optional. The image types to include in the output.</param>
|
||||
/// <response code="200">Instant playlist returned.</response>
|
||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the playlist items.</returns>
|
||||
[HttpGet("MusicGenres/{id}/InstantMix")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenreById(
|
||||
[FromRoute, Required] Guid id,
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] int? limit,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery] bool? enableImages,
|
||||
[FromQuery] bool? enableUserData,
|
||||
[FromQuery] int? imageTypeLimit,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(id);
|
||||
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
||||
? _userManager.GetUserById(userId.Value)
|
||||
: null;
|
||||
var dtoOptions = new DtoOptions { Fields = fields }
|
||||
.AddClientFields(Request)
|
||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes!);
|
||||
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
||||
return GetResult(items, user, limit, dtoOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instant playlist based on a given item.
|
||||
/// </summary>
|
||||
|
@ -352,8 +316,7 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the playlist items.</returns>
|
||||
[HttpGet("MusicGenres/InstantMix")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[Obsolete("Use GetInstantMixFromMusicGenres instead")]
|
||||
public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenreById2(
|
||||
public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenreById(
|
||||
[FromQuery, Required] Guid id,
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] int? limit,
|
||||
|
@ -363,15 +326,15 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] int? imageTypeLimit,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
|
||||
{
|
||||
return GetInstantMixFromMusicGenreById(
|
||||
id,
|
||||
userId,
|
||||
limit,
|
||||
fields,
|
||||
enableImages,
|
||||
enableUserData,
|
||||
imageTypeLimit,
|
||||
enableImageTypes);
|
||||
var item = _libraryManager.GetItemById(id);
|
||||
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
||||
? _userManager.GetUserById(userId.Value)
|
||||
: null;
|
||||
var dtoOptions = new DtoOptions { Fields = fields }
|
||||
.AddClientFields(Request)
|
||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes!);
|
||||
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
||||
return GetResult(items, user, limit, dtoOptions);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItemDto> GetResult(List<BaseItem> items, User? user, int? limit, DtoOptions dtoOptions)
|
||||
|
|
|
@ -161,6 +161,11 @@ namespace Jellyfin.Api.Controllers
|
|||
liveStreamId)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (info.ErrorCode != null)
|
||||
{
|
||||
return info;
|
||||
}
|
||||
|
||||
if (profile != null)
|
||||
{
|
||||
// set device specific data
|
||||
|
@ -302,27 +307,12 @@ namespace Jellyfin.Api.Controllers
|
|||
/// </summary>
|
||||
/// <param name="size">The bitrate. Defaults to 102400.</param>
|
||||
/// <response code="200">Test buffer returned.</response>
|
||||
/// <response code="400">Size has to be a numer between 0 and 10,000,000.</response>
|
||||
/// <returns>A <see cref="FileResult"/> with specified bitrate.</returns>
|
||||
[HttpGet("Playback/BitrateTest")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[Produces(MediaTypeNames.Application.Octet)]
|
||||
[ProducesFile(MediaTypeNames.Application.Octet)]
|
||||
public ActionResult GetBitrateTestBytes([FromQuery] int size = 102400)
|
||||
public ActionResult GetBitrateTestBytes([FromQuery][Range(1, 100_000_000, ErrorMessage = "The requested size must be greater than or equal to {1} and less than or equal to {2}")] int size = 102400)
|
||||
{
|
||||
const int MaxSize = 10_000_000;
|
||||
|
||||
if (size <= 0)
|
||||
{
|
||||
return BadRequest($"The requested size ({size}) is equal to or smaller than 0.");
|
||||
}
|
||||
|
||||
if (size > MaxSize)
|
||||
{
|
||||
return BadRequest($"The requested size ({size}) is larger than the max allowed value ({MaxSize}).");
|
||||
}
|
||||
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(size);
|
||||
try
|
||||
{
|
||||
|
|
|
@ -366,8 +366,7 @@ namespace Jellyfin.Api.Controllers
|
|||
else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var outputFmp4HeaderArg = string.Empty;
|
||||
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
if (isWindows)
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
// on Windows, the path of fmp4 header file needs to be configured
|
||||
outputFmp4HeaderArg = " -hls_fmp4_init_filename \"" + outputPrefix + "-1" + outputExtension + "\"";
|
||||
|
@ -485,7 +484,7 @@ namespace Jellyfin.Api.Controllers
|
|||
args += " -ar " + state.OutputAudioSampleRate.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions, true);
|
||||
args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
|
|
@ -296,6 +296,8 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <param name="startTimeTicks">Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms.</param>
|
||||
/// <param name="width">Optional. The fixed horizontal resolution of the encoded video.</param>
|
||||
/// <param name="height">Optional. The fixed vertical resolution of the encoded video.</param>
|
||||
/// <param name="maxWidth">Optional. The maximum horizontal resolution of the encoded video.</param>
|
||||
/// <param name="maxHeight">Optional. The maximum vertical resolution of the encoded video.</param>
|
||||
/// <param name="videoBitRate">Optional. Specify a video bitrate to encode to, e.g. 500000. If omitted this will be left to encoder defaults.</param>
|
||||
/// <param name="subtitleStreamIndex">Optional. The index of the subtitle stream to use. If omitted no subtitles will be used.</param>
|
||||
/// <param name="subtitleMethod">Optional. Specify the subtitle delivery method.</param>
|
||||
|
@ -352,6 +354,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] long? startTimeTicks,
|
||||
[FromQuery] int? width,
|
||||
[FromQuery] int? height,
|
||||
[FromQuery] int? maxWidth,
|
||||
[FromQuery] int? maxHeight,
|
||||
[FromQuery] int? videoBitRate,
|
||||
[FromQuery] int? subtitleStreamIndex,
|
||||
[FromQuery] SubtitleDeliveryMethod? subtitleMethod,
|
||||
|
@ -407,6 +411,8 @@ namespace Jellyfin.Api.Controllers
|
|||
StartTimeTicks = startTimeTicks,
|
||||
Width = width,
|
||||
Height = height,
|
||||
MaxWidth = maxWidth,
|
||||
MaxHeight = maxHeight,
|
||||
VideoBitRate = videoBitRate,
|
||||
SubtitleStreamIndex = subtitleStreamIndex,
|
||||
SubtitleMethod = subtitleMethod ?? SubtitleDeliveryMethod.Encode,
|
||||
|
@ -550,6 +556,8 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <param name="startTimeTicks">Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms.</param>
|
||||
/// <param name="width">Optional. The fixed horizontal resolution of the encoded video.</param>
|
||||
/// <param name="height">Optional. The fixed vertical resolution of the encoded video.</param>
|
||||
/// <param name="maxWidth">Optional. The maximum horizontal resolution of the encoded video.</param>
|
||||
/// <param name="maxHeight">Optional. The maximum vertical resolution of the encoded video.</param>
|
||||
/// <param name="videoBitRate">Optional. Specify a video bitrate to encode to, e.g. 500000. If omitted this will be left to encoder defaults.</param>
|
||||
/// <param name="subtitleStreamIndex">Optional. The index of the subtitle stream to use. If omitted no subtitles will be used.</param>
|
||||
/// <param name="subtitleMethod">Optional. Specify the subtitle delivery method.</param>
|
||||
|
@ -606,6 +614,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] long? startTimeTicks,
|
||||
[FromQuery] int? width,
|
||||
[FromQuery] int? height,
|
||||
[FromQuery] int? maxWidth,
|
||||
[FromQuery] int? maxHeight,
|
||||
[FromQuery] int? videoBitRate,
|
||||
[FromQuery] int? subtitleStreamIndex,
|
||||
[FromQuery] SubtitleDeliveryMethod? subtitleMethod,
|
||||
|
@ -657,6 +667,8 @@ namespace Jellyfin.Api.Controllers
|
|||
startTimeTicks,
|
||||
width,
|
||||
height,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
videoBitRate,
|
||||
subtitleStreamIndex,
|
||||
subtitleMethod,
|
||||
|
|
|
@ -99,8 +99,7 @@ namespace Jellyfin.Api.Helpers
|
|||
return fmp4InitFileName;
|
||||
}
|
||||
|
||||
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
if (isWindows)
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
// on Windows
|
||||
// #EXT-X-MAP:URI="X:\transcodes\prefix-1.mp4"
|
||||
|
|
|
@ -444,6 +444,10 @@ namespace Jellyfin.Api.Helpers
|
|||
{
|
||||
var audioCodec = state.ActualOutputAudioCodec;
|
||||
var videoCodec = state.ActualOutputVideoCodec;
|
||||
var hardwareAccelerationTypeString = _serverConfigurationManager.GetEncodingOptions().HardwareAccelerationType;
|
||||
HardwareEncodingType? hardwareAccelerationType = string.IsNullOrEmpty(hardwareAccelerationTypeString)
|
||||
? null
|
||||
: (HardwareEncodingType)Enum.Parse(typeof(HardwareEncodingType), hardwareAccelerationTypeString, true);
|
||||
|
||||
_sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
|
||||
{
|
||||
|
@ -458,6 +462,7 @@ namespace Jellyfin.Api.Helpers
|
|||
AudioChannels = state.OutputAudioChannels,
|
||||
IsAudioDirect = EncodingHelper.IsCopyCodec(state.OutputAudioCodec),
|
||||
IsVideoDirect = EncodingHelper.IsCopyCodec(state.OutputVideoCodec),
|
||||
HardwareAccelerationType = hardwareAccelerationType,
|
||||
TranscodeReasons = state.TranscodeReasons
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,17 +8,16 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<!-- https://github.com/microsoft/ApplicationInsights-dotnet/issues/2047 -->
|
||||
<NoWarn>AD0001</NoWarn>
|
||||
<AnalysisMode>AllDisabledByDefault</AnalysisMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.1.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.5" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.1.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -33,10 +32,6 @@
|
|||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>Jellyfin.Api.Tests</_Parameter1>
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
<Nullable>enable</Nullable>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -22,8 +18,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="BlurHashSharp" Version="1.2.0" />
|
||||
<PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.2.0" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.80.2" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.2" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.80.3" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -86,15 +86,12 @@ namespace Jellyfin.Server.Implementations.Activity
|
|||
|
||||
private static ActivityLogEntry ConvertToOldModel(ActivityLog entry)
|
||||
{
|
||||
return new ActivityLogEntry
|
||||
return new ActivityLogEntry(entry.Name, entry.Type, entry.UserId)
|
||||
{
|
||||
Id = entry.Id,
|
||||
Name = entry.Name,
|
||||
Overview = entry.Overview,
|
||||
ShortOverview = entry.ShortOverview,
|
||||
Type = entry.Type,
|
||||
ItemId = entry.ItemId,
|
||||
UserId = entry.UserId,
|
||||
Date = entry.DateCreated,
|
||||
Severity = entry.LogSeverity
|
||||
};
|
||||
|
|
|
@ -4,14 +4,6 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Code analysers-->
|
||||
|
@ -27,13 +19,13 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Linq.Async" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.7">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.7">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
|
|
@ -303,7 +303,7 @@ namespace Jellyfin.Server.Extensions
|
|||
{
|
||||
description.TryGetMethodInfo(out MethodInfo methodInfo);
|
||||
// Attribute name, method name, none.
|
||||
return description?.ActionDescriptor?.AttributeRouteInfo?.Name
|
||||
return description?.ActionDescriptor.AttributeRouteInfo?.Name
|
||||
?? methodInfo?.Name
|
||||
?? null;
|
||||
});
|
||||
|
@ -341,7 +341,7 @@ namespace Jellyfin.Server.Extensions
|
|||
{
|
||||
foreach (var address in host.GetAddresses())
|
||||
{
|
||||
AddIpAddress(config, options, addr.Address, addr.PrefixLength);
|
||||
AddIpAddress(config, options, address, address.AddressFamily == AddressFamily.InterNetwork ? 32 : 128);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ namespace Jellyfin.Server.Extensions
|
|||
Type = "object",
|
||||
Properties = typeof(ImageType).GetEnumNames().ToDictionary(
|
||||
name => name,
|
||||
name => new OpenApiSchema
|
||||
_ => new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
AdditionalProperties = new OpenApiSchema
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
<ServerGarbageCollection>false</ServerGarbageCollection>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
<!-- <DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers> -->
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -38,16 +33,16 @@
|
|||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.7" />
|
||||
<PackageReference Include="prometheus-net" Version="4.1.1" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="4.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.8" />
|
||||
<PackageReference Include="prometheus-net" Version="4.2.0" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="4.2.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Graylog" Version="2.2.2" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.4" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -58,9 +58,12 @@ namespace Jellyfin.Server.Middleware
|
|||
return;
|
||||
}
|
||||
|
||||
if (!startsWithBaseUrl)
|
||||
if (!startsWithBaseUrl
|
||||
|| localPath.Length == baseUrlPrefix.Length
|
||||
// Local path is /baseUrl/
|
||||
|| (localPath.Length == baseUrlPrefix.Length + 1 && localPath[^1] == '/'))
|
||||
{
|
||||
// Always redirect back to the default path if the base prefix is invalid or missing
|
||||
// Always redirect back to the default path if the base prefix is invalid, missing, or is the full path.
|
||||
_logger.LogDebug("Normalizing an URL at {LocalPath}", localPath);
|
||||
httpContext.Response.Redirect(baseUrlPrefix + "/" + _configuration[ConfigurationExtensions.DefaultRedirectKey]);
|
||||
return;
|
||||
|
|
|
@ -137,11 +137,6 @@ namespace Jellyfin.Server.Middleware
|
|||
|
||||
private string NormalizeExceptionMessage(string msg)
|
||||
{
|
||||
if (msg == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// Strip any information we don't want to reveal
|
||||
return msg.Replace(
|
||||
_configuration.ApplicationPaths.ProgramSystemPath,
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Jellyfin.Server.Migrations
|
|||
.Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m))
|
||||
.OfType<IMigrationRoutine>()
|
||||
.ToArray();
|
||||
var migrationOptions = ((IConfigurationManager)host.ConfigurationManager).GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey);
|
||||
var migrationOptions = host.ConfigurationManager.GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey);
|
||||
|
||||
if (!host.ConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0)
|
||||
{
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace Jellyfin.Server.Migrations.Routines
|
|||
if (entry[6].SQLiteType != SQLiteType.Null && !Guid.TryParse(entry[6].ToString(), out guid))
|
||||
{
|
||||
// This is not a valid Guid, see if it is an internal ID from an old Emby schema
|
||||
_logger.LogWarning("Invalid Guid in UserId column: ", entry[6].ToString());
|
||||
_logger.LogWarning("Invalid Guid in UserId column: {Guid}", entry[6].ToString());
|
||||
|
||||
using var statement = userDbConnection.PrepareStatement("SELECT guid FROM LocalUsersv2 WHERE Id=@Id");
|
||||
statement.TryBind("@Id", entry[6].ToString());
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user