aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJPVenson <github@jpb.email>2024-10-08 09:34:34 +0000
committerJPVenson <github@jpb.email>2024-10-08 09:34:34 +0000
commitd3a3d9fce3b891eb0be274a0cdc45a989e557652 (patch)
treebd232ef477c259f1fafa204016f6efd4dcb8691f /src
parentee1bdf4e222125ed7382165fd7e09599ca4bd4aa (diff)
parentaaf20592bb0bbdf4f0f0d99fed091758e68ae850 (diff)
Merge remote-tracking branch 'jellyfinorigin/master' into feature/EFUserData
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.Extensions/FormattingStreamWriter.cs38
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs65
-rw-r--r--src/Jellyfin.Extensions/StringExtensions.cs19
-rw-r--r--src/Jellyfin.LiveTv/IO/EncodedRecorder.cs4
-rw-r--r--src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs2
-rw-r--r--src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs6
-rw-r--r--src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs4
-rw-r--r--src/Jellyfin.Networking/Manager/NetworkManager.cs9
8 files changed, 115 insertions, 32 deletions
diff --git a/src/Jellyfin.Extensions/FormattingStreamWriter.cs b/src/Jellyfin.Extensions/FormattingStreamWriter.cs
new file mode 100644
index 000000000..40e3c5a68
--- /dev/null
+++ b/src/Jellyfin.Extensions/FormattingStreamWriter.cs
@@ -0,0 +1,38 @@
+using System;
+using System.IO;
+
+namespace Jellyfin.Extensions;
+
+/// <summary>
+/// A custom StreamWriter which supports setting a IFormatProvider.
+/// </summary>
+public class FormattingStreamWriter : StreamWriter
+{
+ private readonly IFormatProvider _formatProvider;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FormattingStreamWriter"/> class.
+ /// </summary>
+ /// <param name="stream">The stream to write to.</param>
+ /// <param name="formatProvider">The format provider to use.</param>
+ public FormattingStreamWriter(Stream stream, IFormatProvider formatProvider)
+ : base(stream)
+ {
+ _formatProvider = formatProvider;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FormattingStreamWriter"/> class.
+ /// </summary>
+ /// <param name="path">The complete file path to write to.</param>
+ /// <param name="formatProvider">The format provider to use.</param>
+ public FormattingStreamWriter(string path, IFormatProvider formatProvider)
+ : base(path)
+ {
+ _formatProvider = formatProvider;
+ }
+
+ /// <inheritdoc />
+ public override IFormatProvider FormatProvider
+ => _formatProvider;
+}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs
index 1466d3a71..936a5a97c 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonDelimitedArrayConverter.cs
@@ -1,5 +1,7 @@
using System;
+using System.Collections.Generic;
using System.ComponentModel;
+using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
@@ -35,38 +37,27 @@ namespace Jellyfin.Extensions.Json.Converters
var stringEntries = reader.GetString()!.Split(Delimiter, StringSplitOptions.RemoveEmptyEntries);
if (stringEntries.Length == 0)
{
- return Array.Empty<T>();
+ return [];
}
- var parsedValues = new object[stringEntries.Length];
- var convertedCount = 0;
+ var typedValues = new List<T>();
for (var i = 0; i < stringEntries.Length; i++)
{
try
{
- parsedValues[i] = _typeConverter.ConvertFromInvariantString(stringEntries[i].Trim()) ?? throw new FormatException();
- convertedCount++;
+ var parsedValue = _typeConverter.ConvertFromInvariantString(stringEntries[i].Trim());
+ if (parsedValue is not null)
+ {
+ typedValues.Add((T)parsedValue);
+ }
}
catch (FormatException)
{
- // TODO log when upgraded to .Net6
- // https://github.com/dotnet/runtime/issues/42975
- // _logger.LogDebug(e, "Error converting value.");
+ // Ignore unconvertable inputs
}
}
- var typedValues = new T[convertedCount];
- var typedValueIndex = 0;
- for (var i = 0; i < stringEntries.Length; i++)
- {
- if (parsedValues[i] is not null)
- {
- typedValues.SetValue(parsedValues[i], typedValueIndex);
- typedValueIndex++;
- }
- }
-
- return typedValues;
+ return typedValues.ToArray();
}
return JsonSerializer.Deserialize<T[]>(ref reader, options);
@@ -75,7 +66,39 @@ namespace Jellyfin.Extensions.Json.Converters
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
{
- throw new NotImplementedException();
+ if (value is not null)
+ {
+ writer.WriteStartArray();
+ if (value.Length > 0)
+ {
+ var toWrite = value.Length - 1;
+ foreach (var it in value)
+ {
+ var wrote = false;
+ if (it is not null)
+ {
+ writer.WriteStringValue(it.ToString());
+ wrote = true;
+ }
+
+ if (toWrite > 0)
+ {
+ if (wrote)
+ {
+ writer.WriteStringValue(Delimiter.ToString());
+ }
+
+ toWrite--;
+ }
+ }
+ }
+
+ writer.WriteEndArray();
+ }
+ else
+ {
+ writer.WriteNullValue();
+ }
}
}
}
diff --git a/src/Jellyfin.Extensions/StringExtensions.cs b/src/Jellyfin.Extensions/StringExtensions.cs
index 8cfebd594..4b9677d9f 100644
--- a/src/Jellyfin.Extensions/StringExtensions.cs
+++ b/src/Jellyfin.Extensions/StringExtensions.cs
@@ -9,8 +9,21 @@ namespace Jellyfin.Extensions
/// </summary>
public static partial class StringExtensions
{
- private static readonly Lazy<Transliterator> _transliterator = new(() => Transliterator.GetInstance(
- "Any-Latin; Latin-Ascii; Lower; NFD; [:Nonspacing Mark:] Remove; [:Punctuation:] Remove;"));
+ private static readonly Lazy<string> _transliteratorId = new(() =>
+ Environment.GetEnvironmentVariable("JELLYFIN_TRANSLITERATOR_ID")
+ ?? "Any-Latin; Latin-Ascii; Lower; NFD; [:Nonspacing Mark:] Remove; [:Punctuation:] Remove;");
+
+ private static readonly Lazy<Transliterator?> _transliterator = new(() =>
+ {
+ try
+ {
+ return Transliterator.GetInstance(_transliteratorId.Value);
+ }
+ catch (ArgumentException)
+ {
+ return null;
+ }
+ });
// Matches non-conforming unicode chars
// https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/
@@ -108,7 +121,7 @@ namespace Jellyfin.Extensions
/// <returns>The transliterated string.</returns>
public static string Transliterated(this string text)
{
- return _transliterator.Value.Transliterate(text);
+ return (_transliterator.Value is null) ? text : _transliterator.Value.Transliterate(text);
}
}
}
diff --git a/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs b/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs
index ff00c8999..0c660637f 100644
--- a/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs
+++ b/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs
@@ -130,7 +130,7 @@ namespace Jellyfin.LiveTv.IO
const int MaxBitrate = 25000000;
videoArgs = string.Format(
CultureInfo.InvariantCulture,
- "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41",
+ "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -profile:v high -level 41",
GetOutputSizeParam(),
MaxBitrate);
}
@@ -157,7 +157,7 @@ namespace Jellyfin.LiveTv.IO
flags.Add("+genpts");
}
- var inputModifier = "-async 1 -vsync -1";
+ var inputModifier = "-async 1";
if (flags.Count > 0)
{
diff --git a/src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index fef84dd00..e1f87a7bd 100644
--- a/src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -331,6 +331,8 @@ namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
SupportsTranscoding = true,
IsInfiniteStream = true,
IgnoreDts = true,
+ UseMostCompatibleTranscodingProfile = true, // All HDHR tuners require this
+ FallbackMaxStreamingBitrate = info.FallbackMaxStreamingBitrate,
// IgnoreIndex = true,
// ReadAtNativeFramerate = true
};
diff --git a/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs b/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs
index 365f0188d..be81171a0 100644
--- a/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs
@@ -94,7 +94,7 @@ namespace Jellyfin.LiveTv.TunerHosts
var mediaSource = sources[0];
- if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
+ if (tunerHost.AllowStreamSharing && mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
{
var extension = Path.GetExtension(new UriBuilder(mediaSource.Path).Path);
@@ -200,7 +200,9 @@ namespace Jellyfin.LiveTv.TunerHosts
SupportsDirectPlay = supportsDirectPlay,
SupportsDirectStream = supportsDirectStream,
- RequiredHttpHeaders = httpHeaders
+ RequiredHttpHeaders = httpHeaders,
+ UseMostCompatibleTranscodingProfile = !info.AllowFmp4TranscodingContainer,
+ FallbackMaxStreamingBitrate = info.FallbackMaxStreamingBitrate
};
mediaSource.InferTotalBitrate();
diff --git a/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs b/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs
index 9a023d7ed..1846ba26b 100644
--- a/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs
+++ b/src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs
@@ -128,7 +128,7 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
return false;
}
- internal static bool IsExtractionAllowedForFile(ReadOnlySpan<char> filePath, string[] allowedExtensions)
+ internal static bool IsExtractionAllowedForFile(ReadOnlySpan<char> filePath, IReadOnlyList<string> allowedExtensions)
{
var extension = Path.GetExtension(filePath);
if (extension.IsEmpty)
@@ -138,7 +138,7 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
// Remove the leading dot
var extensionWithoutDot = extension[1..];
- for (var i = 0; i < allowedExtensions.Length; i++)
+ for (var i = 0; i < allowedExtensions.Count; i++)
{
var allowedExtension = allowedExtensions[i].AsSpan().TrimStart('.');
if (extensionWithoutDot.Equals(allowedExtension, StringComparison.OrdinalIgnoreCase))
diff --git a/src/Jellyfin.Networking/Manager/NetworkManager.cs b/src/Jellyfin.Networking/Manager/NetworkManager.cs
index cf6a2cc55..b285b836b 100644
--- a/src/Jellyfin.Networking/Manager/NetworkManager.cs
+++ b/src/Jellyfin.Networking/Manager/NetworkManager.cs
@@ -97,10 +97,15 @@ public class NetworkManager : INetworkManager, IDisposable
_networkEventLock = new object();
_remoteAddressFilter = new List<IPNetwork>();
+ _ = bool.TryParse(startupConfig[DetectNetworkChangeKey], out var detectNetworkChange);
+
UpdateSettings(_configurationManager.GetNetworkConfiguration());
- NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;
- NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
+ if (detectNetworkChange)
+ {
+ NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;
+ NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
+ }
_configurationManager.NamedConfigurationUpdated += ConfigurationUpdated;
}