소스 검색

Remove custom Json serializer from Emby.Server.Implementations

David 4 년 전
부모
커밋
196388d607

+ 5 - 9
Emby.Server.Implementations/ApplicationHost.cs

@@ -7,11 +7,9 @@ using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Net;
-using System.Net.Http;
 using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Security.Cryptography.X509Certificates;
-using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using Emby.Dlna;
@@ -50,6 +48,7 @@ using Jellyfin.Networking.Manager;
 using MediaBrowser.Common;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Events;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Plugins;
 using MediaBrowser.Common.Updates;
@@ -101,6 +100,7 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 using Prometheus.DotNetRuntime;
+using JsonSerializer = System.Text.Json.JsonSerializer;
 using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
 using WebSocketManager = Emby.Server.Implementations.HttpServer.WebSocketManager;
 
@@ -118,7 +118,6 @@ namespace Emby.Server.Implementations
 
         private readonly IFileSystem _fileSystemManager;
         private readonly IXmlSerializer _xmlSerializer;
-        private readonly IJsonSerializer _jsonSerializer;
         private readonly IStartupOptions _startupOptions;
 
         private IMediaEncoder _mediaEncoder;
@@ -257,7 +256,6 @@ namespace Emby.Server.Implementations
             IServiceCollection serviceCollection)
         {
             _xmlSerializer = new MyXmlSerializer();
-            _jsonSerializer = new JsonSerializer();
 
             ServiceCollection = serviceCollection;
 
@@ -528,8 +526,6 @@ namespace Emby.Server.Implementations
 
             ServiceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths);
 
-            ServiceCollection.AddSingleton<IJsonSerializer, JsonSerializer>();
-
             ServiceCollection.AddSingleton(_fileSystemManager);
             ServiceCollection.AddSingleton<TmdbClientManager>();
 
@@ -754,7 +750,6 @@ namespace Emby.Server.Implementations
             UserView.CollectionManager = Resolve<ICollectionManager>();
             BaseItem.MediaSourceManager = Resolve<IMediaSourceManager>();
             CollectionFolder.XmlSerializer = _xmlSerializer;
-            CollectionFolder.JsonSerializer = Resolve<IJsonSerializer>();
             CollectionFolder.ApplicationHost = this;
         }
 
@@ -967,7 +962,7 @@ namespace Emby.Server.Implementations
                 {
                     return true;
                 }
-                
+
                 throw new FileNotFoundException(
                     string.Format(
                         CultureInfo.InvariantCulture,
@@ -1051,7 +1046,8 @@ namespace Emby.Server.Implementations
                     var metafile = Path.Combine(dir, "meta.json");
                     if (File.Exists(metafile))
                     {
-                        var manifest = _jsonSerializer.DeserializeFromFile<PluginManifest>(metafile);
+                        var jsonString = File.ReadAllText(metafile);
+                        var manifest = JsonSerializer.Deserialize<PluginManifest>(jsonString, JsonDefaults.GetOptions());
 
                         if (!Version.TryParse(manifest.TargetAbi, out var targetAbi))
                         {

+ 17 - 15
Emby.Server.Implementations/Channels/ChannelManager.cs

@@ -8,6 +8,7 @@ using System.Threading.Tasks;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
@@ -21,10 +22,10 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Caching.Memory;
 using Microsoft.Extensions.Logging;
 using Episode = MediaBrowser.Controller.Entities.TV.Episode;
+using JsonSerializer = System.Text.Json.JsonSerializer;
 using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
 using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
 using Season = MediaBrowser.Controller.Entities.TV.Season;
@@ -44,7 +45,6 @@ namespace Emby.Server.Implementations.Channels
         private readonly ILogger<ChannelManager> _logger;
         private readonly IServerConfigurationManager _config;
         private readonly IFileSystem _fileSystem;
-        private readonly IJsonSerializer _jsonSerializer;
         private readonly IProviderManager _providerManager;
         private readonly IMemoryCache _memoryCache;
         private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
@@ -70,7 +70,6 @@ namespace Emby.Server.Implementations.Channels
             IServerConfigurationManager config,
             IFileSystem fileSystem,
             IUserDataManager userDataManager,
-            IJsonSerializer jsonSerializer,
             IProviderManager providerManager,
             IMemoryCache memoryCache)
         {
@@ -81,7 +80,6 @@ namespace Emby.Server.Implementations.Channels
             _config = config;
             _fileSystem = fileSystem;
             _userDataManager = userDataManager;
-            _jsonSerializer = jsonSerializer;
             _providerManager = providerManager;
             _memoryCache = memoryCache;
         }
@@ -343,7 +341,8 @@ namespace Emby.Server.Implementations.Channels
 
             try
             {
-                return _jsonSerializer.DeserializeFromFile<List<MediaSourceInfo>>(path) ?? new List<MediaSourceInfo>();
+                var jsonString = File.ReadAllText(path);
+                return JsonSerializer.Deserialize<List<MediaSourceInfo>>(jsonString, JsonDefaults.GetOptions()) ?? new List<MediaSourceInfo>();
             }
             catch
             {
@@ -351,7 +350,7 @@ namespace Emby.Server.Implementations.Channels
             }
         }
 
-        private void SaveMediaSources(BaseItem item, List<MediaSourceInfo> mediaSources)
+        private async Task SaveMediaSources(BaseItem item, List<MediaSourceInfo> mediaSources)
         {
             var path = Path.Combine(item.GetInternalMetadataPath(), "channelmediasourceinfos.json");
 
@@ -369,8 +368,8 @@ namespace Emby.Server.Implementations.Channels
             }
 
             Directory.CreateDirectory(Path.GetDirectoryName(path));
-
-            _jsonSerializer.SerializeToFile(mediaSources, path);
+            await using FileStream createStream = File.Create(path);
+            await JsonSerializer.SerializeAsync(createStream, mediaSources, JsonDefaults.GetOptions()).ConfigureAwait(false);
         }
 
         /// <inheritdoc />
@@ -812,7 +811,8 @@ namespace Emby.Server.Implementations.Channels
             {
                 if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
                 {
-                    var cachedResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
+                    var jsonString = await File.ReadAllTextAsync(cachePath, cancellationToken);
+                    var cachedResult = JsonSerializer.Deserialize<ChannelItemResult>(jsonString);
                     if (cachedResult != null)
                     {
                         return null;
@@ -834,7 +834,8 @@ namespace Emby.Server.Implementations.Channels
                 {
                     if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
                     {
-                        var cachedResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
+                        var jsonString = await File.ReadAllTextAsync(cachePath, cancellationToken);
+                        var cachedResult = JsonSerializer.Deserialize<ChannelItemResult>(jsonString);
                         if (cachedResult != null)
                         {
                             return null;
@@ -865,7 +866,7 @@ namespace Emby.Server.Implementations.Channels
                     throw new InvalidOperationException("Channel returned a null result from GetChannelItems");
                 }
 
-                CacheResponse(result, cachePath);
+                await CacheResponse(result, cachePath);
 
                 return result;
             }
@@ -875,13 +876,14 @@ namespace Emby.Server.Implementations.Channels
             }
         }
 
-        private void CacheResponse(object result, string path)
+        private async Task CacheResponse(object result, string path)
         {
             try
             {
                 Directory.CreateDirectory(Path.GetDirectoryName(path));
 
-                _jsonSerializer.SerializeToFile(result, path);
+                await using FileStream createStream = File.Create(path);
+                await JsonSerializer.SerializeAsync(createStream, result, JsonDefaults.GetOptions()).ConfigureAwait(false);
             }
             catch (Exception ex)
             {
@@ -1176,11 +1178,11 @@ namespace Emby.Server.Implementations.Channels
             {
                 if (enableMediaProbe && !info.IsLiveStream && item.HasPathProtocol)
                 {
-                    SaveMediaSources(item, new List<MediaSourceInfo>());
+                    await SaveMediaSources(item, new List<MediaSourceInfo>());
                 }
                 else
                 {
-                    SaveMediaSources(item, info.MediaSources);
+                    await SaveMediaSources(item, info.MediaSources);
                 }
             }
 

+ 7 - 6
Emby.Server.Implementations/Library/LiveStreamHelper.cs

@@ -5,16 +5,17 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.MediaInfo;
-using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.Library
@@ -23,14 +24,12 @@ namespace Emby.Server.Implementations.Library
     {
         private readonly IMediaEncoder _mediaEncoder;
         private readonly ILogger _logger;
-        private readonly IJsonSerializer _json;
         private readonly IApplicationPaths _appPaths;
 
-        public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger, IJsonSerializer json, IApplicationPaths appPaths)
+        public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger, IApplicationPaths appPaths)
         {
             _mediaEncoder = mediaEncoder;
             _logger = logger;
-            _json = json;
             _appPaths = appPaths;
         }
 
@@ -47,7 +46,8 @@ namespace Emby.Server.Implementations.Library
             {
                 try
                 {
-                    mediaInfo = _json.DeserializeFromFile<MediaInfo>(cacheFilePath);
+                    var jsonString = await File.ReadAllTextAsync(cacheFilePath, cancellationToken).ConfigureAwait(false);
+                    JsonSerializer.Deserialize<MediaInfo>(jsonString, JsonDefaults.GetOptions());
 
                     // _logger.LogDebug("Found cached media info");
                 }
@@ -83,7 +83,8 @@ namespace Emby.Server.Implementations.Library
                 if (cacheFilePath != null)
                 {
                     Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
-                    _json.SerializeToFile(mediaInfo, cacheFilePath);
+                    await using FileStream createStream = File.Create(cacheFilePath);
+                    await JsonSerializer.SerializeAsync(createStream, mediaInfo, cancellationToken: cancellationToken).ConfigureAwait(false);
 
                     // _logger.LogDebug("Saved media info to {0}", cacheFilePath);
                 }

+ 9 - 9
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -6,12 +6,14 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.MediaEncoding;
@@ -23,7 +25,6 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.MediaInfo;
-using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.Library
@@ -36,7 +37,6 @@ namespace Emby.Server.Implementations.Library
         private readonly IItemRepository _itemRepo;
         private readonly IUserManager _userManager;
         private readonly ILibraryManager _libraryManager;
-        private readonly IJsonSerializer _jsonSerializer;
         private readonly IFileSystem _fileSystem;
         private readonly ILogger<MediaSourceManager> _logger;
         private readonly IUserDataManager _userDataManager;
@@ -56,7 +56,6 @@ namespace Emby.Server.Implementations.Library
             IUserManager userManager,
             ILibraryManager libraryManager,
             ILogger<MediaSourceManager> logger,
-            IJsonSerializer jsonSerializer,
             IFileSystem fileSystem,
             IUserDataManager userDataManager,
             IMediaEncoder mediaEncoder)
@@ -65,7 +64,6 @@ namespace Emby.Server.Implementations.Library
             _userManager = userManager;
             _libraryManager = libraryManager;
             _logger = logger;
-            _jsonSerializer = jsonSerializer;
             _fileSystem = fileSystem;
             _userDataManager = userDataManager;
             _mediaEncoder = mediaEncoder;
@@ -504,7 +502,7 @@ namespace Emby.Server.Implementations.Library
                     // hack - these two values were taken from LiveTVMediaSourceProvider
                     string cacheKey = request.OpenToken;
 
-                    await new LiveStreamHelper(_mediaEncoder, _logger, _jsonSerializer, _appPaths)
+                    await new LiveStreamHelper(_mediaEncoder, _logger, _appPaths)
                         .AddMediaInfoWithProbe(mediaSource, isAudio, cacheKey, true, cancellationToken)
                         .ConfigureAwait(false);
                 }
@@ -516,9 +514,9 @@ namespace Emby.Server.Implementations.Library
             }
 
             // TODO: @bond Fix
-            var json = _jsonSerializer.SerializeToString(mediaSource);
+            var json = JsonSerializer.Serialize(mediaSource, JsonDefaults.GetOptions());
             _logger.LogInformation("Live stream opened: " + json);
-            var clone = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json);
+            var clone = JsonSerializer.Deserialize<MediaSourceInfo>(json, JsonDefaults.GetOptions());
 
             if (!request.UserId.Equals(Guid.Empty))
             {
@@ -643,7 +641,8 @@ namespace Emby.Server.Implementations.Library
             {
                 try
                 {
-                    mediaInfo = _jsonSerializer.DeserializeFromFile<MediaInfo>(cacheFilePath);
+                    var json = await File.ReadAllTextAsync(cacheFilePath, cancellationToken).ConfigureAwait(false);
+                    mediaInfo = JsonSerializer.Deserialize<MediaInfo>(json, JsonDefaults.GetOptions());
 
                     // _logger.LogDebug("Found cached media info");
                 }
@@ -679,7 +678,8 @@ namespace Emby.Server.Implementations.Library
                 if (cacheFilePath != null)
                 {
                     Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
-                    _jsonSerializer.SerializeToFile(mediaInfo, cacheFilePath);
+                    await using FileStream createStream = File.Create(cacheFilePath);
+                    await JsonSerializer.SerializeAsync(createStream, mediaInfo, JsonDefaults.GetOptions(), cancellationToken).ConfigureAwait(false);
 
                     // _logger.LogDebug("Saved media info to {0}", cacheFilePath);
                 }

+ 4 - 8
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -36,7 +36,6 @@ using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Providers;
 using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.LiveTv.EmbyTV
@@ -51,7 +50,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         private readonly ILogger<EmbyTV> _logger;
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IServerConfigurationManager _config;
-        private readonly IJsonSerializer _jsonSerializer;
 
         private readonly ItemDataProvider<SeriesTimerInfo> _seriesTimerProvider;
         private readonly TimerManager _timerProvider;
@@ -81,7 +79,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             IStreamHelper streamHelper,
             IMediaSourceManager mediaSourceManager,
             ILogger<EmbyTV> logger,
-            IJsonSerializer jsonSerializer,
             IHttpClientFactory httpClientFactory,
             IServerConfigurationManager config,
             ILiveTvManager liveTvManager,
@@ -103,12 +100,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             _providerManager = providerManager;
             _mediaEncoder = mediaEncoder;
             _liveTvManager = (LiveTvManager)liveTvManager;
-            _jsonSerializer = jsonSerializer;
             _mediaSourceManager = mediaSourceManager;
             _streamHelper = streamHelper;
 
-            _seriesTimerProvider = new SeriesTimerManager(jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers.json"));
-            _timerProvider = new TimerManager(jsonSerializer, _logger, Path.Combine(DataPath, "timers.json"));
+            _seriesTimerProvider = new SeriesTimerManager(_logger, Path.Combine(DataPath, "seriestimers.json"));
+            _timerProvider = new TimerManager(_logger, Path.Combine(DataPath, "timers.json"));
             _timerProvider.TimerFired += OnTimerProviderTimerFired;
 
             _config.NamedConfigurationUpdated += OnNamedConfigurationUpdated;
@@ -1052,7 +1048,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 IgnoreIndex = true
             };
 
-            await new LiveStreamHelper(_mediaEncoder, _logger, _jsonSerializer, _config.CommonApplicationPaths)
+            await new LiveStreamHelper(_mediaEncoder, _logger, _config.CommonApplicationPaths)
                 .AddMediaInfoWithProbe(stream, false, false, cancellationToken).ConfigureAwait(false);
 
             return new List<MediaSourceInfo>
@@ -1635,7 +1631,7 @@ 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))
             {
-                return new EncodedRecorder(_logger, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _config);
+                return new EncodedRecorder(_logger, _mediaEncoder, _config.ApplicationPaths, _config);
             }
 
             return new DirectRecorder(_logger, _httpClientFactory, _streamHelper);

+ 3 - 5
Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs

@@ -6,16 +6,17 @@ using System.Diagnostics;
 using System.Globalization;
 using System.IO;
 using System.Text;
+using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.LiveTv.EmbyTV
@@ -25,7 +26,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         private readonly ILogger _logger;
         private readonly IMediaEncoder _mediaEncoder;
         private readonly IServerApplicationPaths _appPaths;
-        private readonly IJsonSerializer _json;
         private readonly TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
         private readonly IServerConfigurationManager _serverConfigurationManager;
 
@@ -38,13 +38,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             ILogger logger,
             IMediaEncoder mediaEncoder,
             IServerApplicationPaths appPaths,
-            IJsonSerializer json,
             IServerConfigurationManager serverConfigurationManager)
         {
             _logger = logger;
             _mediaEncoder = mediaEncoder;
             _appPaths = appPaths;
-            _json = json;
             _serverConfigurationManager = serverConfigurationManager;
         }
 
@@ -95,7 +93,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             // FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
             _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(JsonSerializer.Serialize(mediaSource, JsonDefaults.GetOptions()) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
             _logFileStream.Write(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length);
 
             _process = new Process

+ 6 - 6
Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs

@@ -4,7 +4,8 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using MediaBrowser.Model.Serialization;
+using System.Text.Json;
+using MediaBrowser.Common.Json;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.LiveTv.EmbyTV
@@ -12,18 +13,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
     public class ItemDataProvider<T>
         where T : class
     {
-        private readonly IJsonSerializer _jsonSerializer;
         private readonly string _dataPath;
         private readonly object _fileDataLock = new object();
         private T[] _items;
 
         public ItemDataProvider(
-            IJsonSerializer jsonSerializer,
             ILogger logger,
             string dataPath,
             Func<T, T, bool> equalityComparer)
         {
-            _jsonSerializer = jsonSerializer;
             Logger = logger;
             _dataPath = dataPath;
             EqualityComparer = equalityComparer;
@@ -46,7 +44,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
                 try
                 {
-                    _items = _jsonSerializer.DeserializeFromFile<T[]>(_dataPath);
+                    var json = File.ReadAllText(_dataPath);
+                    _items = JsonSerializer.Deserialize<T[]>(json, JsonDefaults.GetOptions());
                     return;
                 }
                 catch (Exception ex)
@@ -61,7 +60,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         private void SaveList()
         {
             Directory.CreateDirectory(Path.GetDirectoryName(_dataPath));
-            _jsonSerializer.SerializeToFile(_items, _dataPath);
+            using FileStream stream = File.OpenWrite(_dataPath);
+            JsonSerializer.SerializeAsync(stream, _items, JsonDefaults.GetOptions());
         }
 
         public IReadOnlyList<T> GetAll()

+ 2 - 2
Emby.Server.Implementations/LiveTv/EmbyTV/SeriesTimerManager.cs

@@ -9,8 +9,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 {
     public class SeriesTimerManager : ItemDataProvider<SeriesTimerInfo>
     {
-        public SeriesTimerManager(IJsonSerializer jsonSerializer, ILogger logger, string dataPath)
-            : base(jsonSerializer, logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
+        public SeriesTimerManager(ILogger logger, string dataPath)
+            : base(logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
         {
         }
 

+ 2 - 3
Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs

@@ -8,7 +8,6 @@ using System.Threading;
 using Jellyfin.Data.Events;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Model.LiveTv;
-using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.LiveTv.EmbyTV
@@ -17,8 +16,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
     {
         private readonly ConcurrentDictionary<string, Timer> _timers = new ConcurrentDictionary<string, Timer>(StringComparer.OrdinalIgnoreCase);
 
-        public TimerManager(IJsonSerializer jsonSerializer, ILogger logger, string dataPath)
-            : base(jsonSerializer, logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
+        public TimerManager(ILogger logger, string dataPath)
+            : base(logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
         {
         }
 

+ 12 - 12
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs

@@ -9,16 +9,17 @@ using System.Net;
 using System.Net.Http;
 using System.Net.Mime;
 using System.Text;
+using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Common;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Model.Cryptography;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.LiveTv;
-using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.LiveTv.Listings
@@ -28,7 +29,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
         private const string ApiUrl = "https://json.schedulesdirect.org/20141201";
 
         private readonly ILogger<SchedulesDirect> _logger;
-        private readonly IJsonSerializer _jsonSerializer;
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly SemaphoreSlim _tokenSemaphore = new SemaphoreSlim(1, 1);
         private readonly IApplicationHost _appHost;
@@ -39,13 +39,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 
         public SchedulesDirect(
             ILogger<SchedulesDirect> logger,
-            IJsonSerializer jsonSerializer,
             IHttpClientFactory httpClientFactory,
             IApplicationHost appHost,
             ICryptoProvider cryptoProvider)
         {
             _logger = logger;
-            _jsonSerializer = jsonSerializer;
             _httpClientFactory = httpClientFactory;
             _appHost = appHost;
             _cryptoProvider = cryptoProvider;
@@ -104,7 +102,9 @@ namespace Emby.Server.Implementations.LiveTv.Listings
                     }
                 };
 
-            var requestString = _jsonSerializer.SerializeToString(requestList);
+            var jsonOptions = JsonDefaults.GetOptions();
+
+            var requestString = JsonSerializer.Serialize(requestList, jsonOptions);
             _logger.LogDebug("Request string for schedules is: {RequestString}", requestString);
 
             using var options = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/schedules");
@@ -112,7 +112,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
             options.Headers.TryAddWithoutValidation("token", token);
             using var response = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
             await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-            var dailySchedules = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Day>>(responseStream).ConfigureAwait(false);
+            var dailySchedules = await JsonSerializer.DeserializeAsync<List<ScheduleDirect.Day>>(responseStream, jsonOptions).ConfigureAwait(false);
             _logger.LogDebug("Found {ScheduleCount} programs on {ChannelID} ScheduleDirect", dailySchedules.Count, channelId);
 
             using var programRequestOptions = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/programs");
@@ -123,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 
             using var innerResponse = await Send(programRequestOptions, true, info, cancellationToken).ConfigureAwait(false);
             await using var innerResponseStream = await innerResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-            var programDetails = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ProgramDetails>>(innerResponseStream).ConfigureAwait(false);
+            var programDetails = await JsonSerializer.DeserializeAsync<List<ScheduleDirect.ProgramDetails>>(innerResponseStream, jsonOptions).ConfigureAwait(false);
             var programDict = programDetails.ToDictionary(p => p.programID, y => y);
 
             var programIdsWithImages =
@@ -479,7 +479,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
             {
                 using var innerResponse2 = await Send(message, true, info, cancellationToken).ConfigureAwait(false);
                 await using var response = await innerResponse2.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-                return await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ShowImages>>(response).ConfigureAwait(false);
+                return await JsonSerializer.DeserializeAsync<List<ScheduleDirect.ShowImages>>(response, JsonDefaults.GetOptions(), cancellationToken).ConfigureAwait(false);
             }
             catch (Exception ex)
             {
@@ -508,7 +508,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
                 using var httpResponse = await Send(options, false, info, cancellationToken).ConfigureAwait(false);
                 await using var response = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
 
-                var root = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Headends>>(response).ConfigureAwait(false);
+                var root = await JsonSerializer.DeserializeAsync<List<ScheduleDirect.Headends>>(response, JsonDefaults.GetOptions(), cancellationToken).ConfigureAwait(false);
 
                 if (root != null)
                 {
@@ -649,7 +649,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
             using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
             response.EnsureSuccessStatusCode();
             await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-            var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Token>(stream).ConfigureAwait(false);
+            var root = await JsonSerializer.DeserializeAsync<ScheduleDirect.Token>(stream, JsonDefaults.GetOptions(), cancellationToken).ConfigureAwait(false);
             if (string.Equals(root.message, "OK", StringComparison.Ordinal))
             {
                 _logger.LogInformation("Authenticated with Schedules Direct token: " + root.token);
@@ -705,7 +705,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
                 httpResponse.EnsureSuccessStatusCode();
                 await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
                 using var response = httpResponse.Content;
-                var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Lineups>(stream).ConfigureAwait(false);
+                var root = await JsonSerializer.DeserializeAsync<ScheduleDirect.Lineups>(stream, JsonDefaults.GetOptions()).ConfigureAwait(false);
 
                 return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
             }
@@ -777,7 +777,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 
             using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
             await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-            var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Channel>(stream).ConfigureAwait(false);
+            var root = await JsonSerializer.DeserializeAsync<ScheduleDirect.Channel>(stream, JsonDefaults.GetOptions()).ConfigureAwait(false);
             _logger.LogInformation("Found {ChannelCount} channels on the lineup on ScheduleDirect", root.map.Count);
             _logger.LogInformation("Mapping Stations to Channel");
 

+ 8 - 6
Emby.Server.Implementations/Localization/LocalizationManager.cs

@@ -5,7 +5,9 @@ using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Reflection;
+using System.Text.Json;
 using System.Threading.Tasks;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Globalization;
@@ -24,7 +26,6 @@ namespace Emby.Server.Implementations.Localization
         private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
 
         private readonly IServerConfigurationManager _configurationManager;
-        private readonly IJsonSerializer _jsonSerializer;
         private readonly ILogger<LocalizationManager> _logger;
 
         private readonly Dictionary<string, Dictionary<string, ParentalRating>> _allParentalRatings =
@@ -43,11 +44,9 @@ namespace Emby.Server.Implementations.Localization
         /// <param name="logger">The logger.</param>
         public LocalizationManager(
             IServerConfigurationManager configurationManager,
-            IJsonSerializer jsonSerializer,
             ILogger<LocalizationManager> logger)
         {
             _configurationManager = configurationManager;
-            _jsonSerializer = jsonSerializer;
             _logger = logger;
         }
 
@@ -179,8 +178,11 @@ namespace Emby.Server.Implementations.Localization
 
         /// <inheritdoc />
         public IEnumerable<CountryInfo> GetCountries()
-            => _jsonSerializer.DeserializeFromStream<IEnumerable<CountryInfo>>(
-                    _assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
+        {
+            StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
+
+            return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), JsonDefaults.GetOptions());
+        }
 
         /// <inheritdoc />
         public IEnumerable<ParentalRating> GetParentalRatings()
@@ -344,7 +346,7 @@ namespace Emby.Server.Implementations.Localization
                 // If a Culture doesn't have a translation the stream will be null and it defaults to en-us further up the chain
                 if (stream != null)
                 {
-                    var dict = await _jsonSerializer.DeserializeFromStreamAsync<Dictionary<string, string>>(stream).ConfigureAwait(false);
+                    var dict = await JsonSerializer.DeserializeAsync<Dictionary<string, string>>(stream, JsonDefaults.GetOptions()).ConfigureAwait(false);
 
                     foreach (var key in dict.Keys)
                     {

+ 18 - 17
Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs

@@ -4,13 +4,14 @@ using System;
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Data.Events;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Json;
 using MediaBrowser.Common.Progress;
-using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Tasks;
 using Microsoft.Extensions.Logging;
 
@@ -21,11 +22,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
     /// </summary>
     public class ScheduledTaskWorker : IScheduledTaskWorker
     {
-        /// <summary>
-        /// Gets or sets the json serializer.
-        /// </summary>
-        /// <value>The json serializer.</value>
-        private readonly IJsonSerializer _jsonSerializer;
 
         /// <summary>
         /// Gets or sets the application paths.
@@ -88,7 +84,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
         /// or
         /// logger.
         /// </exception>
-        public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger)
+        public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, ILogger logger)
         {
             if (scheduledTask == null)
             {
@@ -105,11 +101,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
                 throw new ArgumentNullException(nameof(taskManager));
             }
 
-            if (jsonSerializer == null)
-            {
-                throw new ArgumentNullException(nameof(jsonSerializer));
-            }
-
             if (logger == null)
             {
                 throw new ArgumentNullException(nameof(logger));
@@ -118,7 +109,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
             ScheduledTask = scheduledTask;
             _applicationPaths = applicationPaths;
             _taskManager = taskManager;
-            _jsonSerializer = jsonSerializer;
             _logger = logger;
 
             InitTriggerEvents();
@@ -150,7 +140,15 @@ namespace Emby.Server.Implementations.ScheduledTasks
                         {
                             try
                             {
-                                _lastExecutionResult = _jsonSerializer.DeserializeFromFile<TaskResult>(path);
+                                var jsonString = File.ReadAllText(path);
+                                if (!string.IsNullOrWhiteSpace(jsonString))
+                                {
+                                    _lastExecutionResult = JsonSerializer.Deserialize<TaskResult>(jsonString, JsonDefaults.GetOptions());
+                                }
+                                else
+                                {
+                                    _logger.LogDebug("Scheduled Task history file {path} is empty. Skipping deserialization.", path);
+                                }
                             }
                             catch (Exception ex)
                             {
@@ -174,7 +172,8 @@ namespace Emby.Server.Implementations.ScheduledTasks
 
                 lock (_lastExecutionResultSyncLock)
                 {
-                    _jsonSerializer.SerializeToFile(value, path);
+                    using FileStream createStream = File.OpenWrite(path);
+                    JsonSerializer.SerializeAsync(createStream, value, JsonDefaults.GetOptions());
                 }
             }
         }
@@ -537,7 +536,8 @@ namespace Emby.Server.Implementations.ScheduledTasks
             TaskTriggerInfo[] list = null;
             if (File.Exists(path))
             {
-                list = _jsonSerializer.DeserializeFromFile<TaskTriggerInfo[]>(path);
+                var jsonString = File.ReadAllText(path);
+                list = JsonSerializer.Deserialize<TaskTriggerInfo[]>(jsonString, JsonDefaults.GetOptions());
             }
 
             // Return defaults if file doesn't exist.
@@ -573,7 +573,8 @@ namespace Emby.Server.Implementations.ScheduledTasks
 
             Directory.CreateDirectory(Path.GetDirectoryName(path));
 
-            _jsonSerializer.SerializeToFile(triggers, path);
+            using FileStream stream = File.OpenWrite(path);
+            JsonSerializer.SerializeAsync(stream, triggers, JsonDefaults.GetOptions());
         }
 
         /// <summary>

+ 2 - 5
Emby.Server.Implementations/ScheduledTasks/TaskManager.cs

@@ -7,7 +7,6 @@ using System.Linq;
 using System.Threading.Tasks;
 using Jellyfin.Data.Events;
 using MediaBrowser.Common.Configuration;
-using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Tasks;
 using Microsoft.Extensions.Logging;
 
@@ -19,6 +18,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
     public class TaskManager : ITaskManager
     {
         public event EventHandler<GenericEventArgs<IScheduledTaskWorker>> TaskExecuting;
+
         public event EventHandler<TaskCompletionEventArgs> TaskCompleted;
 
         /// <summary>
@@ -33,7 +33,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
         private readonly ConcurrentQueue<Tuple<Type, TaskOptions>> _taskQueue =
             new ConcurrentQueue<Tuple<Type, TaskOptions>>();
 
-        private readonly IJsonSerializer _jsonSerializer;
         private readonly IApplicationPaths _applicationPaths;
         private readonly ILogger<TaskManager> _logger;
 
@@ -45,11 +44,9 @@ namespace Emby.Server.Implementations.ScheduledTasks
         /// <param name="logger">The logger.</param>
         public TaskManager(
             IApplicationPaths applicationPaths,
-            IJsonSerializer jsonSerializer,
             ILogger<TaskManager> logger)
         {
             _applicationPaths = applicationPaths;
-            _jsonSerializer = jsonSerializer;
             _logger = logger;
 
             ScheduledTasks = Array.Empty<IScheduledTaskWorker>();
@@ -196,7 +193,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
         /// <param name="tasks">The tasks.</param>
         public void AddTasks(IEnumerable<IScheduledTask> tasks)
         {
-            var list = tasks.Select(t => new ScheduledTaskWorker(t, _applicationPaths, this, _jsonSerializer, _logger));
+            var list = tasks.Select(t => new ScheduledTaskWorker(t, _applicationPaths, this, _logger));
 
             ScheduledTasks = ScheduledTasks.Concat(list).ToArray();
         }