mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-24 14:08:44 -04:00
Merge branch 'master' into naming
This commit is contained in:
commit
d5fcca3d05
193 changed files with 687 additions and 1057 deletions
|
@ -31,7 +31,7 @@ COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||||
# mesa-va-drivers: needed for VAAPI
|
# mesa-va-drivers: needed for VAAPI
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --no-install-recommends --no-install-suggests -y \
|
&& apt-get install --no-install-recommends --no-install-suggests -y \
|
||||||
libfontconfig1 libgomp1 libva-drm2 mesa-va-drivers openssl \
|
libfontconfig1 libgomp1 libva-drm2 mesa-va-drivers openssl ca-certificates \
|
||||||
&& apt-get clean autoclean \
|
&& apt-get clean autoclean \
|
||||||
&& apt-get autoremove \
|
&& apt-get autoremove \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
|
|
@ -24,7 +24,7 @@ RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin"
|
||||||
FROM debian:buster-slim
|
FROM debian:buster-slim
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
|
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
|
||||||
libssl-dev \
|
libssl-dev ca-certificates \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& mkdir -p /cache /config /media \
|
&& mkdir -p /cache /config /media \
|
||||||
&& chmod 777 /cache /config /media
|
&& chmod 777 /cache /config /media
|
||||||
|
|
|
@ -24,7 +24,7 @@ RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin"
|
||||||
FROM debian:buster-slim
|
FROM debian:buster-slim
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
|
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
|
||||||
libssl-dev \
|
libssl-dev ca-certificates \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& mkdir -p /cache /config /media \
|
&& mkdir -p /cache /config /media \
|
||||||
&& chmod 777 /cache /config /media
|
&& chmod 777 /cache /config /media
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace DvdLib.Ifo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using (var vmgFs = _fileSystem.GetFileStream(vmgPath.FullName, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
|
using (var vmgFs = new FileStream(vmgPath.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
using (var vmgRead = new BigEndianBinaryReader(vmgFs))
|
using (var vmgRead = new BigEndianBinaryReader(vmgFs))
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ namespace DvdLib.Ifo
|
||||||
{
|
{
|
||||||
VTSPaths[vtsNum] = vtsPath;
|
VTSPaths[vtsNum] = vtsPath;
|
||||||
|
|
||||||
using (var vtsFs = _fileSystem.GetFileStream(vtsPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
|
using (var vtsFs = new FileStream(vtsPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
using (var vtsRead = new BigEndianBinaryReader(vtsFs))
|
using (var vtsRead = new BigEndianBinaryReader(vtsFs))
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,6 @@ using MediaBrowser.Controller.Playlists;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Emby.Dlna.Didl
|
||||||
|
|
||||||
public Filter(string filter)
|
public Filter(string filter)
|
||||||
{
|
{
|
||||||
_all = StringHelper.EqualsIgnoreCase(filter, "*");
|
_all = string.Equals(filter, "*", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
_fields = (filter ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
_fields = (filter ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ namespace Emby.Dlna
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(systemProfilesPath);
|
Directory.CreateDirectory(systemProfilesPath);
|
||||||
|
|
||||||
using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
await stream.CopyToAsync(fileStream);
|
await stream.CopyToAsync(fileStream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Dlna.Didl;
|
using Emby.Dlna.Didl;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
|
|
@ -5,7 +5,6 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Emby.Dlna.Common;
|
using Emby.Dlna.Common;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
|
|
||||||
namespace Emby.Dlna.Server
|
namespace Emby.Dlna.Server
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
|
@ -14,7 +14,6 @@ using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -129,7 +128,7 @@ namespace Emby.Drawing
|
||||||
{
|
{
|
||||||
var file = await ProcessImage(options).ConfigureAwait(false);
|
var file = await ProcessImage(options).ConfigureAwait(false);
|
||||||
|
|
||||||
using (var fileStream = _fileSystem.GetFileStream(file.Item1, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read, true))
|
using (var fileStream = new FileStream(file.Item1, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, true))
|
||||||
{
|
{
|
||||||
await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
|
await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Controller;
|
|
||||||
using MediaBrowser.Controller.Notifications;
|
using MediaBrowser.Controller.Notifications;
|
||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.Notifications;
|
using MediaBrowser.Model.Notifications;
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
||||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#pragma warning disable SA1600
|
#pragma warning disable SA1600
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
|
|
|
@ -599,7 +599,7 @@ namespace Emby.Server.Implementations
|
||||||
HttpsPort = ServerConfiguration.DefaultHttpsPort;
|
HttpsPort = ServerConfiguration.DefaultHttpsPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonSerializer = new JsonSerializer(FileSystemManager);
|
JsonSerializer = new JsonSerializer();
|
||||||
|
|
||||||
if (Plugins != null)
|
if (Plugins != null)
|
||||||
{
|
{
|
||||||
|
@ -1007,7 +1007,7 @@ namespace Emby.Server.Implementations
|
||||||
{
|
{
|
||||||
string dir = Path.Combine(ApplicationPaths.PluginsPath, args.Argument.name);
|
string dir = Path.Combine(ApplicationPaths.PluginsPath, args.Argument.name);
|
||||||
var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.AllDirectories)
|
var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.AllDirectories)
|
||||||
.Select(x => Assembly.LoadFrom(x))
|
.Select(Assembly.LoadFrom)
|
||||||
.SelectMany(x => x.ExportedTypes)
|
.SelectMany(x => x.ExportedTypes)
|
||||||
.Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && !x.IsGenericType)
|
.Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && !x.IsGenericType)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
@ -1707,29 +1707,6 @@ namespace Emby.Server.Implementations
|
||||||
_plugins = list.ToArray();
|
_plugins = list.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This returns localhost in the case of no external dns, and the hostname if the
|
|
||||||
/// dns is prefixed with a valid Uri prefix.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="externalDns">The external dns prefix to get the hostname of.</param>
|
|
||||||
/// <returns>The hostname in <paramref name="externalDns"/>.</returns>
|
|
||||||
private static string GetHostnameFromExternalDns(string externalDns)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(externalDns))
|
|
||||||
{
|
|
||||||
return "localhost";
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return new Uri(externalDns).Host;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return externalDns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void LaunchUrl(string url)
|
public virtual void LaunchUrl(string url)
|
||||||
{
|
{
|
||||||
if (!CanLaunchWebBrowser)
|
if (!CanLaunchWebBrowser)
|
||||||
|
|
|
@ -35,14 +35,6 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetUserDistinctValue(User user)
|
|
||||||
{
|
|
||||||
var channels = user.Policy.EnabledChannels
|
|
||||||
.OrderBy(i => i);
|
|
||||||
|
|
||||||
return string.Join("|", channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CleanDatabase(CancellationToken cancellationToken)
|
private void CleanDatabase(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var installedChannelIds = ((ChannelManager)_channelManager).GetInstalledChannelIds();
|
var installedChannelIds = ((ChannelManager)_channelManager).GetInstalledChannelIds();
|
||||||
|
@ -75,19 +67,23 @@ namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
_libraryManager.DeleteItem(item, new DeleteOptions
|
_libraryManager.DeleteItem(
|
||||||
{
|
item,
|
||||||
DeleteFileLocation = false
|
new DeleteOptions
|
||||||
|
{
|
||||||
}, false);
|
DeleteFileLocation = false
|
||||||
|
},
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, delete the channel itself
|
// Finally, delete the channel itself
|
||||||
_libraryManager.DeleteItem(channel, new DeleteOptions
|
_libraryManager.DeleteItem(
|
||||||
{
|
channel,
|
||||||
DeleteFileLocation = false
|
new DeleteOptions
|
||||||
|
{
|
||||||
}, false);
|
DeleteFileLocation = false
|
||||||
|
},
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,18 +28,28 @@ namespace Emby.Server.Implementations.Channels
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string Name => "Refresh Channels";
|
public string Name => "Refresh Channels";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string Description => "Refreshes internet channel information.";
|
public string Description => "Refreshes internet channel information.";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string Category => "Internet Channels";
|
public string Category => "Internet Channels";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool IsHidden => ((ChannelManager)_channelManager).Channels.Length == 0;
|
public bool IsHidden => ((ChannelManager)_channelManager).Channels.Length == 0;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool IsEnabled => true;
|
public bool IsEnabled => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool IsLogged => true;
|
public bool IsLogged => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Key => "RefreshInternetChannels";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
var manager = (ChannelManager)_channelManager;
|
var manager = (ChannelManager)_channelManager;
|
||||||
|
@ -50,18 +60,18 @@ namespace Emby.Server.Implementations.Channels
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Creates the triggers that define when the task will run
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
{
|
{
|
||||||
return new[] {
|
return new[]
|
||||||
|
{
|
||||||
|
|
||||||
// Every so often
|
// Every so often
|
||||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
|
new TaskTriggerInfo
|
||||||
|
{
|
||||||
|
Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Key => "RefreshInternetChannels";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
#pragma warning disable SA1600
|
#pragma warning disable SA1600
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Emby.Server.Implementations.Images;
|
using Emby.Server.Implementations.Images;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Emby.Server.Implementations.AppBase;
|
using Emby.Server.Implementations.AppBase;
|
||||||
|
|
|
@ -243,7 +243,7 @@ namespace Emby.Server.Implementations.Devices
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var fs = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
await stream.CopyToAsync(fs).ConfigureAwait(false);
|
await stream.CopyToAsync(fs).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,11 @@
|
||||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
|
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.0" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.1" />
|
||||||
<PackageReference Include="Mono.Nat" Version="2.0.0" />
|
<PackageReference Include="Mono.Nat" Version="2.0.0" />
|
||||||
<PackageReference Include="ServiceStack.Text.Core" Version="5.7.0" />
|
<PackageReference Include="ServiceStack.Text.Core" Version="5.8.0" />
|
||||||
<PackageReference Include="sharpcompress" Version="0.24.0" />
|
<PackageReference Include="sharpcompress" Version="0.24.0" />
|
||||||
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
|
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
|
||||||
<PackageReference Include="System.Interactive.Async" Version="4.0.0" />
|
<PackageReference Include="System.Interactive.Async" Version="4.0.0" />
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
#pragma warning disable SA1600
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Controller;
|
|
||||||
using MediaBrowser.Controller.Configuration;
|
|
||||||
using MediaBrowser.Controller.LiveTv;
|
|
||||||
using MediaBrowser.Controller.Plugins;
|
|
||||||
using MediaBrowser.Controller.Session;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
using MediaBrowser.Model.Tasks;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
|
||||||
{
|
|
||||||
public class AutomaticRestartEntryPoint : IServerEntryPoint
|
|
||||||
{
|
|
||||||
private readonly IServerApplicationHost _appHost;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private readonly ITaskManager _iTaskManager;
|
|
||||||
private readonly ISessionManager _sessionManager;
|
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
private readonly ILiveTvManager _liveTvManager;
|
|
||||||
|
|
||||||
private Timer _timer;
|
|
||||||
|
|
||||||
public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager)
|
|
||||||
{
|
|
||||||
_appHost = appHost;
|
|
||||||
_logger = logger;
|
|
||||||
_iTaskManager = iTaskManager;
|
|
||||||
_sessionManager = sessionManager;
|
|
||||||
_config = config;
|
|
||||||
_liveTvManager = liveTvManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task RunAsync()
|
|
||||||
{
|
|
||||||
if (_appHost.CanSelfRestart)
|
|
||||||
{
|
|
||||||
_appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _appHost_HasPendingRestartChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
DisposeTimer();
|
|
||||||
|
|
||||||
if (_appHost.HasPendingRestart)
|
|
||||||
{
|
|
||||||
_timer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(15));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void TimerCallback(object state)
|
|
||||||
{
|
|
||||||
if (_config.Configuration.EnableAutomaticRestart)
|
|
||||||
{
|
|
||||||
var isIdle = await IsIdle().ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (isIdle)
|
|
||||||
{
|
|
||||||
DisposeTimer();
|
|
||||||
|
|
||||||
_logger.LogInformation("Automatically restarting the system because it is idle and a restart is required.");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_appHost.Restart();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error restarting server");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> IsIdle()
|
|
||||||
{
|
|
||||||
if (_iTaskManager.ScheduledTasks.Any(i => i.State != TaskState.Idle))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_liveTvManager.Services.Count == 1)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var timers = await _liveTvManager.GetTimers(new TimerQuery(), CancellationToken.None).ConfigureAwait(false);
|
|
||||||
if (timers.Items.Any(i => i.Status == RecordingStatus.InProgress))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error getting timers");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
|
||||||
|
|
||||||
return !_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_appHost.HasPendingRestartChanged -= _appHost_HasPendingRestartChanged;
|
|
||||||
|
|
||||||
DisposeTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DisposeTimer()
|
|
||||||
{
|
|
||||||
if (_timer != null)
|
|
||||||
{
|
|
||||||
_timer.Dispose();
|
|
||||||
_timer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,7 +16,6 @@ using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Server.Implementations.Udp;
|
using Emby.Server.Implementations.Udp;
|
||||||
|
|
|
@ -197,7 +197,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
if (File.Exists(responseCachePath)
|
if (File.Exists(responseCachePath)
|
||||||
&& _fileSystem.GetLastWriteTimeUtc(responseCachePath).Add(cacheLength) > DateTime.UtcNow)
|
&& _fileSystem.GetLastWriteTimeUtc(responseCachePath).Add(cacheLength) > DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
var stream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read, true);
|
var stream = new FileStream(responseCachePath, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, true);
|
||||||
|
|
||||||
return new HttpResponseInfo
|
return new HttpResponseInfo
|
||||||
{
|
{
|
||||||
|
@ -220,7 +220,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
FileMode.Create,
|
FileMode.Create,
|
||||||
FileAccess.Write,
|
FileAccess.Write,
|
||||||
FileShare.None,
|
FileShare.None,
|
||||||
StreamDefaults.DefaultFileStreamBufferSize,
|
IODefaults.FileStreamBufferSize,
|
||||||
true))
|
true))
|
||||||
{
|
{
|
||||||
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
|
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
SetRangeValues();
|
SetRangeValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileShare = FileShareMode.Read;
|
FileShare = FileShare.Read;
|
||||||
Cookies = new List<Cookie>();
|
Cookies = new List<Cookie>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
public List<Cookie> Cookies { get; private set; }
|
public List<Cookie> Cookies { get; private set; }
|
||||||
|
|
||||||
public FileShareMode FileShare { get; set; }
|
public FileShare FileShare { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the options.
|
/// Gets the options.
|
||||||
|
@ -222,17 +222,17 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task TransmitFile(Stream stream, string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
public async Task TransmitFile(Stream stream, string path, long offset, long count, FileShare fileShare, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var fileOpenOptions = FileOpenOptions.SequentialScan;
|
var fileOptions = FileOptions.SequentialScan;
|
||||||
|
|
||||||
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
|
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
|
||||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
fileOpenOptions |= FileOpenOptions.Asynchronous;
|
fileOptions |= FileOptions.Asynchronous;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var fs = _fileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, fileShareMode, fileOpenOptions))
|
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, fileShare, IODefaults.FileStreamBufferSize, fileOptions))
|
||||||
{
|
{
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
|
@ -245,7 +245,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await fs.CopyToAsync(stream, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false);
|
await fs.CopyToAsync(stream, IODefaults.CopyToBufferSize, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,7 +440,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
public Task<object> GetStaticFileResult(IRequest requestContext,
|
public Task<object> GetStaticFileResult(IRequest requestContext,
|
||||||
string path,
|
string path,
|
||||||
FileShareMode fileShare = FileShareMode.Read)
|
FileShare fileShare = FileShare.Read)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
|
@ -464,7 +464,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
throw new ArgumentException("Path can't be empty.", nameof(options));
|
throw new ArgumentException("Path can't be empty.", nameof(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileShare != FileShareMode.Read && fileShare != FileShareMode.ReadWrite)
|
if (fileShare != FileShare.Read && fileShare != FileShare.ReadWrite)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("FileShare must be either Read or ReadWrite");
|
throw new ArgumentException("FileShare must be either Read or ReadWrite");
|
||||||
}
|
}
|
||||||
|
@ -492,9 +492,9 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
/// <param name="path">The path.</param>
|
/// <param name="path">The path.</param>
|
||||||
/// <param name="fileShare">The file share.</param>
|
/// <param name="fileShare">The file share.</param>
|
||||||
/// <returns>Stream.</returns>
|
/// <returns>Stream.</returns>
|
||||||
private Stream GetFileStream(string path, FileShareMode fileShare)
|
private Stream GetFileStream(string path, FileShare fileShare)
|
||||||
{
|
{
|
||||||
return _fileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, fileShare);
|
return new FileStream(path, FileMode.Open, FileAccess.Read, fileShare);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<object> GetStaticResult(IRequest requestContext,
|
public Task<object> GetStaticResult(IRequest requestContext,
|
||||||
|
|
|
@ -365,87 +365,6 @@ namespace Emby.Server.Implementations.IO
|
||||||
return GetLastWriteTimeUtc(GetFileSystemInfo(path));
|
return GetLastWriteTimeUtc(GetFileSystemInfo(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the file stream.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path.</param>
|
|
||||||
/// <param name="mode">The mode.</param>
|
|
||||||
/// <param name="access">The access.</param>
|
|
||||||
/// <param name="share">The share.</param>
|
|
||||||
/// <param name="isAsync">if set to <c>true</c> [is asynchronous].</param>
|
|
||||||
/// <returns>FileStream.</returns>
|
|
||||||
public virtual Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, bool isAsync = false)
|
|
||||||
{
|
|
||||||
if (isAsync)
|
|
||||||
{
|
|
||||||
return GetFileStream(path, mode, access, share, FileOpenOptions.Asynchronous);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetFileStream(path, mode, access, share, FileOpenOptions.None);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, FileOpenOptions fileOpenOptions)
|
|
||||||
=> new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 4096, GetFileOptions(fileOpenOptions));
|
|
||||||
|
|
||||||
private static FileOptions GetFileOptions(FileOpenOptions mode)
|
|
||||||
{
|
|
||||||
var val = (int)mode;
|
|
||||||
return (FileOptions)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FileMode GetFileMode(FileOpenMode mode)
|
|
||||||
{
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
//case FileOpenMode.Append:
|
|
||||||
// return FileMode.Append;
|
|
||||||
case FileOpenMode.Create:
|
|
||||||
return FileMode.Create;
|
|
||||||
case FileOpenMode.CreateNew:
|
|
||||||
return FileMode.CreateNew;
|
|
||||||
case FileOpenMode.Open:
|
|
||||||
return FileMode.Open;
|
|
||||||
case FileOpenMode.OpenOrCreate:
|
|
||||||
return FileMode.OpenOrCreate;
|
|
||||||
//case FileOpenMode.Truncate:
|
|
||||||
// return FileMode.Truncate;
|
|
||||||
default:
|
|
||||||
throw new Exception("Unrecognized FileOpenMode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FileAccess GetFileAccess(FileAccessMode mode)
|
|
||||||
{
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
//case FileAccessMode.ReadWrite:
|
|
||||||
// return FileAccess.ReadWrite;
|
|
||||||
case FileAccessMode.Write:
|
|
||||||
return FileAccess.Write;
|
|
||||||
case FileAccessMode.Read:
|
|
||||||
return FileAccess.Read;
|
|
||||||
default:
|
|
||||||
throw new Exception("Unrecognized FileAccessMode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FileShare GetFileShare(FileShareMode mode)
|
|
||||||
{
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case FileShareMode.ReadWrite:
|
|
||||||
return FileShare.ReadWrite;
|
|
||||||
case FileShareMode.Write:
|
|
||||||
return FileShare.Write;
|
|
||||||
case FileShareMode.Read:
|
|
||||||
return FileShare.Read;
|
|
||||||
case FileShareMode.None:
|
|
||||||
return FileShare.None;
|
|
||||||
default:
|
|
||||||
throw new Exception("Unrecognized FileShareMode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SetHidden(string path, bool isHidden)
|
public virtual void SetHidden(string path, bool isHidden)
|
||||||
{
|
{
|
||||||
if (OperatingSystem.Id != OperatingSystemId.Windows)
|
if (OperatingSystem.Id != OperatingSystemId.Windows)
|
||||||
|
|
|
@ -710,10 +710,10 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the root media folder
|
/// Creates the root media folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>AggregateFolder.</returns>
|
/// <returns>AggregateFolder.</returns>
|
||||||
/// <exception cref="InvalidOperationException">Cannot create the root folder until plugins have loaded</exception>
|
/// <exception cref="InvalidOperationException">Cannot create the root folder until plugins have loaded.</exception>
|
||||||
public AggregateFolder CreateRootFolder()
|
public AggregateFolder CreateRootFolder()
|
||||||
{
|
{
|
||||||
var rootFolderPath = ConfigurationManager.ApplicationPaths.RootFolderPath;
|
var rootFolderPath = ConfigurationManager.ApplicationPaths.RootFolderPath;
|
||||||
|
@ -824,7 +824,6 @@ namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
// If this returns multiple items it could be tricky figuring out which one is correct.
|
// If this returns multiple items it could be tricky figuring out which one is correct.
|
||||||
// In most cases, the newest one will be and the others obsolete but not yet cleaned up
|
// In most cases, the newest one will be and the others obsolete but not yet cleaned up
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(path));
|
throw new ArgumentNullException(nameof(path));
|
||||||
|
@ -844,7 +843,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Person
|
/// Gets the person.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <returns>Task{Person}.</returns>
|
/// <returns>Task{Person}.</returns>
|
||||||
|
@ -854,7 +853,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Studio
|
/// Gets the studio.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <returns>Task{Studio}.</returns>
|
/// <returns>Task{Studio}.</returns>
|
||||||
|
@ -879,7 +878,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Genre
|
/// Gets the genre.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <returns>Task{Genre}.</returns>
|
/// <returns>Task{Genre}.</returns>
|
||||||
|
@ -889,7 +888,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the genre.
|
/// Gets the music genre.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <returns>Task{MusicGenre}.</returns>
|
/// <returns>Task{MusicGenre}.</returns>
|
||||||
|
@ -899,7 +898,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Year
|
/// Gets the year.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
/// <returns>Task{Year}.</returns>
|
/// <returns>Task{Year}.</returns>
|
||||||
|
@ -1076,9 +1075,9 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
var innerProgress = new ActionableProgress<double>();
|
var innerProgress = new ActionableProgress<double>();
|
||||||
|
|
||||||
innerProgress.RegisterAction(pct => progress.Report(pct * .96));
|
innerProgress.RegisterAction(pct => progress.Report(pct * pct * 0.96));
|
||||||
|
|
||||||
// Now validate the entire media library
|
// Validate the entire media library
|
||||||
await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), recursive: true).ConfigureAwait(false);
|
await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), recursive: true).ConfigureAwait(false);
|
||||||
|
|
||||||
progress.Report(96);
|
progress.Report(96);
|
||||||
|
@ -1087,7 +1086,6 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
innerProgress.RegisterAction(pct => progress.Report(96 + (pct * .04)));
|
innerProgress.RegisterAction(pct => progress.Report(96 + (pct * .04)));
|
||||||
|
|
||||||
// Run post-scan tasks
|
|
||||||
await RunPostScanTasks(innerProgress, cancellationToken).ConfigureAwait(false);
|
await RunPostScanTasks(innerProgress, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
progress.Report(100);
|
progress.Report(100);
|
||||||
|
@ -1138,7 +1136,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error running postscan task");
|
_logger.LogError(ex, "Error running post-scan task");
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
|
|
@ -291,10 +291,11 @@ namespace Emby.Server.Implementations.Library
|
||||||
&& authenticationProvider != null
|
&& authenticationProvider != null
|
||||||
&& !(authenticationProvider is DefaultAuthenticationProvider))
|
&& !(authenticationProvider is DefaultAuthenticationProvider))
|
||||||
{
|
{
|
||||||
// We should trust the user that the authprovider says, not what was typed
|
// Trust the username returned by the authentication provider
|
||||||
username = updatedUsername;
|
username = updatedUsername;
|
||||||
|
|
||||||
// Search the database for the user again; the authprovider might have created it
|
// Search the database for the user again
|
||||||
|
// the authentication provider might have created it
|
||||||
user = Users
|
user = Users
|
||||||
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
@ -667,7 +668,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
throw new ArgumentException("Invalid username", nameof(newName));
|
throw new ArgumentException("Invalid username", nameof(newName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.Name.Equals(newName, StringComparison.OrdinalIgnoreCase))
|
if (user.Name.Equals(newName, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("The new and old names must be different.");
|
throw new ArgumentException("The new and old names must be different.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
private readonly IStreamHelper _streamHelper;
|
private readonly IStreamHelper _streamHelper;
|
||||||
|
|
||||||
public DirectRecorder(ILogger logger, IHttpClient httpClient, IFileSystem fileSystem, IStreamHelper streamHelper)
|
public DirectRecorder(ILogger logger, IHttpClient httpClient, IStreamHelper streamHelper)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_fileSystem = fileSystem;
|
|
||||||
_streamHelper = streamHelper;
|
_streamHelper = streamHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +43,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(targetFile));
|
Directory.CreateDirectory(Path.GetDirectoryName(targetFile));
|
||||||
|
|
||||||
using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
using (var output = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
onStarted();
|
onStarted();
|
||||||
|
|
||||||
|
@ -81,7 +79,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(targetFile));
|
Directory.CreateDirectory(Path.GetDirectoryName(targetFile));
|
||||||
|
|
||||||
using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
using (var output = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
onStarted();
|
onStarted();
|
||||||
|
|
||||||
|
|
|
@ -427,7 +427,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
foreach (NameValuePair mapping in mappings)
|
foreach (NameValuePair mapping in mappings)
|
||||||
{
|
{
|
||||||
if (StringHelper.EqualsIgnoreCase(mapping.Name, channelId))
|
if (string.Equals(mapping.Name, channelId, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return mapping.Value;
|
return mapping.Value;
|
||||||
}
|
}
|
||||||
|
@ -1664,10 +1664,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
if (mediaSource.RequiresLooping || !(mediaSource.Container ?? string.Empty).EndsWith("ts", StringComparison.OrdinalIgnoreCase) || (mediaSource.Protocol != MediaProtocol.File && mediaSource.Protocol != MediaProtocol.Http))
|
if (mediaSource.RequiresLooping || !(mediaSource.Container ?? string.Empty).EndsWith("ts", StringComparison.OrdinalIgnoreCase) || (mediaSource.Protocol != MediaProtocol.File && mediaSource.Protocol != MediaProtocol.Http))
|
||||||
{
|
{
|
||||||
return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _processFactory, _config);
|
return new EncodedRecorder(_logger, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _processFactory, _config);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DirectRecorder(_logger, _httpClient, _fileSystem, _streamHelper);
|
return new DirectRecorder(_logger, _httpClient, _streamHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSuccessfulRecording(TimerInfo timer, string path)
|
private void OnSuccessfulRecording(TimerInfo timer, string path)
|
||||||
|
@ -1888,7 +1888,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var stream = _fileSystem.GetFileStream(nfoPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
using (var stream = new FileStream(nfoPath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
var settings = new XmlWriterSettings
|
var settings = new XmlWriterSettings
|
||||||
{
|
{
|
||||||
|
@ -1952,7 +1952,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var stream = _fileSystem.GetFileStream(nfoPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
using (var stream = new FileStream(nfoPath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
var settings = new XmlWriterSettings
|
var settings = new XmlWriterSettings
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -14,7 +13,6 @@ using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Diagnostics;
|
using MediaBrowser.Model.Diagnostics;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -24,7 +22,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
public class EncodedRecorder : IRecorder
|
public class EncodedRecorder : IRecorder
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
private readonly IServerApplicationPaths _appPaths;
|
private readonly IServerApplicationPaths _appPaths;
|
||||||
private bool _hasExited;
|
private bool _hasExited;
|
||||||
|
@ -38,7 +35,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
public EncodedRecorder(
|
public EncodedRecorder(
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
IFileSystem fileSystem,
|
|
||||||
IMediaEncoder mediaEncoder,
|
IMediaEncoder mediaEncoder,
|
||||||
IServerApplicationPaths appPaths,
|
IServerApplicationPaths appPaths,
|
||||||
IJsonSerializer json,
|
IJsonSerializer json,
|
||||||
|
@ -46,7 +42,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
IServerConfigurationManager config)
|
IServerConfigurationManager config)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_fileSystem = fileSystem;
|
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
_appPaths = appPaths;
|
_appPaths = appPaths;
|
||||||
_json = json;
|
_json = json;
|
||||||
|
@ -107,7 +102,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));
|
||||||
|
|
||||||
// FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
|
// FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
|
||||||
_logFileStream = _fileSystem.GetFileStream(logFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true);
|
_logFileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true);
|
||||||
|
|
||||||
var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(_json.SerializeToString(mediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
|
var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(_json.SerializeToString(mediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
|
||||||
_logFileStream.Write(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length);
|
_logFileStream.Write(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length);
|
||||||
|
|
|
@ -96,7 +96,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
FileMode.Open,
|
FileMode.Open,
|
||||||
FileAccess.Read,
|
FileAccess.Read,
|
||||||
FileShare.ReadWrite,
|
FileShare.ReadWrite,
|
||||||
StreamDefaults.DefaultFileStreamBufferSize,
|
IODefaults.FileStreamBufferSize,
|
||||||
allowAsyncFileRead ? FileOptions.SequentialScan | FileOptions.Asynchronous : FileOptions.SequentialScan);
|
allowAsyncFileRead ? FileOptions.SequentialScan | FileOptions.Asynchronous : FileOptions.SequentialScan);
|
||||||
|
|
||||||
public Task DeleteTempFiles()
|
public Task DeleteTempFiles()
|
||||||
|
@ -199,7 +199,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
await StreamHelper.CopyToAsync(
|
await StreamHelper.CopyToAsync(
|
||||||
inputStream,
|
inputStream,
|
||||||
stream,
|
stream,
|
||||||
StreamDefaults.DefaultCopyToBufferSize,
|
IODefaults.CopyToBufferSize,
|
||||||
emptyReadLimit,
|
emptyReadLimit,
|
||||||
cancellationToken).ConfigureAwait(false);
|
cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
|
|
|
@ -127,12 +127,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
Logger.LogInformation("Beginning {0} stream to {1}", GetType().Name, TempFilePath);
|
Logger.LogInformation("Beginning {0} stream to {1}", GetType().Name, TempFilePath);
|
||||||
using (response)
|
using (response)
|
||||||
using (var stream = response.Content)
|
using (var stream = response.Content)
|
||||||
using (var fileStream = FileSystem.GetFileStream(TempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.None))
|
using (var fileStream = new FileStream(TempFilePath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
await StreamHelper.CopyToAsync(
|
await StreamHelper.CopyToAsync(
|
||||||
stream,
|
stream,
|
||||||
fileStream,
|
fileStream,
|
||||||
StreamDefaults.DefaultCopyToBufferSize,
|
IODefaults.CopyToBufferSize,
|
||||||
() => Resolve(openTaskCompletionSource),
|
() => Resolve(openTaskCompletionSource),
|
||||||
cancellationToken).ConfigureAwait(false);
|
cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"Channels": "القنوات",
|
"Channels": "القنوات",
|
||||||
"ChapterNameValue": "الباب {0}",
|
"ChapterNameValue": "الباب {0}",
|
||||||
"Collections": "مجموعات",
|
"Collections": "مجموعات",
|
||||||
"DeviceOfflineWithName": "تم قطع الاتصال بـ{0}",
|
"DeviceOfflineWithName": "تم قطع اتصال {0}",
|
||||||
"DeviceOnlineWithName": "{0} متصل",
|
"DeviceOnlineWithName": "{0} متصل",
|
||||||
"FailedLoginAttemptWithUserName": "عملية تسجيل الدخول فشلت من {0}",
|
"FailedLoginAttemptWithUserName": "عملية تسجيل الدخول فشلت من {0}",
|
||||||
"Favorites": "التفضيلات",
|
"Favorites": "التفضيلات",
|
||||||
|
@ -75,8 +75,8 @@
|
||||||
"Songs": "الأغاني",
|
"Songs": "الأغاني",
|
||||||
"StartupEmbyServerIsLoading": "سيرفر Jellyfin قيد التشغيل . الرجاء المحاولة بعد قليل.",
|
"StartupEmbyServerIsLoading": "سيرفر Jellyfin قيد التشغيل . الرجاء المحاولة بعد قليل.",
|
||||||
"SubtitleDownloadFailureForItem": "عملية إنزال الترجمة فشلت لـ{0}",
|
"SubtitleDownloadFailureForItem": "عملية إنزال الترجمة فشلت لـ{0}",
|
||||||
"SubtitleDownloadFailureFromForItem": "الترجمات فشلت في التحميل من {0} لـ {1}",
|
"SubtitleDownloadFailureFromForItem": "الترجمات فشلت في التحميل من {0} الى {1}",
|
||||||
"SubtitlesDownloadedForItem": "تم تحميل الترجمات لـ {0}",
|
"SubtitlesDownloadedForItem": "تم تحميل الترجمات الى {0}",
|
||||||
"Sync": "مزامنة",
|
"Sync": "مزامنة",
|
||||||
"System": "النظام",
|
"System": "النظام",
|
||||||
"TvShows": "البرامج التلفزيونية",
|
"TvShows": "البرامج التلفزيونية",
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
"UserOfflineFromDevice": "تم قطع اتصال {0} من {1}",
|
"UserOfflineFromDevice": "تم قطع اتصال {0} من {1}",
|
||||||
"UserOnlineFromDevice": "{0} متصل عبر {1}",
|
"UserOnlineFromDevice": "{0} متصل عبر {1}",
|
||||||
"UserPasswordChangedWithName": "تم تغيير كلمة السر للمستخدم {0}",
|
"UserPasswordChangedWithName": "تم تغيير كلمة السر للمستخدم {0}",
|
||||||
"UserPolicyUpdatedWithName": "سياسة المستخدمين تم تحديثها لـ {0}",
|
"UserPolicyUpdatedWithName": "تم تحديث سياسة المستخدم {0}",
|
||||||
"UserStartedPlayingItemWithValues": "قام {0} ببدء تشغيل {1} على {2}",
|
"UserStartedPlayingItemWithValues": "قام {0} ببدء تشغيل {1} على {2}",
|
||||||
"UserStoppedPlayingItemWithValues": "قام {0} بإيقاف تشغيل {1} على {2}",
|
"UserStoppedPlayingItemWithValues": "قام {0} بإيقاف تشغيل {1} على {2}",
|
||||||
"ValueHasBeenAddedToLibrary": "{0} تم اضافتها الى مكتبة الوسائط",
|
"ValueHasBeenAddedToLibrary": "{0} تم اضافتها الى مكتبة الوسائط",
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
"AppDeviceValues": "Aplicació: {0}, Dispositiu: {1}",
|
"AppDeviceValues": "Aplicació: {0}, Dispositiu: {1}",
|
||||||
"Application": "Aplicació",
|
"Application": "Aplicació",
|
||||||
"Artists": "Artistes",
|
"Artists": "Artistes",
|
||||||
"AuthenticationSucceededWithUserName": "{0} s'ha autenticat correctament",
|
"AuthenticationSucceededWithUserName": "{0} s'ha autentificat correctament",
|
||||||
"Books": "Llibres",
|
"Books": "Llibres",
|
||||||
"CameraImageUploadedFrom": "Una nova imatge de càmera ha sigut pujada des de {0}",
|
"CameraImageUploadedFrom": "Una nova imatge de la càmera ha sigut pujada des de {0}",
|
||||||
"Channels": "Canals",
|
"Channels": "Canals",
|
||||||
"ChapterNameValue": "Episodi {0}",
|
"ChapterNameValue": "Episodi {0}",
|
||||||
"Collections": "Col·leccions",
|
"Collections": "Col·leccions",
|
||||||
|
|
95
Emby.Server.Implementations/Localization/Core/fil.json
Normal file
95
Emby.Server.Implementations/Localization/Core/fil.json
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
"VersionNumber": "Bersyon {0}",
|
||||||
|
"ValueSpecialEpisodeName": "Espesyal - {0}",
|
||||||
|
"ValueHasBeenAddedToLibrary": "Naidagdag na ang {0} sa iyong media library",
|
||||||
|
"UserStoppedPlayingItemWithValues": "Natapos ni {0} ang {1} sa {2}",
|
||||||
|
"UserStartedPlayingItemWithValues": "Si {0} ay nagplaplay ng {1} sa {2}",
|
||||||
|
"UserPolicyUpdatedWithName": "Ang user policy ay naiupdate para kay {0}",
|
||||||
|
"UserPasswordChangedWithName": "Napalitan na ang password ni {0}",
|
||||||
|
"UserOnlineFromDevice": "Si {0} ay nakakonekta galing sa {1}",
|
||||||
|
"UserOfflineFromDevice": "Si {0} ay nadiskonekta galing sa {1}",
|
||||||
|
"UserLockedOutWithName": "Si {0} ay nalock out",
|
||||||
|
"UserDownloadingItemWithValues": "Nagdadownload si {0} ng {1}",
|
||||||
|
"UserDeletedWithName": "Natanggal na is user {0}",
|
||||||
|
"UserCreatedWithName": "Nagawa na si user {0}",
|
||||||
|
"User": "User",
|
||||||
|
"TvShows": "Pelikula",
|
||||||
|
"System": "Sistema",
|
||||||
|
"Sync": "Pag-sync",
|
||||||
|
"SubtitlesDownloadedForItem": "Naidownload na ang subtitles {0}",
|
||||||
|
"SubtitleDownloadFailureFromForItem": "Hindi naidownload ang subtitles {0} para sa {1}",
|
||||||
|
"StartupEmbyServerIsLoading": "Nagloload ang Jellyfin Server. Sandaling maghintay.",
|
||||||
|
"Songs": "Kanta",
|
||||||
|
"Shows": "Pelikula",
|
||||||
|
"ServerNameNeedsToBeRestarted": "Kailangan irestart ang {0}",
|
||||||
|
"ScheduledTaskStartedWithName": "Nagsimula na ang {0}",
|
||||||
|
"ScheduledTaskFailedWithName": "Hindi gumana and {0}",
|
||||||
|
"ProviderValue": "Ang provider ay {0}",
|
||||||
|
"PluginUpdatedWithName": "Naiupdate na ang {0}",
|
||||||
|
"PluginUninstalledWithName": "Naiuninstall na ang {0}",
|
||||||
|
"PluginInstalledWithName": "Nainstall na ang {0}",
|
||||||
|
"Plugin": "Plugin",
|
||||||
|
"Playlists": "Playlists",
|
||||||
|
"Photos": "Larawan",
|
||||||
|
"NotificationOptionVideoPlaybackStopped": "Huminto na ang pelikula",
|
||||||
|
"NotificationOptionVideoPlayback": "Nagsimula na ang pelikula",
|
||||||
|
"NotificationOptionUserLockedOut": "Nakalock out ang user",
|
||||||
|
"NotificationOptionTaskFailed": "Hindi gumana ang scheduled task",
|
||||||
|
"NotificationOptionServerRestartRequired": "Kailangan irestart ang server",
|
||||||
|
"NotificationOptionPluginUpdateInstalled": "Naiupdate na ang plugin",
|
||||||
|
"NotificationOptionPluginUninstalled": "Naiuninstall na ang plugin",
|
||||||
|
"NotificationOptionPluginInstalled": "Nainstall na ang plugin",
|
||||||
|
"NotificationOptionPluginError": "Hindi gumagana ang plugin",
|
||||||
|
"NotificationOptionNewLibraryContent": "May bagong content na naidagdag",
|
||||||
|
"NotificationOptionInstallationFailed": "Hindi nainstall ng mabuti",
|
||||||
|
"NotificationOptionCameraImageUploaded": "Naiupload na ang picture",
|
||||||
|
"NotificationOptionAudioPlaybackStopped": "Huminto na ang patugtog",
|
||||||
|
"NotificationOptionAudioPlayback": "Nagsimula na ang patugtog",
|
||||||
|
"NotificationOptionApplicationUpdateInstalled": "Naiupdate na ang aplikasyon",
|
||||||
|
"NotificationOptionApplicationUpdateAvailable": "May bagong update ang aplikasyon",
|
||||||
|
"NewVersionIsAvailable": "May bagong version ng Jellyfin Server na pwede idownload.",
|
||||||
|
"NameSeasonUnknown": "Hindi alam ang season",
|
||||||
|
"NameSeasonNumber": "Season {0}",
|
||||||
|
"NameInstallFailed": "Hindi nainstall ang {0}",
|
||||||
|
"MusicVideos": "Music video",
|
||||||
|
"Music": "Kanta",
|
||||||
|
"Movies": "Pelikula",
|
||||||
|
"MixedContent": "Halo-halong content",
|
||||||
|
"MessageServerConfigurationUpdated": "Naiupdate na ang server configuration",
|
||||||
|
"MessageNamedServerConfigurationUpdatedWithValue": "Naiupdate na ang server configuration section {0}",
|
||||||
|
"MessageApplicationUpdatedTo": "Ang Jellyfin Server ay naiupdate to {0}",
|
||||||
|
"MessageApplicationUpdated": "Naiupdate na ang Jellyfin Server",
|
||||||
|
"Latest": "Pinakabago",
|
||||||
|
"LabelRunningTimeValue": "Oras: {0}",
|
||||||
|
"LabelIpAddressValue": "Ang IP Address ay {0}",
|
||||||
|
"ItemRemovedWithName": "Naitanggal ang {0} sa library",
|
||||||
|
"ItemAddedWithName": "Naidagdag ang {0} sa library",
|
||||||
|
"Inherit": "Manahin",
|
||||||
|
"HeaderRecordingGroups": "Pagtatalang Grupo",
|
||||||
|
"HeaderNextUp": "Susunod",
|
||||||
|
"HeaderLiveTV": "Live TV",
|
||||||
|
"HeaderFavoriteSongs": "Paboritong Kanta",
|
||||||
|
"HeaderFavoriteShows": "Paboritong Pelikula",
|
||||||
|
"HeaderFavoriteEpisodes": "Paboritong Episodes",
|
||||||
|
"HeaderFavoriteArtists": "Paboritong Artista",
|
||||||
|
"HeaderFavoriteAlbums": "Paboritong Albums",
|
||||||
|
"HeaderContinueWatching": "Ituloy Manood",
|
||||||
|
"HeaderCameraUploads": "Camera Uploads",
|
||||||
|
"HeaderAlbumArtists": "Artista ng Album",
|
||||||
|
"Genres": "Kategorya",
|
||||||
|
"Folders": "Folders",
|
||||||
|
"Favorites": "Paborito",
|
||||||
|
"FailedLoginAttemptWithUserName": "maling login galing {0}",
|
||||||
|
"DeviceOnlineWithName": "nakakonekta si {0}",
|
||||||
|
"DeviceOfflineWithName": "nadiskonekta si {0}",
|
||||||
|
"Collections": "Koleksyon",
|
||||||
|
"ChapterNameValue": "Kabanata {0}",
|
||||||
|
"Channels": "Channel",
|
||||||
|
"CameraImageUploadedFrom": "May bagong larawan na naupload galing {0}",
|
||||||
|
"Books": "Libro",
|
||||||
|
"AuthenticationSucceededWithUserName": "{0} na patunayan",
|
||||||
|
"Artists": "Artista",
|
||||||
|
"Application": "Aplikasyon",
|
||||||
|
"AppDeviceValues": "Aplikasyon: {0}, Aparato: {1}",
|
||||||
|
"Albums": "Albums"
|
||||||
|
}
|
1
Emby.Server.Implementations/Localization/Core/gl.json
Normal file
1
Emby.Server.Implementations/Localization/Core/gl.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -6,7 +6,7 @@
|
||||||
"MessageApplicationUpdatedTo": "Jellyfin Server sudah diperbarui ke {0}",
|
"MessageApplicationUpdatedTo": "Jellyfin Server sudah diperbarui ke {0}",
|
||||||
"MessageApplicationUpdated": "Jellyfin Server sudah diperbarui",
|
"MessageApplicationUpdated": "Jellyfin Server sudah diperbarui",
|
||||||
"Latest": "Terbaru",
|
"Latest": "Terbaru",
|
||||||
"LabelIpAddressValue": "IP address: {0}",
|
"LabelIpAddressValue": "Alamat IP: {0}",
|
||||||
"ItemRemovedWithName": "{0} sudah dikeluarkan dari perpustakaan",
|
"ItemRemovedWithName": "{0} sudah dikeluarkan dari perpustakaan",
|
||||||
"ItemAddedWithName": "{0} sudah dimasukkan ke dalam perpustakaan",
|
"ItemAddedWithName": "{0} sudah dimasukkan ke dalam perpustakaan",
|
||||||
"Inherit": "Warisan",
|
"Inherit": "Warisan",
|
||||||
|
@ -28,5 +28,63 @@
|
||||||
"Collections": "Koleksi",
|
"Collections": "Koleksi",
|
||||||
"Books": "Buku",
|
"Books": "Buku",
|
||||||
"Artists": "Artis",
|
"Artists": "Artis",
|
||||||
"Application": "Aplikasi"
|
"Application": "Aplikasi",
|
||||||
|
"ChapterNameValue": "Bagian {0}",
|
||||||
|
"Channels": "Saluran",
|
||||||
|
"TvShows": "Seri TV",
|
||||||
|
"SubtitleDownloadFailureFromForItem": "Talop gagal diunduh dari {0} untuk {1}",
|
||||||
|
"StartupEmbyServerIsLoading": "Peladen Jellyfin sedang dimuat. Silakan coba kembali beberapa saat lagi.",
|
||||||
|
"Songs": "Lagu",
|
||||||
|
"Playlists": "Daftar putar",
|
||||||
|
"NotificationOptionPluginUninstalled": "Plugin dilepas",
|
||||||
|
"MusicVideos": "Video musik",
|
||||||
|
"VersionNumber": "Versi {0}",
|
||||||
|
"ValueSpecialEpisodeName": "Spesial - {0}",
|
||||||
|
"ValueHasBeenAddedToLibrary": "{0} telah ditambahkan ke pustaka media Anda",
|
||||||
|
"UserStoppedPlayingItemWithValues": "{0} telah selesai memutar {1} pada {2}",
|
||||||
|
"UserStartedPlayingItemWithValues": "{0} sedang memutar {1} pada {2}",
|
||||||
|
"UserPolicyUpdatedWithName": "Kebijakan pengguna telah diperbarui untuk {0}",
|
||||||
|
"UserPasswordChangedWithName": "Kata sandi telah diubah untuk pengguna {0}",
|
||||||
|
"UserOnlineFromDevice": "{0} sedang daring dari {1}",
|
||||||
|
"UserOfflineFromDevice": "{0} telah terputus dari {1}",
|
||||||
|
"UserLockedOutWithName": "Pengguna {0} telah dikunci",
|
||||||
|
"UserDownloadingItemWithValues": "{0} sedang mengunduh {1}",
|
||||||
|
"UserDeletedWithName": "Pengguna {0} telah dihapus",
|
||||||
|
"UserCreatedWithName": "Pengguna {0} telah dibuat",
|
||||||
|
"User": "Pengguna",
|
||||||
|
"System": "Sistem",
|
||||||
|
"Sync": "Sinkron",
|
||||||
|
"SubtitlesDownloadedForItem": "Talop telah diunduh untuk {0}",
|
||||||
|
"Shows": "Tayangan",
|
||||||
|
"ServerNameNeedsToBeRestarted": "{0} perlu dimuat ulang",
|
||||||
|
"ScheduledTaskStartedWithName": "{0} dimulai",
|
||||||
|
"ScheduledTaskFailedWithName": "{0} gagal",
|
||||||
|
"ProviderValue": "Penyedia: {0}",
|
||||||
|
"PluginUpdatedWithName": "{0} telah diperbarui",
|
||||||
|
"PluginInstalledWithName": "{0} telah dipasang",
|
||||||
|
"Plugin": "Plugin",
|
||||||
|
"Photos": "Foto",
|
||||||
|
"NotificationOptionUserLockedOut": "Pengguna terkunci",
|
||||||
|
"NotificationOptionTaskFailed": "Kegagalan tugas terjadwal",
|
||||||
|
"NotificationOptionServerRestartRequired": "Restart peladen dibutuhkan",
|
||||||
|
"NotificationOptionPluginUpdateInstalled": "Pembaruan plugin terpasang",
|
||||||
|
"NotificationOptionPluginInstalled": "Plugin terpasang",
|
||||||
|
"NotificationOptionPluginError": "Kegagalan plugin",
|
||||||
|
"NotificationOptionNewLibraryContent": "Konten baru ditambahkan",
|
||||||
|
"NotificationOptionInstallationFailed": "Kegagalan pemasangan",
|
||||||
|
"NotificationOptionCameraImageUploaded": "Gambar kamera terunggah",
|
||||||
|
"NotificationOptionApplicationUpdateInstalled": "Pembaruan aplikasi terpasang",
|
||||||
|
"NotificationOptionApplicationUpdateAvailable": "Pembaruan aplikasi tersedia",
|
||||||
|
"NewVersionIsAvailable": "Sebuah versi baru dari Peladen Jellyfin tersedia untuk diunduh.",
|
||||||
|
"NameSeasonUnknown": "Musim tak diketahui",
|
||||||
|
"NameSeasonNumber": "Musim {0}",
|
||||||
|
"NameInstallFailed": "{0} instalasi gagal",
|
||||||
|
"Music": "Musik",
|
||||||
|
"Movies": "Film",
|
||||||
|
"MessageServerConfigurationUpdated": "Konfigurasi peladen telah diperbarui",
|
||||||
|
"MessageNamedServerConfigurationUpdatedWithValue": "Konfigurasi peladen bagian {0} telah diperbarui",
|
||||||
|
"FailedLoginAttemptWithUserName": "Percobaan login gagal dari {0}",
|
||||||
|
"CameraImageUploadedFrom": "Sebuah gambar baru telah diunggah dari {0}",
|
||||||
|
"DeviceOfflineWithName": "{0} telah terputus",
|
||||||
|
"DeviceOnlineWithName": "{0} telah terhubung"
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"DeviceOfflineWithName": "{0} je prekinil povezavo",
|
"DeviceOfflineWithName": "{0} je prekinil povezavo",
|
||||||
"DeviceOnlineWithName": "{0} je povezan",
|
"DeviceOnlineWithName": "{0} je povezan",
|
||||||
"FailedLoginAttemptWithUserName": "Neuspešen poskus prijave z {0}",
|
"FailedLoginAttemptWithUserName": "Neuspešen poskus prijave z {0}",
|
||||||
"Favorites": "Priljubljeni",
|
"Favorites": "Priljubljeno",
|
||||||
"Folders": "Mape",
|
"Folders": "Mape",
|
||||||
"Genres": "Zvrsti",
|
"Genres": "Zvrsti",
|
||||||
"HeaderAlbumArtists": "Izvajalci albuma",
|
"HeaderAlbumArtists": "Izvajalci albuma",
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
"SubtitlesDownloadedForItem": "已为 {0} 下载了字幕",
|
"SubtitlesDownloadedForItem": "已为 {0} 下载了字幕",
|
||||||
"Sync": "同步",
|
"Sync": "同步",
|
||||||
"System": "系统",
|
"System": "系统",
|
||||||
"TvShows": "电视节目",
|
"TvShows": "电视剧",
|
||||||
"User": "用户",
|
"User": "用户",
|
||||||
"UserCreatedWithName": "用户 {0} 已创建",
|
"UserCreatedWithName": "用户 {0} 已创建",
|
||||||
"UserDeletedWithName": "用户 {0} 已删除",
|
"UserDeletedWithName": "用户 {0} 已删除",
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Net.WebSockets;
|
|
||||||
using MediaBrowser.Model.Services;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Net
|
namespace Emby.Server.Implementations.Net
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Emby.Server.Implementations.Images;
|
using Emby.Server.Implementations.Images;
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the task to be executed
|
/// Returns the task to be executed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <param name="progress">The progress.</param>
|
/// <param name="progress">The progress.</param>
|
||||||
|
@ -89,7 +89,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
SourceTypes = new SourceType[] { SourceType.Library },
|
SourceTypes = new SourceType[] { SourceType.Library },
|
||||||
HasChapterImages = false,
|
HasChapterImages = false,
|
||||||
IsVirtualItem = false
|
IsVirtualItem = false
|
||||||
|
|
||||||
})
|
})
|
||||||
.OfType<Video>()
|
.OfType<Video>()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -160,7 +159,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name => "Chapter image extraction";
|
public string Name => "Extract Chapter Images";
|
||||||
|
|
||||||
public string Description => "Creates thumbnails for videos that have chapters.";
|
public string Description => "Creates thumbnails for videos that have chapters.";
|
||||||
|
|
||||||
|
|
|
@ -158,9 +158,9 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name => "Cache file cleanup";
|
public string Name => "Clean Cache Directory";
|
||||||
|
|
||||||
public string Description => "Deletes cache files no longer needed by the system";
|
public string Description => "Deletes cache files no longer needed by the system.";
|
||||||
|
|
||||||
public string Category => "Maintenance";
|
public string Category => "Maintenance";
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ using MediaBrowser.Model.Tasks;
|
||||||
namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes old log files
|
/// Deletes old log files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask
|
public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask
|
||||||
{
|
{
|
||||||
|
@ -33,20 +33,18 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the triggers that define when the task will run
|
/// Creates the triggers that define when the task will run.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
{
|
{
|
||||||
return new[] {
|
return new[] {
|
||||||
|
|
||||||
// Every so often
|
|
||||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
|
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the task to be executed
|
/// Returns the task to be executed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <param name="progress">The progress.</param>
|
/// <param name="progress">The progress.</param>
|
||||||
|
@ -81,7 +79,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name => "Log file cleanup";
|
public string Name => "Clean Log Directory";
|
||||||
|
|
||||||
public string Description => string.Format("Deletes log files that are more than {0} days old.", ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
|
public string Description => string.Format("Deletes log files that are more than {0} days old.", ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
|
||||||
|
|
||||||
|
|
|
@ -125,9 +125,9 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name => "Transcode file cleanup";
|
public string Name => "Clean Transcode Directory";
|
||||||
|
|
||||||
public string Description => "Deletes transcode files more than 24 hours old.";
|
public string Description => "Deletes transcode files more than one day old.";
|
||||||
|
|
||||||
public string Category => "Maintenance";
|
public string Category => "Maintenance";
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,12 @@ using MediaBrowser.Model.Tasks;
|
||||||
namespace Emby.Server.Implementations.ScheduledTasks
|
namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class PeopleValidationTask
|
/// Class PeopleValidationTask.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PeopleValidationTask : IScheduledTask
|
public class PeopleValidationTask : IScheduledTask
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _library manager
|
/// The library manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
@ -32,13 +32,12 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the triggers that define when the task will run
|
/// Creates the triggers that define when the task will run.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
{
|
{
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
// Every so often
|
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfo.TriggerInterval,
|
||||||
|
@ -48,7 +47,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the task to be executed
|
/// Returns the task to be executed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <param name="progress">The progress.</param>
|
/// <param name="progress">The progress.</param>
|
||||||
|
@ -58,7 +57,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
return _libraryManager.ValidatePeople(cancellationToken, progress);
|
return _libraryManager.ValidatePeople(cancellationToken, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name => "Refresh people";
|
public string Name => "Refresh People";
|
||||||
|
|
||||||
public string Description => "Updates metadata for actors and directors in your media library.";
|
public string Description => "Updates metadata for actors and directors in your media library.";
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Name => "Check for plugin updates";
|
public string Name => "Update Plugins";
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Description => "Downloads and installs updates for plugins that are configured to update automatically.";
|
public string Description => "Downloads and installs updates for plugins that are configured to update automatically.";
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken);
|
return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name => "Scan media library";
|
public string Name => "Scan Media Library";
|
||||||
|
|
||||||
public string Description => "Scans your media library for new files and refreshes metadata.";
|
public string Description => "Scans your media library for new files and refreshes metadata.";
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Serialization
|
namespace Emby.Server.Implementations.Serialization
|
||||||
|
@ -12,13 +11,15 @@ namespace Emby.Server.Implementations.Serialization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JsonSerializer : IJsonSerializer
|
public class JsonSerializer : IJsonSerializer
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem;
|
public JsonSerializer()
|
||||||
|
|
||||||
public JsonSerializer(
|
|
||||||
IFileSystem fileSystem)
|
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601;
|
||||||
Configure();
|
ServiceStack.Text.JsConfig.ExcludeTypeInfo = true;
|
||||||
|
ServiceStack.Text.JsConfig.IncludeNullValues = false;
|
||||||
|
ServiceStack.Text.JsConfig.AlwaysUseUtc = true;
|
||||||
|
ServiceStack.Text.JsConfig.AssumeUtc = true;
|
||||||
|
|
||||||
|
ServiceStack.Text.JsConfig<Guid>.SerializeFn = SerializeGuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -81,7 +82,7 @@ namespace Emby.Server.Implementations.Serialization
|
||||||
throw new ArgumentNullException(nameof(file));
|
throw new ArgumentNullException(nameof(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var stream = _fileSystem.GetFileStream(file, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
using (var stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
SerializeToStream(obj, stream);
|
SerializeToStream(obj, stream);
|
||||||
}
|
}
|
||||||
|
@ -162,7 +163,6 @@ namespace Emby.Server.Implementations.Serialization
|
||||||
throw new ArgumentNullException(nameof(stream));
|
throw new ArgumentNullException(nameof(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ServiceStack.Text.JsonSerializer.DeserializeFromStreamAsync<T>(stream);
|
return ServiceStack.Text.JsonSerializer.DeserializeFromStreamAsync<T>(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,20 +225,6 @@ namespace Emby.Server.Implementations.Serialization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configures this instance.
|
|
||||||
/// </summary>
|
|
||||||
private void Configure()
|
|
||||||
{
|
|
||||||
ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601;
|
|
||||||
ServiceStack.Text.JsConfig.ExcludeTypeInfo = true;
|
|
||||||
ServiceStack.Text.JsConfig.IncludeNullValues = false;
|
|
||||||
ServiceStack.Text.JsConfig.AlwaysUseUtc = true;
|
|
||||||
ServiceStack.Text.JsConfig.AssumeUtc = true;
|
|
||||||
|
|
||||||
ServiceStack.Text.JsConfig<Guid>.SerializeFn = SerializeGuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string SerializeGuid(Guid guid)
|
private static string SerializeGuid(Guid guid)
|
||||||
{
|
{
|
||||||
if (guid.Equals(Guid.Empty))
|
if (guid.Equals(Guid.Empty))
|
||||||
|
|
|
@ -30,17 +30,17 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Session
|
namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class SessionManager
|
/// Class SessionManager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SessionManager : ISessionManager, IDisposable
|
public class SessionManager : ISessionManager, IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _user data repository
|
/// The user data repository.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IUserDataManager _userDataManager;
|
private readonly IUserDataManager _userDataManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _logger
|
/// The logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
private readonly IDeviceManager _deviceManager;
|
private readonly IDeviceManager _deviceManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _active connections
|
/// The active connections.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ConcurrentDictionary<string, SessionInfo> _activeConnections =
|
private readonly ConcurrentDictionary<string, SessionInfo> _activeConnections =
|
||||||
new ConcurrentDictionary<string, SessionInfo>(StringComparer.OrdinalIgnoreCase);
|
new ConcurrentDictionary<string, SessionInfo>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
@ -70,18 +70,23 @@ namespace Emby.Server.Implementations.Session
|
||||||
/// Occurs when [playback start].
|
/// Occurs when [playback start].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<PlaybackProgressEventArgs> PlaybackStart;
|
public event EventHandler<PlaybackProgressEventArgs> PlaybackStart;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when [playback progress].
|
/// Occurs when [playback progress].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<PlaybackProgressEventArgs> PlaybackProgress;
|
public event EventHandler<PlaybackProgressEventArgs> PlaybackProgress;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when [playback stopped].
|
/// Occurs when [playback stopped].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<PlaybackStopEventArgs> PlaybackStopped;
|
public event EventHandler<PlaybackStopEventArgs> PlaybackStopped;
|
||||||
|
|
||||||
public event EventHandler<SessionEventArgs> SessionStarted;
|
public event EventHandler<SessionEventArgs> SessionStarted;
|
||||||
|
|
||||||
public event EventHandler<SessionEventArgs> CapabilitiesChanged;
|
public event EventHandler<SessionEventArgs> CapabilitiesChanged;
|
||||||
|
|
||||||
public event EventHandler<SessionEventArgs> SessionEnded;
|
public event EventHandler<SessionEventArgs> SessionEnded;
|
||||||
|
|
||||||
public event EventHandler<SessionEventArgs> SessionActivity;
|
public event EventHandler<SessionEventArgs> SessionActivity;
|
||||||
|
|
||||||
public SessionManager(
|
public SessionManager(
|
||||||
|
@ -924,7 +929,6 @@ namespace Emby.Server.Implementations.Session
|
||||||
ClientName = session.Client,
|
ClientName = session.Client,
|
||||||
DeviceId = session.DeviceId,
|
DeviceId = session.DeviceId,
|
||||||
Session = session
|
Session = session
|
||||||
|
|
||||||
},
|
},
|
||||||
_logger);
|
_logger);
|
||||||
}
|
}
|
||||||
|
@ -1610,7 +1614,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
private DtoOptions _itemInfoDtoOptions;
|
private DtoOptions _itemInfoDtoOptions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a BaseItem to a BaseItemInfo
|
/// Converts a BaseItem to a BaseItemInfo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private BaseItemDto GetItemInfo(BaseItem item, MediaSourceInfo mediaSource)
|
private BaseItemDto GetItemInfo(BaseItem item, MediaSourceInfo mediaSource)
|
||||||
{
|
{
|
||||||
|
@ -1680,7 +1684,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError("Error getting {0} image info", ex, type);
|
_logger.LogError(ex, "Error getting image information for {Type}", type);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Model.Services;
|
|
||||||
|
|
||||||
public sealed class HttpPostedFile : IDisposable
|
public sealed class HttpPostedFile : IDisposable
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Server.Implementations.HttpServer;
|
using Emby.Server.Implementations.HttpServer;
|
||||||
using Emby.Server.Implementations.Net;
|
using Emby.Server.Implementations.Net;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="SkiaSharp" Version="1.68.0" />
|
<PackageReference Include="SkiaSharp" Version="1.68.1" />
|
||||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.0" />
|
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.1" />
|
||||||
<PackageReference Include="Jellyfin.SkiaSharp.NativeAssets.LinuxArm" Version="1.68.0" />
|
<PackageReference Include="Jellyfin.SkiaSharp.NativeAssets.LinuxArm" Version="1.68.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
<!-- Code analysers-->
|
<!-- Code analysers-->
|
||||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.7" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
|
||||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
||||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,16 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommandLineParser" Version="2.6.0" />
|
<PackageReference Include="CommandLineParser" Version="2.7.82" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.1" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
|
||||||
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
|
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
|
||||||
<PackageReference Include="Serilog.Settings.Configuration" 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.Async" Version="1.4.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Graylog" Version="2.1.1" />
|
<PackageReference Include="Serilog.Sinks.Graylog" Version="2.1.2" />
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.2" />
|
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.2" />
|
||||||
<PackageReference Include="SQLitePCLRaw.provider.sqlite3.netstandard11" Version="1.1.14" />
|
<PackageReference Include="SQLitePCLRaw.provider.sqlite3.netstandard11" Version="1.1.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -4,7 +4,6 @@ using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Security;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -238,7 +237,7 @@ namespace Jellyfin.Server
|
||||||
{
|
{
|
||||||
foreach (var address in addresses)
|
foreach (var address in addresses)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Kestrel listening on {ipaddr}", address);
|
_logger.LogInformation("Kestrel listening on {IpAddress}", address);
|
||||||
options.Listen(address, appHost.HttpPort);
|
options.Listen(address, appHost.HttpPort);
|
||||||
|
|
||||||
if (appHost.EnableHttps && appHost.Certificate != null)
|
if (appHost.EnableHttps && appHost.Certificate != null)
|
||||||
|
@ -443,20 +442,18 @@ namespace Jellyfin.Server
|
||||||
if (!File.Exists(configPath))
|
if (!File.Exists(configPath))
|
||||||
{
|
{
|
||||||
// For some reason the csproj name is used instead of the assembly name
|
// For some reason the csproj name is used instead of the assembly name
|
||||||
using (Stream? resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath))
|
await using Stream? resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath);
|
||||||
|
if (resource == null)
|
||||||
{
|
{
|
||||||
if (resource == null)
|
throw new InvalidOperationException(
|
||||||
{
|
string.Format(
|
||||||
throw new InvalidOperationException(
|
CultureInfo.InvariantCulture,
|
||||||
string.Format(
|
"Invalid resource path: '{0}'",
|
||||||
CultureInfo.InvariantCulture,
|
ResourcePath));
|
||||||
"Invalid resource path: '{0}'",
|
|
||||||
ResourcePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
using Stream dst = File.Open(configPath, FileMode.CreateNew);
|
|
||||||
await resource.CopyToAsync(dst).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await using Stream dst = File.Open(configPath, FileMode.CreateNew);
|
||||||
|
await resource.CopyToAsync(dst).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConfigurationBuilder()
|
return new ConfigurationBuilder()
|
||||||
|
@ -485,7 +482,7 @@ namespace Jellyfin.Server
|
||||||
.WriteTo.Async(x => x.File(
|
.WriteTo.Async(x => x.File(
|
||||||
Path.Combine(appPaths.LogDirectoryPath, "log_.log"),
|
Path.Combine(appPaths.LogDirectoryPath, "log_.log"),
|
||||||
rollingInterval: RollingInterval.Day,
|
rollingInterval: RollingInterval.Day,
|
||||||
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}:{Message}{NewLine}{Exception}"))
|
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message}{NewLine}{Exception}"))
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
.Enrich.WithThreadId()
|
.Enrich.WithThreadId()
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
"retainedFileCountLimit": 3,
|
"retainedFileCountLimit": 3,
|
||||||
"rollOnFileSizeLimit": true,
|
"rollOnFileSizeLimit": true,
|
||||||
"fileSizeLimitBytes": 100000000,
|
"fileSizeLimitBytes": 100000000,
|
||||||
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}:{Message}{NewLine}{Exception}"
|
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message}{NewLine}{Exception}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,6 @@ using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Configuration;
|
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
@ -6,7 +6,6 @@ using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Net;
|
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
|
@ -656,7 +656,7 @@ namespace MediaBrowser.Api.Images
|
||||||
IsHeadRequest = isHeadRequest,
|
IsHeadRequest = isHeadRequest,
|
||||||
Path = imageResult.Item1,
|
Path = imageResult.Item1,
|
||||||
|
|
||||||
FileShare = FileShareMode.Read
|
FileShare = FileShare.Read
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,11 +274,9 @@ namespace MediaBrowser.Api.Images
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
||||||
using (var stream = result.Content)
|
using (var stream = result.Content)
|
||||||
|
using (var filestream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true))
|
||||||
{
|
{
|
||||||
using (var filestream = _fileSystem.GetFileStream(fullCachePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
await stream.CopyToAsync(filestream).ConfigureAwait(false);
|
||||||
{
|
|
||||||
await stream.CopyToAsync(filestream).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
|
||||||
|
|
|
@ -305,7 +305,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
||||||
using (var stream = result.Content)
|
using (var stream = result.Content)
|
||||||
using (var filestream = _fileSystem.GetFileStream(fullCachePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
using (var filestream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true))
|
||||||
{
|
{
|
||||||
await stream.CopyToAsync(filestream).ConfigureAwait(false);
|
await stream.CopyToAsync(filestream).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
|
|
|
@ -16,17 +16,13 @@ using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Persistence;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Controller.TV;
|
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
@ -261,7 +261,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt");
|
var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt");
|
||||||
|
|
||||||
// FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
|
// FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
|
||||||
Stream logStream = FileSystem.GetFileStream(logFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true);
|
Stream logStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true);
|
||||||
|
|
||||||
var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(Request.AbsoluteUri + Environment.NewLine + Environment.NewLine + JsonSerializer.SerializeToString(state.MediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
|
var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(Request.AbsoluteUri + Environment.NewLine + Environment.NewLine + JsonSerializer.SerializeToString(state.MediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
|
||||||
await logStream.WriteAsync(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length, cancellationTokenSource.Token).ConfigureAwait(false);
|
await logStream.WriteAsync(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length, cancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
|
|
|
@ -168,7 +168,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
|
|
||||||
private string GetLivePlaylistText(string path, int segmentLength)
|
private string GetLivePlaylistText(string path, int segmentLength)
|
||||||
{
|
{
|
||||||
using (var stream = FileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite))
|
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
{
|
{
|
||||||
using (var reader = new StreamReader(stream))
|
using (var reader = new StreamReader(stream))
|
||||||
{
|
{
|
||||||
|
@ -211,7 +211,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Need to use FileShareMode.ReadWrite because we're reading the file at the same time it's being written
|
// Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
|
||||||
using (var fileStream = GetPlaylistFileStream(playlist))
|
using (var fileStream = GetPlaylistFileStream(playlist))
|
||||||
{
|
{
|
||||||
using (var reader = new StreamReader(fileStream))
|
using (var reader = new StreamReader(fileStream))
|
||||||
|
@ -252,11 +252,11 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return FileSystem.GetFileStream(tmpPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, FileOpenOptions.SequentialScan);
|
return new FileStream(tmpPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, FileOptions.SequentialScan);
|
||||||
}
|
}
|
||||||
catch (IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
return FileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, FileOpenOptions.SequentialScan);
|
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, FileOptions.SequentialScan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
@ -537,7 +536,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
||||||
{
|
{
|
||||||
Path = segmentPath,
|
Path = segmentPath,
|
||||||
FileShare = FileShareMode.ReadWrite,
|
FileShare = FileShare.ReadWrite,
|
||||||
OnComplete = () =>
|
OnComplete = () =>
|
||||||
{
|
{
|
||||||
Logger.LogDebug("finished serving {0}", segmentPath);
|
Logger.LogDebug("finished serving {0}", segmentPath);
|
||||||
|
@ -954,12 +953,12 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
// Unable to force key frames to h264_qsv transcode
|
// Unable to force key frames to h264_qsv transcode
|
||||||
if (string.Equals(codec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(codec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Bug Workaround: Disabling force_key_frames for h264_qsv");
|
Logger.LogInformation("Bug Workaround: Disabling force_key_frames for h264_qsv");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args += " " + keyFrameArg;
|
args += " " + keyFrameArg;
|
||||||
}
|
}
|
||||||
|
|
||||||
//args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0";
|
//args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0";
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
|
var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
|
||||||
file = Path.Combine(ServerConfigurationManager.GetTranscodePath(), file);
|
file = Path.Combine(ServerConfigurationManager.GetTranscodePath(), file);
|
||||||
|
|
||||||
return ResultFactory.GetStaticFileResult(Request, file, FileShareMode.ReadWrite);
|
return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<object> GetFileResult(string path, string playlistPath)
|
private Task<object> GetFileResult(string path, string playlistPath)
|
||||||
|
@ -150,7 +150,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
||||||
{
|
{
|
||||||
Path = path,
|
Path = path,
|
||||||
FileShare = FileShareMode.ReadWrite,
|
FileShare = FileShare.ReadWrite,
|
||||||
OnComplete = () =>
|
OnComplete = () =>
|
||||||
{
|
{
|
||||||
if (transcodingJob != null)
|
if (transcodingJob != null)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -23,7 +22,6 @@ using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
using MediaBrowser.Model.Serialization;
|
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
@ -248,7 +248,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
// ContentType = contentType,
|
// ContentType = contentType,
|
||||||
// IsHeadRequest = isHeadRequest,
|
// IsHeadRequest = isHeadRequest,
|
||||||
// Path = outputPath,
|
// Path = outputPath,
|
||||||
// FileShare = FileShareMode.ReadWrite,
|
// FileShare = FileShare.ReadWrite,
|
||||||
// OnComplete = () =>
|
// OnComplete = () =>
|
||||||
// {
|
// {
|
||||||
// if (transcodingJob != null)
|
// if (transcodingJob != null)
|
||||||
|
|
|
@ -21,8 +21,6 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
private readonly CancellationToken _cancellationToken;
|
private readonly CancellationToken _cancellationToken;
|
||||||
private readonly Dictionary<string, string> _outputHeaders;
|
private readonly Dictionary<string, string> _outputHeaders;
|
||||||
|
|
||||||
const int StreamCopyToBufferSize = 81920;
|
|
||||||
|
|
||||||
private long _bytesWritten = 0;
|
private long _bytesWritten = 0;
|
||||||
public long StartPosition { get; set; }
|
public long StartPosition { get; set; }
|
||||||
public bool AllowEndOfFile = true;
|
public bool AllowEndOfFile = true;
|
||||||
|
@ -52,14 +50,14 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
|
|
||||||
private Stream GetInputStream(bool allowAsyncFileRead)
|
private Stream GetInputStream(bool allowAsyncFileRead)
|
||||||
{
|
{
|
||||||
var fileOpenOptions = FileOpenOptions.SequentialScan;
|
var fileOptions = FileOptions.SequentialScan;
|
||||||
|
|
||||||
if (allowAsyncFileRead)
|
if (allowAsyncFileRead)
|
||||||
{
|
{
|
||||||
fileOpenOptions |= FileOpenOptions.Asynchronous;
|
fileOptions |= FileOptions.Asynchronous;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _fileSystem.GetFileStream(_path, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, fileOpenOptions);
|
return new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, fileOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task WriteToAsync(Stream outputStream, CancellationToken cancellationToken)
|
public async Task WriteToAsync(Stream outputStream, CancellationToken cancellationToken)
|
||||||
|
@ -127,7 +125,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
|
|
||||||
private async Task<int> CopyToInternalAsyncWithSyncRead(Stream source, Stream destination, CancellationToken cancellationToken)
|
private async Task<int> CopyToInternalAsyncWithSyncRead(Stream source, Stream destination, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var array = new byte[StreamCopyToBufferSize];
|
var array = new byte[IODefaults.CopyToBufferSize];
|
||||||
int bytesRead;
|
int bytesRead;
|
||||||
int totalBytesRead = 0;
|
int totalBytesRead = 0;
|
||||||
|
|
||||||
|
@ -154,7 +152,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||||
|
|
||||||
private async Task<int> CopyToInternalAsync(Stream source, Stream destination, CancellationToken cancellationToken)
|
private async Task<int> CopyToInternalAsync(Stream source, Stream destination, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var array = new byte[StreamCopyToBufferSize];
|
var array = new byte[IODefaults.CopyToBufferSize];
|
||||||
int bytesRead;
|
int bytesRead;
|
||||||
int totalBytesRead = 0;
|
int totalBytesRead = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReportTranscodingProgress(TimeSpan? transcodingPosition, float framerate, double? percentComplete, long bytesTranscoded, int? bitRate)
|
public override void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
|
||||||
{
|
{
|
||||||
ApiEntryPoint.Instance.ReportTranscodingProgress(TranscodingJob, this, transcodingPosition, framerate, percentComplete, bytesTranscoded, bitRate);
|
ApiEntryPoint.Instance.ReportTranscodingProgress(TranscodingJob, this, transcodingPosition, framerate, percentComplete, bytesTranscoded, bitRate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace MediaBrowser.Api.Session
|
namespace MediaBrowser.Api.Session
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class GetSessions
|
/// Class GetSessions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("/Sessions", "GET", Summary = "Gets a list of sessions")]
|
[Route("/Sessions", "GET", Summary = "Gets a list of sessions")]
|
||||||
[Authenticated]
|
[Authenticated]
|
||||||
|
@ -34,7 +34,7 @@ namespace MediaBrowser.Api.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class DisplayContent
|
/// Class DisplayContent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("/Sessions/{Id}/Viewing", "POST", Summary = "Instructs a session to browse to an item or view")]
|
[Route("/Sessions/{Id}/Viewing", "POST", Summary = "Instructs a session to browse to an item or view")]
|
||||||
[Authenticated]
|
[Authenticated]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
|
|
|
@ -170,10 +170,10 @@ namespace MediaBrowser.Api.System
|
||||||
// For older files, assume fully static
|
// For older files, assume fully static
|
||||||
if (file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1))
|
if (file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1))
|
||||||
{
|
{
|
||||||
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShareMode.Read);
|
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.Read);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShareMode.ReadWrite);
|
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.ReadWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -5,7 +5,6 @@ using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Persistence;
|
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
|
|
@ -6,7 +6,6 @@ using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Persistence;
|
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
|
|
@ -6,7 +6,6 @@ using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Persistence;
|
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
@ -281,7 +281,6 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
IsHidden = false,
|
IsHidden = false,
|
||||||
IsDisabled = false
|
IsDisabled = false
|
||||||
|
|
||||||
}, true, true);
|
}, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,10 +394,11 @@ namespace MediaBrowser.Api
|
||||||
throw new MethodNotAllowedException("Hashed-only passwords are not valid for this API.");
|
throw new MethodNotAllowedException("Hashed-only passwords are not valid for this API.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Password should always be null
|
||||||
return Post(new AuthenticateUserByName
|
return Post(new AuthenticateUserByName
|
||||||
{
|
{
|
||||||
Username = user.Name,
|
Username = user.Name,
|
||||||
Password = null, // This should always be null
|
Password = null,
|
||||||
Pw = request.Pw
|
Pw = request.Pw
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.1" />
|
||||||
<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
|
<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -135,57 +135,4 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return hasChanges;
|
return hasChanges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is the small Person stub that is attached to BaseItems
|
|
||||||
/// </summary>
|
|
||||||
public class PersonInfo : IHasProviderIds
|
|
||||||
{
|
|
||||||
public PersonInfo()
|
|
||||||
{
|
|
||||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Guid ItemId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The name.</value>
|
|
||||||
public string Name { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the role.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The role.</value>
|
|
||||||
public string Role { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the type.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The type.</value>
|
|
||||||
public string Type { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the sort order - ascending
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The sort order.</value>
|
|
||||||
public int? SortOrder { get; set; }
|
|
||||||
|
|
||||||
public string ImageUrl { get; set; }
|
|
||||||
|
|
||||||
public Dictionary<string, string> ProviderIds { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a <see cref="string" /> that represents this instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A <see cref="string" /> that represents this instance.</returns>
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsType(string type)
|
|
||||||
{
|
|
||||||
return string.Equals(Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(Role, type, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
63
MediaBrowser.Controller/Entities/PersonInfo.cs
Normal file
63
MediaBrowser.Controller/Entities/PersonInfo.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is a small Person stub that is attached to BaseItems.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class PersonInfo : IHasProviderIds
|
||||||
|
{
|
||||||
|
public PersonInfo()
|
||||||
|
{
|
||||||
|
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid ItemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the name.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name.</value>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the role.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The role.</value>
|
||||||
|
public string Role { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the type.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The type.</value>
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the ascending sort order.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The sort order.</value>
|
||||||
|
public int? SortOrder { get; set; }
|
||||||
|
|
||||||
|
public string ImageUrl { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<string, string> ProviderIds { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="string" /> that represents this instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="string" /> that represents this instance.</returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsType(string type)
|
||||||
|
{
|
||||||
|
return string.Equals(Type, type, StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(Role, type, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,14 +60,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
PresetViews = query.PresetViews
|
PresetViews = query.PresetViews
|
||||||
});
|
});
|
||||||
|
|
||||||
var itemsArray = result;
|
return UserViewBuilder.SortAndPage(result, null, query, LibraryManager, true);
|
||||||
var totalCount = itemsArray.Length;
|
|
||||||
|
|
||||||
return new QueryResult<BaseItem>
|
|
||||||
{
|
|
||||||
TotalRecordCount = totalCount,
|
|
||||||
Items = itemsArray //TODO Fix The co-variant conversion between Folder[] and BaseItem[], this can generate runtime issues.
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetChildCount(User user)
|
public override int GetChildCount(User user)
|
||||||
|
|
|
@ -7,7 +7,6 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -26,4 +26,16 @@
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- Code Analyzers-->
|
||||||
|
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -475,7 +475,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
.Append(' ');
|
.Append(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.IsVideoRequest
|
if (state.IsVideoRequest
|
||||||
&& string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
&& string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions);
|
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions);
|
||||||
|
@ -486,11 +486,11 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase))
|
if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
arg.Append("-hwaccel qsv ");
|
arg.Append("-hwaccel qsv ");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arg.Append("-init_hw_device qsv=hw -filter_hw_device hw ");
|
arg.Append("-init_hw_device qsv=hw -filter_hw_device hw ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arg.Append(videoDecoder + " ");
|
arg.Append(videoDecoder + " ");
|
||||||
|
@ -653,7 +653,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
// _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(fallbackFontPath));
|
// _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(fallbackFontPath));
|
||||||
// using (var stream = _assemblyInfo.GetManifestResourceStream(GetType(), GetType().Namespace + ".DroidSansFallback.ttf"))
|
// using (var stream = _assemblyInfo.GetManifestResourceStream(GetType(), GetType().Namespace + ".DroidSansFallback.ttf"))
|
||||||
// {
|
// {
|
||||||
// using (var fileStream = _fileSystem.GetFileStream(fallbackFontPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
// using (var fileStream = new FileStream(fallbackFontPath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
// {
|
// {
|
||||||
// stream.CopyTo(fileStream);
|
// stream.CopyTo(fileStream);
|
||||||
// }
|
// }
|
||||||
|
@ -1624,22 +1624,22 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
// Setup default filtergraph utilizing FFMpeg overlay() and FFMpeg scale() (see the return of this function for index reference)
|
// Setup default filtergraph utilizing FFMpeg overlay() and FFMpeg scale() (see the return of this function for index reference)
|
||||||
var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\"";
|
var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\"";
|
||||||
|
|
||||||
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
QSV in FFMpeg can now setup hardware overlay for transcodes.
|
QSV in FFMpeg can now setup hardware overlay for transcodes.
|
||||||
For software decoding and hardware encoding option, frames must be hwuploaded into hardware
|
For software decoding and hardware encoding option, frames must be hwuploaded into hardware
|
||||||
with fixed frame size.
|
with fixed frame size.
|
||||||
*/
|
*/
|
||||||
if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase))
|
if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\"";
|
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\"";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]hwupload=extra_hw_frames=64[v];[v][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\"";
|
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]hwupload=extra_hw_frames=64[v];[v][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format(
|
return string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
|
@ -1731,8 +1731,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
vaapi_or_qsv,
|
vaapi_or_qsv,
|
||||||
outputWidth,
|
outputWidth,
|
||||||
outputHeight));
|
outputHeight));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv));
|
filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv));
|
||||||
}
|
}
|
||||||
|
@ -1979,8 +1979,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
|
|
||||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
|
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
|
||||||
|
|
||||||
// If we are software decoding, and hardware encoding
|
// If we are software decoding, and hardware encoding
|
||||||
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)
|
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)
|
||||||
&& (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)))
|
&& (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
filters.Add("format=nv12|qsv");
|
filters.Add("format=nv12|qsv");
|
||||||
|
|
|
@ -665,7 +665,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
}
|
}
|
||||||
|
|
||||||
public IProgress<double> Progress { get; set; }
|
public IProgress<double> Progress { get; set; }
|
||||||
public virtual void ReportTranscodingProgress(TimeSpan? transcodingPosition, float framerate, double? percentComplete, long bytesTranscoded, int? bitRate)
|
public virtual void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
|
||||||
{
|
{
|
||||||
Progress.Report(percentComplete.Value);
|
Progress.Report(percentComplete.Value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
|
|
@ -4,7 +4,6 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.MediaEncoding
|
namespace MediaBrowser.Controller.MediaEncoding
|
||||||
|
@ -90,6 +89,15 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
framerate = val;
|
framerate = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (part.StartsWith("fps=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var rate = part.Split(new[] { '=' }, 2)[^1];
|
||||||
|
|
||||||
|
if (float.TryParse(rate, NumberStyles.Any, _usCulture, out var val))
|
||||||
|
{
|
||||||
|
framerate = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (state.RunTimeTicks.HasValue &&
|
else if (state.RunTimeTicks.HasValue &&
|
||||||
part.StartsWith("time=", StringComparison.OrdinalIgnoreCase))
|
part.StartsWith("time=", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -146,7 +154,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
|
|
||||||
if (framerate.HasValue || percent.HasValue)
|
if (framerate.HasValue || percent.HasValue)
|
||||||
{
|
{
|
||||||
state.ReportTranscodingProgress(transcodingPosition, 0, percent, 0, bitRate);
|
state.ReportTranscodingProgress(transcodingPosition, framerate, percent, bytesTranscoded, bitRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue