aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile2
-rw-r--r--Emby.Dlna/ContentDirectory/ControlHandler.cs2
-rw-r--r--Emby.Dlna/Didl/DidlBuilder.cs149
-rw-r--r--Emby.Dlna/Main/DlnaEntryPoint.cs11
-rw-r--r--Emby.Dlna/PlayTo/Device.cs181
-rw-r--r--Emby.Dlna/PlayTo/PlayToController.cs32
-rw-r--r--Emby.Dlna/PlayTo/PlayToManager.cs7
-rw-r--r--Emby.Dlna/Ssdp/DeviceDiscovery.cs8
-rw-r--r--Emby.Drawing/ImageProcessor.cs37
-rw-r--r--Emby.Drawing/NullImageEncoder.cs15
-rw-r--r--Emby.Notifications/Notifications.cs9
-rw-r--r--Emby.Photos/PhotoProvider.cs2
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs15
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs2
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj2
-rw-r--r--Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs9
-rw-r--r--Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs9
-rw-r--r--Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs13
-rw-r--r--Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs9
-rw-r--r--Emby.Server.Implementations/IO/FileRefresher.cs10
-rw-r--r--Emby.Server.Implementations/IO/LibraryMonitor.cs14
-rw-r--r--Emby.Server.Implementations/Library/MediaSourceManager.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs7
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs34
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs5
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs10
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs27
-rw-r--r--Emby.Server.Implementations/Localization/LocalizationManager.cs65
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs9
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs6
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs22
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs7
-rw-r--r--Emby.Server.Implementations/Networking/NetworkManager.cs2
-rw-r--r--Emby.Server.Implementations/Serialization/JsonSerializer.cs3
-rw-r--r--Emby.Server.Implementations/Services/ResponseHelper.cs2
-rw-r--r--Emby.Server.Implementations/Services/ServiceExec.cs2
-rw-r--r--Emby.Server.Implementations/Session/SessionManager.cs14
-rw-r--r--Emby.Server.Implementations/Threading/CommonTimer.cs36
-rw-r--r--Emby.Server.Implementations/Threading/TimerFactory.cs18
-rw-r--r--Emby.Server.Implementations/UserViews/FolderImageProvider.cs2
-rw-r--r--Jellyfin.Drawing.Skia/SkiaEncoder.cs13
-rw-r--r--Jellyfin.Server/CoreAppHost.cs2
-rw-r--r--Jellyfin.Server/SocketSharp/HttpFile.cs2
-rw-r--r--Jellyfin.Server/SocketSharp/RequestMono.cs61
-rw-r--r--Jellyfin.Server/SocketSharp/SharpWebSocket.cs2
-rw-r--r--Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs2
-rw-r--r--Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs45
-rw-r--r--Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs2
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs91
-rw-r--r--MediaBrowser.Api/BaseApiService.cs22
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs2
-rw-r--r--MediaBrowser.Api/LocalizationService.cs5
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs93
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs39
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs31
-rw-r--r--MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs4
-rw-r--r--MediaBrowser.Api/Playback/Hls/VideoHlsService.cs31
-rw-r--r--MediaBrowser.Api/Playback/Progressive/AudioService.cs28
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs29
-rw-r--r--MediaBrowser.Api/Playback/Progressive/VideoService.cs28
-rw-r--r--MediaBrowser.Api/Playback/TranscodingThrottler.cs29
-rw-r--r--MediaBrowser.Api/Playback/UniversalAudioService.cs3
-rw-r--r--MediaBrowser.Controller/Drawing/IImageEncoder.cs5
-rw-r--r--MediaBrowser.Controller/Drawing/IImageProcessor.cs29
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvService.cs5
-rw-r--r--MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs19
-rw-r--r--MediaBrowser.Controller/Session/SessionInfo.cs8
-rw-r--r--MediaBrowser.Model/Drawing/ImageDimensions.cs (renamed from MediaBrowser.Model/Drawing/ImageSize.cs)2
-rw-r--r--MediaBrowser.Model/Threading/ITimer.cs10
-rw-r--r--MediaBrowser.Model/Threading/ITimerFactory.cs10
-rw-r--r--MediaBrowser.Providers/Manager/GenericPriorityQueue.cs1
-rw-r--r--MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs1
-rw-r--r--MediaBrowser.Providers/Music/FanArtArtistProvider.cs1
-rw-r--r--MediaBrowser.Providers/People/TvdbPersonImageProvider.cs1
-rw-r--r--MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/MissingEpisodeProvider.cs1
-rw-r--r--MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TvExternalIds.cs1
-rw-r--r--README.md24
-rw-r--r--RSSDP/SsdpDeviceLocator.cs9
-rw-r--r--RSSDP/SsdpDevicePublisher.cs9
95 files changed, 803 insertions, 742 deletions
diff --git a/Dockerfile b/Dockerfile
index 37388fda9..266b59f1c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -10,7 +10,7 @@ RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \
--output /jellyfin \
Jellyfin.Server
-FROM jrottenberg/ffmpeg:4.0-scratch as ffmpeg
+FROM jrottenberg/ffmpeg:4.0-vaapi as ffmpeg
FROM microsoft/dotnet:${DOTNET_VERSION}-runtime
# libfontconfig1 is required for Skia
RUN apt-get update \
diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs
index bed4d885c..1150afdba 100644
--- a/Emby.Dlna/ContentDirectory/ControlHandler.cs
+++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs
@@ -63,7 +63,7 @@ namespace Emby.Dlna.ContentDirectory
_profile = profile;
_config = config;
- _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, _logger, libraryManager, mediaEncoder);
+ _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, _logger, mediaEncoder);
}
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams)
diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs
index f6d923a1f..605f4f37b 100644
--- a/Emby.Dlna/Didl/DidlBuilder.cs
+++ b/Emby.Dlna/Didl/DidlBuilder.cs
@@ -43,22 +43,30 @@ namespace Emby.Dlna.Didl
private readonly ILocalizationManager _localization;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly ILogger _logger;
- private readonly ILibraryManager _libraryManager;
private readonly IMediaEncoder _mediaEncoder;
- public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, ILogger logger, ILibraryManager libraryManager, IMediaEncoder mediaEncoder)
+ public DidlBuilder(
+ DeviceProfile profile,
+ User user,
+ IImageProcessor imageProcessor,
+ string serverAddress,
+ string accessToken,
+ IUserDataManager userDataManager,
+ ILocalizationManager localization,
+ IMediaSourceManager mediaSourceManager,
+ ILogger logger,
+ IMediaEncoder mediaEncoder)
{
_profile = profile;
+ _user = user;
_imageProcessor = imageProcessor;
_serverAddress = serverAddress;
+ _accessToken = accessToken;
_userDataManager = userDataManager;
_localization = localization;
_mediaSourceManager = mediaSourceManager;
_logger = logger;
- _libraryManager = libraryManager;
_mediaEncoder = mediaEncoder;
- _accessToken = accessToken;
- _user = user;
}
public static string NormalizeDlnaMediaUrl(string url)
@@ -117,7 +125,8 @@ namespace Emby.Dlna.Didl
}
}
- public void WriteItemElement(DlnaOptions options,
+ public void WriteItemElement(
+ DlnaOptions options,
XmlWriter writer,
BaseItem item,
User user,
@@ -232,12 +241,15 @@ namespace Emby.Dlna.Didl
AddVideoResource(writer, video, deviceId, filter, contentFeature, streamInfo);
}
- var subtitleProfiles = streamInfo.GetSubtitleProfiles(_mediaEncoder, false, _serverAddress, _accessToken)
- .Where(subtitle => subtitle.DeliveryMethod == SubtitleDeliveryMethod.External)
- .ToList();
+ var subtitleProfiles = streamInfo.GetSubtitleProfiles(_mediaEncoder, false, _serverAddress, _accessToken);
foreach (var subtitle in subtitleProfiles)
{
+ if (subtitle.DeliveryMethod != SubtitleDeliveryMethod.External)
+ {
+ continue;
+ }
+
var subtitleAdded = AddSubtitleElement(writer, subtitle);
if (subtitleAdded && _profile.EnableSingleSubtitleLimit)
@@ -250,7 +262,8 @@ namespace Emby.Dlna.Didl
private bool AddSubtitleElement(XmlWriter writer, SubtitleStreamInfo info)
{
var subtitleProfile = _profile.SubtitleProfiles
- .FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase) && i.Method == SubtitleDeliveryMethod.External);
+ .FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase)
+ && i.Method == SubtitleDeliveryMethod.External);
if (subtitleProfile == null)
{
@@ -387,91 +400,39 @@ namespace Emby.Dlna.Didl
private string GetDisplayName(BaseItem item, StubType? itemStubType, BaseItem context)
{
- if (itemStubType.HasValue && itemStubType.Value == StubType.Latest)
- {
- return _localization.GetLocalizedString("Latest");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Playlists)
+ if (itemStubType.HasValue)
{
- return _localization.GetLocalizedString("Playlists");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.AlbumArtists)
- {
- return _localization.GetLocalizedString("HeaderAlbumArtists");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Albums)
- {
- return _localization.GetLocalizedString("Albums");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Artists)
- {
- return _localization.GetLocalizedString("Artists");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Songs)
- {
- return _localization.GetLocalizedString("Songs");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Genres)
- {
- return _localization.GetLocalizedString("Genres");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteAlbums)
- {
- return _localization.GetLocalizedString("HeaderFavoriteAlbums");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteArtists)
- {
- return _localization.GetLocalizedString("HeaderFavoriteArtists");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteSongs)
- {
- return _localization.GetLocalizedString("HeaderFavoriteSongs");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.ContinueWatching)
- {
- return _localization.GetLocalizedString("HeaderContinueWatching");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Movies)
- {
- return _localization.GetLocalizedString("Movies");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Collections)
- {
- return _localization.GetLocalizedString("Collections");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Favorites)
- {
- return _localization.GetLocalizedString("Favorites");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.NextUp)
- {
- return _localization.GetLocalizedString("HeaderNextUp");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteSeries)
- {
- return _localization.GetLocalizedString("HeaderFavoriteShows");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteEpisodes)
- {
- return _localization.GetLocalizedString("HeaderFavoriteEpisodes");
- }
- if (itemStubType.HasValue && itemStubType.Value == StubType.Series)
- {
- return _localization.GetLocalizedString("Shows");
+ switch (itemStubType.Value)
+ {
+ case StubType.Latest: return _localization.GetLocalizedString("Latest");
+ case StubType.Playlists: return _localization.GetLocalizedString("Playlists");
+ case StubType.AlbumArtists: return _localization.GetLocalizedString("HeaderAlbumArtists");
+ case StubType.Albums: return _localization.GetLocalizedString("Albums");
+ case StubType.Artists: return _localization.GetLocalizedString("Artists");
+ case StubType.Songs: return _localization.GetLocalizedString("Songs");
+ case StubType.Genres: return _localization.GetLocalizedString("Genres");
+ case StubType.FavoriteAlbums: return _localization.GetLocalizedString("HeaderFavoriteAlbums");
+ case StubType.FavoriteArtists: return _localization.GetLocalizedString("HeaderFavoriteArtists");
+ case StubType.FavoriteSongs: return _localization.GetLocalizedString("HeaderFavoriteSongs");
+ case StubType.ContinueWatching: return _localization.GetLocalizedString("HeaderContinueWatching");
+ case StubType.Movies: return _localization.GetLocalizedString("Movies");
+ case StubType.Collections: return _localization.GetLocalizedString("Collections");
+ case StubType.Favorites: return _localization.GetLocalizedString("Favorites");
+ case StubType.NextUp: return _localization.GetLocalizedString("HeaderNextUp");
+ case StubType.FavoriteSeries: return _localization.GetLocalizedString("HeaderFavoriteShows");
+ case StubType.FavoriteEpisodes: return _localization.GetLocalizedString("HeaderFavoriteEpisodes");
+ case StubType.Series: return _localization.GetLocalizedString("Shows");
+ default: break;
+ }
}
- var episode = item as Episode;
- var season = context as Season;
-
- if (episode != null && season != null)
+ if (item is Episode episode && context is Season season)
{
// This is a special embedded within a season
- if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0)
+ if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0
+ && season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
{
- if (season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
- {
- return string.Format(_localization.GetLocalizedString("ValueSpecialEpisodeName"), item.Name);
- }
+ return string.Format(_localization.GetLocalizedString("ValueSpecialEpisodeName"), item.Name);
}
if (item.IndexNumber.HasValue)
@@ -585,10 +546,8 @@ namespace Emby.Dlna.Didl
public static bool IsIdRoot(string id)
{
- if (string.IsNullOrWhiteSpace(id) ||
-
- string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
-
+ if (string.IsNullOrWhiteSpace(id)
+ || string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
// Samsung sometimes uses 1 as root
|| string.Equals(id, "1", StringComparison.OrdinalIgnoreCase))
{
@@ -1112,7 +1071,7 @@ namespace Emby.Dlna.Didl
};
}
- class ImageDownloadInfo
+ private class ImageDownloadInfo
{
internal Guid ItemId;
internal string ImageTag;
@@ -1128,7 +1087,7 @@ namespace Emby.Dlna.Didl
internal ItemImageInfo ItemImageInfo;
}
- class ImageUrlInfo
+ private class ImageUrlInfo
{
internal string Url;
diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs
index 7398b24cd..a20006578 100644
--- a/Emby.Dlna/Main/DlnaEntryPoint.cs
+++ b/Emby.Dlna/Main/DlnaEntryPoint.cs
@@ -20,7 +20,6 @@ using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.System;
-using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
using Rssdp;
@@ -49,8 +48,7 @@ namespace Emby.Dlna.Main
private readonly IDeviceDiscovery _deviceDiscovery;
private SsdpDevicePublisher _Publisher;
-
- private readonly ITimerFactory _timerFactory;
+
private readonly ISocketFactory _socketFactory;
private readonly IEnvironmentInfo _environmentInfo;
private readonly INetworkManager _networkManager;
@@ -78,7 +76,6 @@ namespace Emby.Dlna.Main
IDeviceDiscovery deviceDiscovery,
IMediaEncoder mediaEncoder,
ISocketFactory socketFactory,
- ITimerFactory timerFactory,
IEnvironmentInfo environmentInfo,
INetworkManager networkManager,
IUserViewManager userViewManager,
@@ -99,7 +96,6 @@ namespace Emby.Dlna.Main
_deviceDiscovery = deviceDiscovery;
_mediaEncoder = mediaEncoder;
_socketFactory = socketFactory;
- _timerFactory = timerFactory;
_environmentInfo = environmentInfo;
_networkManager = networkManager;
_logger = loggerFactory.CreateLogger("Dlna");
@@ -233,7 +229,7 @@ namespace Emby.Dlna.Main
try
{
- _Publisher = new SsdpDevicePublisher(_communicationsServer, _timerFactory, _environmentInfo.OperatingSystemName, _environmentInfo.OperatingSystemVersion);
+ _Publisher = new SsdpDevicePublisher(_communicationsServer, _environmentInfo.OperatingSystemName, _environmentInfo.OperatingSystemVersion);
_Publisher.LogFunction = LogMessage;
_Publisher.SupportPnpRootDevice = false;
@@ -353,8 +349,7 @@ namespace Emby.Dlna.Main
_userDataManager,
_localization,
_mediaSourceManager,
- _mediaEncoder,
- _timerFactory);
+ _mediaEncoder);
_manager.Start();
}
diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs
index 85a522d1c..037cdd8aa 100644
--- a/Emby.Dlna/PlayTo/Device.cs
+++ b/Emby.Dlna/PlayTo/Device.cs
@@ -10,7 +10,6 @@ using Emby.Dlna.Server;
using Emby.Dlna.Ssdp;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.PlayTo
@@ -19,7 +18,7 @@ namespace Emby.Dlna.PlayTo
{
#region Fields & Properties
- private ITimer _timer;
+ private Timer _timer;
public DeviceInfo Properties { get; set; }
@@ -40,12 +39,7 @@ namespace Emby.Dlna.PlayTo
public TimeSpan? Duration { get; set; }
- private TimeSpan _position = TimeSpan.FromSeconds(0);
- public TimeSpan Position
- {
- get => _position;
- set => _position = value;
- }
+ public TimeSpan Position { get; set; } = TimeSpan.FromSeconds(0);
public TRANSPORTSTATE TransportState { get; private set; }
@@ -61,24 +55,20 @@ namespace Emby.Dlna.PlayTo
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
- public DateTime DateLastActivity { get; private set; }
public Action OnDeviceUnavailable { get; set; }
- private readonly ITimerFactory _timerFactory;
-
- public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config, ITimerFactory timerFactory)
+ public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config)
{
Properties = deviceProperties;
_httpClient = httpClient;
_logger = logger;
_config = config;
- _timerFactory = timerFactory;
}
public void Start()
{
_logger.LogDebug("Dlna Device.Start");
- _timer = _timerFactory.Create(TimerCallback, null, 1000, Timeout.Infinite);
+ _timer = new Timer(TimerCallback, null, 1000, Timeout.Infinite);
}
private DateTime _lastVolumeRefresh;
@@ -119,7 +109,9 @@ namespace Emby.Dlna.PlayTo
lock (_timerLock)
{
if (_disposed)
+ {
return;
+ }
_volumeRefreshActive = true;
@@ -136,7 +128,9 @@ namespace Emby.Dlna.PlayTo
lock (_timerLock)
{
if (_disposed)
+ {
return;
+ }
_volumeRefreshActive = false;
@@ -144,11 +138,6 @@ namespace Emby.Dlna.PlayTo
}
}
- public void OnPlaybackStartedExternally()
- {
- RestartTimer(true);
- }
-
#region Commanding
public Task VolumeDown(CancellationToken cancellationToken)
@@ -333,7 +322,9 @@ namespace Emby.Dlna.PlayTo
private string CreateDidlMeta(string value)
{
if (string.IsNullOrEmpty(value))
+ {
return string.Empty;
+ }
return DescriptionXmlBuilder.Escape(value);
}
@@ -342,10 +333,11 @@ namespace Emby.Dlna.PlayTo
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Play");
if (command == null)
+ {
return Task.CompletedTask;
+ }
var service = GetAvTransportService();
-
if (service == null)
{
throw new InvalidOperationException("Unable to find service");
@@ -369,7 +361,9 @@ namespace Emby.Dlna.PlayTo
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Stop");
if (command == null)
+ {
return;
+ }
var service = GetAvTransportService();
@@ -385,7 +379,9 @@ namespace Emby.Dlna.PlayTo
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Pause");
if (command == null)
+ {
return;
+ }
var service = GetAvTransportService();
@@ -405,7 +401,9 @@ namespace Emby.Dlna.PlayTo
private async void TimerCallback(object sender)
{
if (_disposed)
+ {
return;
+ }
try
{
@@ -425,8 +423,6 @@ namespace Emby.Dlna.PlayTo
return;
}
- DateLastActivity = DateTime.UtcNow;
-
if (transportState.HasValue)
{
// If we're not playing anything no need to get additional data
@@ -505,7 +501,9 @@ namespace Emby.Dlna.PlayTo
var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetVolume");
if (command == null)
+ {
return;
+ }
var service = GetServiceRenderingControl();
@@ -518,13 +516,17 @@ namespace Emby.Dlna.PlayTo
.ConfigureAwait(false);
if (result == null || result.Document == null)
+ {
return;
+ }
var volume = result.Document.Descendants(uPnpNamespaces.RenderingControl + "GetVolumeResponse").Select(i => i.Element("CurrentVolume")).FirstOrDefault(i => i != null);
- var volumeValue = volume == null ? null : volume.Value;
+ var volumeValue = volume?.Value;
if (string.IsNullOrWhiteSpace(volumeValue))
+ {
return;
+ }
Volume = int.Parse(volumeValue, UsCulture);
@@ -545,7 +547,9 @@ namespace Emby.Dlna.PlayTo
var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMute");
if (command == null)
+ {
return;
+ }
var service = GetServiceRenderingControl();
@@ -560,39 +564,44 @@ namespace Emby.Dlna.PlayTo
if (result == null || result.Document == null)
return;
- var valueNode = result.Document.Descendants(uPnpNamespaces.RenderingControl + "GetMuteResponse").Select(i => i.Element("CurrentMute")).FirstOrDefault(i => i != null);
- var value = valueNode == null ? null : valueNode.Value;
+ var valueNode = result.Document.Descendants(uPnpNamespaces.RenderingControl + "GetMuteResponse")
+ .Select(i => i.Element("CurrentMute"))
+ .FirstOrDefault(i => i != null);
- IsMuted = string.Equals(value, "1", StringComparison.OrdinalIgnoreCase);
+ IsMuted = string.Equals(valueNode?.Value, "1", StringComparison.OrdinalIgnoreCase);
}
private async Task<TRANSPORTSTATE?> GetTransportInfo(TransportCommands avCommands, CancellationToken cancellationToken)
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetTransportInfo");
if (command == null)
+ {
return null;
+ }
var service = GetAvTransportService();
if (service == null)
+ {
return null;
+ }
var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false);
if (result == null || result.Document == null)
+ {
return null;
+ }
var transportState =
result.Document.Descendants(uPnpNamespaces.AvTransport + "GetTransportInfoResponse").Select(i => i.Element("CurrentTransportState")).FirstOrDefault(i => i != null);
var transportStateValue = transportState == null ? null : transportState.Value;
- if (transportStateValue != null)
+ if (transportStateValue != null
+ && Enum.TryParse(transportStateValue, true, out TRANSPORTSTATE state))
{
- if (Enum.TryParse(transportStateValue, true, out TRANSPORTSTATE state))
- {
- return state;
- }
+ return state;
}
return null;
@@ -602,10 +611,11 @@ namespace Emby.Dlna.PlayTo
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMediaInfo");
if (command == null)
+ {
return null;
+ }
var service = GetAvTransportService();
-
if (service == null)
{
throw new InvalidOperationException("Unable to find service");
@@ -617,7 +627,9 @@ namespace Emby.Dlna.PlayTo
.ConfigureAwait(false);
if (result == null || result.Document == null)
+ {
return null;
+ }
var track = result.Document.Descendants("CurrentURIMetaData").FirstOrDefault();
@@ -657,11 +669,13 @@ namespace Emby.Dlna.PlayTo
return null;
}
- private async Task<Tuple<bool, uBaseObject>> GetPositionInfo(TransportCommands avCommands, CancellationToken cancellationToken)
+ private async Task<(bool, uBaseObject)> GetPositionInfo(TransportCommands avCommands, CancellationToken cancellationToken)
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetPositionInfo");
if (command == null)
- return new Tuple<bool, uBaseObject>(false, null);
+ {
+ return (false, null);
+ }
var service = GetAvTransportService();
@@ -676,7 +690,9 @@ namespace Emby.Dlna.PlayTo
.ConfigureAwait(false);
if (result == null || result.Document == null)
- return new Tuple<bool, uBaseObject>(false, null);
+ {
+ return (false, null);
+ }
var trackUriElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackURI")).FirstOrDefault(i => i != null);
var trackUri = trackUriElem == null ? null : trackUriElem.Value;
@@ -684,8 +700,8 @@ namespace Emby.Dlna.PlayTo
var durationElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackDuration")).FirstOrDefault(i => i != null);
var duration = durationElem == null ? null : durationElem.Value;
- if (!string.IsNullOrWhiteSpace(duration) &&
- !string.Equals(duration, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
+ if (!string.IsNullOrWhiteSpace(duration)
+ && !string.Equals(duration, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
{
Duration = TimeSpan.Parse(duration, UsCulture);
}
@@ -707,14 +723,14 @@ namespace Emby.Dlna.PlayTo
if (track == null)
{
//If track is null, some vendors do this, use GetMediaInfo instead
- return new Tuple<bool, uBaseObject>(true, null);
+ return (true, null);
}
var trackString = (string)track;
if (string.IsNullOrWhiteSpace(trackString) || string.Equals(trackString, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
{
- return new Tuple<bool, uBaseObject>(true, null);
+ return (true, null);
}
XElement uPnpResponse;
@@ -735,7 +751,7 @@ namespace Emby.Dlna.PlayTo
catch (Exception ex)
{
_logger.LogError(ex, "Unable to parse xml {0}", trackString);
- return new Tuple<bool, uBaseObject>(true, null);
+ return (true, null);
}
}
@@ -743,7 +759,7 @@ namespace Emby.Dlna.PlayTo
var uTrack = CreateUBaseObject(e, trackUri);
- return new Tuple<bool, uBaseObject>(true, uTrack);
+ return (true, uTrack);
}
private static uBaseObject CreateUBaseObject(XElement container, string trackUri)
@@ -801,11 +817,9 @@ namespace Emby.Dlna.PlayTo
private async Task<TransportCommands> GetAVProtocolAsync(CancellationToken cancellationToken)
{
- var avCommands = AvCommands;
-
- if (avCommands != null)
+ if (AvCommands != null)
{
- return avCommands;
+ return AvCommands;
}
if (_disposed)
@@ -825,18 +839,15 @@ namespace Emby.Dlna.PlayTo
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
- avCommands = TransportCommands.Create(document);
- AvCommands = avCommands;
- return avCommands;
+ AvCommands = TransportCommands.Create(document);
+ return AvCommands;
}
private async Task<TransportCommands> GetRenderingProtocolAsync(CancellationToken cancellationToken)
{
- var rendererCommands = RendererCommands;
-
- if (rendererCommands != null)
+ if (RendererCommands != null)
{
- return rendererCommands;
+ return RendererCommands;
}
if (_disposed)
@@ -845,7 +856,6 @@ namespace Emby.Dlna.PlayTo
}
var avService = GetServiceRenderingControl();
-
if (avService == null)
{
throw new ArgumentException("Device AvService is null");
@@ -857,9 +867,8 @@ namespace Emby.Dlna.PlayTo
_logger.LogDebug("Dlna Device.GetRenderingProtocolAsync");
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
- rendererCommands = TransportCommands.Create(document);
- RendererCommands = rendererCommands;
- return rendererCommands;
+ RendererCommands = TransportCommands.Create(document);
+ return RendererCommands;
}
private string NormalizeUrl(string baseUrl, string url)
@@ -871,33 +880,28 @@ namespace Emby.Dlna.PlayTo
}
if (!url.Contains("/"))
+ {
url = "/dmr/" + url;
+ }
+
if (!url.StartsWith("/"))
+ {
url = "/" + url;
+ }
return baseUrl + url;
}
- private TransportCommands AvCommands
- {
- get;
- set;
- }
+ private TransportCommands AvCommands { get; set; }
- private TransportCommands RendererCommands
- {
- get;
- set;
- }
+ private TransportCommands RendererCommands { get; set; }
- public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory, CancellationToken cancellationToken)
+ public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, CancellationToken cancellationToken)
{
var ssdpHttpClient = new SsdpHttpClient(httpClient, config);
var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false);
- var deviceProperties = new DeviceInfo();
-
var friendlyNames = new List<string>();
var name = document.Descendants(uPnpNamespaces.ud.GetName("friendlyName")).FirstOrDefault();
@@ -912,7 +916,11 @@ namespace Emby.Dlna.PlayTo
friendlyNames.Add(room.Value);
}
- deviceProperties.Name = string.Join(" ", friendlyNames);
+ var deviceProperties = new DeviceInfo()
+ {
+ Name = string.Join(" ", friendlyNames),
+ BaseUrl = string.Format("http://{0}:{1}", url.Host, url.Port)
+ };
var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault();
if (model != null)
@@ -968,8 +976,6 @@ namespace Emby.Dlna.PlayTo
deviceProperties.ModelDescription = modelDescription.Value;
}
- deviceProperties.BaseUrl = string.Format("http://{0}:{1}", url.Host, url.Port);
-
var icon = document.Descendants(uPnpNamespaces.ud.GetName("icon")).FirstOrDefault();
if (icon != null)
{
@@ -984,7 +990,6 @@ namespace Emby.Dlna.PlayTo
}
var servicesList = services.Descendants(uPnpNamespaces.ud.GetName("service"));
-
if (servicesList == null)
{
continue;
@@ -1001,9 +1006,7 @@ namespace Emby.Dlna.PlayTo
}
}
- var device = new Device(deviceProperties, httpClient, logger, config, timerFactory);
-
- return device;
+ return new Device(deviceProperties, httpClient, logger, config);
}
#endregion
@@ -1131,23 +1134,29 @@ namespace Emby.Dlna.PlayTo
#region IDisposable
bool _disposed;
+
public void Dispose()
{
- if (!_disposed)
- {
- _disposed = true;
-
- DisposeTimer();
- }
+ Dispose(true);
+ GC.SuppressFinalize(this);
}
- private void DisposeTimer()
+ protected virtual void Dispose(bool disposing)
{
- if (_timer != null)
+ if (_disposed)
{
- _timer.Dispose();
- _timer = null;
+ return;
}
+
+ if (disposing)
+ {
+ _timer?.Dispose();
+ }
+
+ _timer = null;
+ Properties = null;
+
+ _disposed = true;
}
#endregion
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs
index 409b8442c..be86dde16 100644
--- a/Emby.Dlna/PlayTo/PlayToController.cs
+++ b/Emby.Dlna/PlayTo/PlayToController.cs
@@ -42,30 +42,43 @@ namespace Emby.Dlna.PlayTo
private readonly IDeviceDiscovery _deviceDiscovery;
private readonly string _serverAddress;
private readonly string _accessToken;
- private readonly DateTime _creationTime;
public bool IsSessionActive => !_disposed && _device != null;
public bool SupportsMediaControl => IsSessionActive;
- public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, IDeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IConfigurationManager config, IMediaEncoder mediaEncoder)
+ public PlayToController(
+ SessionInfo session,
+ ISessionManager sessionManager,
+ ILibraryManager libraryManager,
+ ILogger logger,
+ IDlnaManager dlnaManager,
+ IUserManager userManager,
+ IImageProcessor imageProcessor,
+ string serverAddress,
+ string accessToken,
+ IDeviceDiscovery deviceDiscovery,
+ IUserDataManager userDataManager,
+ ILocalizationManager localization,
+ IMediaSourceManager mediaSourceManager,
+ IConfigurationManager config,
+ IMediaEncoder mediaEncoder)
{
_session = session;
_sessionManager = sessionManager;
_libraryManager = libraryManager;
+ _logger = logger;
_dlnaManager = dlnaManager;
_userManager = userManager;
_imageProcessor = imageProcessor;
_serverAddress = serverAddress;
+ _accessToken = accessToken;
_deviceDiscovery = deviceDiscovery;
_userDataManager = userDataManager;
_localization = localization;
_mediaSourceManager = mediaSourceManager;
_config = config;
_mediaEncoder = mediaEncoder;
- _accessToken = accessToken;
- _logger = logger;
- _creationTime = DateTime.UtcNow;
}
public void Init(Device device)
@@ -374,9 +387,7 @@ namespace Emby.Dlna.PlayTo
return _device.IsPaused ? _device.SetPlay(CancellationToken.None) : _device.SetPause(CancellationToken.None);
case PlaystateCommand.Seek:
- {
- return Seek(command.SeekPositionTicks ?? 0);
- }
+ return Seek(command.SeekPositionTicks ?? 0);
case PlaystateCommand.NextTrack:
return SetPlaylistIndex(_currentPlaylistIndex + 1);
@@ -442,8 +453,7 @@ namespace Emby.Dlna.PlayTo
var profile = _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification()) ??
_dlnaManager.GetDefaultProfile();
- var hasMediaSources = item as IHasMediaSources;
- var mediaSources = hasMediaSources != null
+ var mediaSources = item is IHasMediaSources
? (_mediaSourceManager.GetStaticMediaSources(item, true, user))
: new List<MediaSourceInfo>();
@@ -452,7 +462,7 @@ namespace Emby.Dlna.PlayTo
playlistItem.StreamUrl = DidlBuilder.NormalizeDlnaMediaUrl(playlistItem.StreamInfo.ToUrl(_serverAddress, _accessToken));
- var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _libraryManager, _mediaEncoder)
+ var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _mediaEncoder)
.GetItemDidl(_config.GetDlnaConfiguration(), item, user, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo);
playlistItem.Didl = itemXml;
diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs
index 790625705..6cce312ee 100644
--- a/Emby.Dlna/PlayTo/PlayToManager.cs
+++ b/Emby.Dlna/PlayTo/PlayToManager.cs
@@ -16,7 +16,6 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Session;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.PlayTo
@@ -39,13 +38,12 @@ namespace Emby.Dlna.PlayTo
private readonly IDeviceDiscovery _deviceDiscovery;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IMediaEncoder _mediaEncoder;
- private readonly ITimerFactory _timerFactory;
private bool _disposed;
private SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1);
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
- public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory)
+ public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder)
{
_logger = logger;
_sessionManager = sessionManager;
@@ -61,7 +59,6 @@ namespace Emby.Dlna.PlayTo
_localization = localization;
_mediaSourceManager = mediaSourceManager;
_mediaEncoder = mediaEncoder;
- _timerFactory = timerFactory;
}
public void Start()
@@ -168,7 +165,7 @@ namespace Emby.Dlna.PlayTo
if (controller == null)
{
- var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false);
+ var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, cancellationToken).ConfigureAwait(false);
string deviceName = device.Properties.Name;
diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs
index 89a88705f..298f68a28 100644
--- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs
@@ -5,7 +5,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Net;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
using Rssdp;
using Rssdp.Infrastructure;
@@ -48,20 +47,17 @@ namespace Emby.Dlna.Ssdp
private SsdpDeviceLocator _deviceLocator;
- private readonly ITimerFactory _timerFactory;
private readonly ISocketFactory _socketFactory;
private ISsdpCommunicationsServer _commsServer;
public DeviceDiscovery(
ILoggerFactory loggerFactory,
IServerConfigurationManager config,
- ISocketFactory socketFactory,
- ITimerFactory timerFactory)
+ ISocketFactory socketFactory)
{
_logger = loggerFactory.CreateLogger(nameof(DeviceDiscovery));
_config = config;
_socketFactory = socketFactory;
- _timerFactory = timerFactory;
}
// Call this method from somewhere in your code to start the search.
@@ -78,7 +74,7 @@ namespace Emby.Dlna.Ssdp
{
if (_listenerCount > 0 && _deviceLocator == null)
{
- _deviceLocator = new SsdpDeviceLocator(_commsServer, _timerFactory);
+ _deviceLocator = new SsdpDeviceLocator(_commsServer);
// (Optional) Set the filter so we only see notifications for devices we care about
// (can be any search target value i.e device type, uuid value etc - any value that appears in the
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index f229d9a0b..faaeb5af8 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -83,8 +83,8 @@ namespace Emby.Drawing
}
}
- public string[] SupportedInputFormats =>
- new string[]
+ public IReadOnlyCollection<string> SupportedInputFormats =>
+ new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"tiff",
"tif",
@@ -137,14 +137,14 @@ namespace Emby.Drawing
}
}
- public ImageFormat[] GetSupportedImageOutputFormats()
- {
- return _imageEncoder.SupportedOutputFormats;
- }
+ public IReadOnlyCollection<ImageFormat> GetSupportedImageOutputFormats()
+ => _imageEncoder.SupportedOutputFormats;
+
+ private static readonly HashSet<string> TransparentImageTypes
+ = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".png", ".webp", ".gif" };
- private static readonly string[] TransparentImageTypes = new string[] { ".png", ".webp", ".gif" };
public bool SupportsTransparency(string path)
- => TransparentImageTypes.Contains(Path.GetExtension(path).ToLowerInvariant());
+ => TransparentImageTypes.Contains(Path.GetExtension(path));
public async Task<(string path, string mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options)
{
@@ -261,15 +261,6 @@ namespace Emby.Drawing
return (cacheFilePath, GetMimeType(outputFormat, cacheFilePath), _fileSystem.GetLastWriteTimeUtc(cacheFilePath));
}
- catch (ArgumentOutOfRangeException ex)
- {
- // Decoder failed to decode it
-#if DEBUG
- _logger.LogError(ex, "Error encoding image");
-#endif
- // Just spit out the original file if all the options are default
- return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
- }
catch (Exception ex)
{
// If it fails for whatever reason, return the original image
@@ -377,10 +368,10 @@ namespace Emby.Drawing
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLowerInvariant());
}
- public ImageDimensions GetImageSize(BaseItem item, ItemImageInfo info)
- => GetImageSize(item, info, true);
+ public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info)
+ => GetImageDimensions(item, info, true);
- public ImageDimensions GetImageSize(BaseItem item, ItemImageInfo info, bool updateItem)
+ public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem)
{
int width = info.Width;
int height = info.Height;
@@ -393,7 +384,7 @@ namespace Emby.Drawing
string path = info.Path;
_logger.LogInformation("Getting image size for item {ItemType} {Path}", item.GetType().Name, path);
- ImageDimensions size = GetImageSize(path);
+ ImageDimensions size = GetImageDimensions(path);
info.Width = size.Width;
info.Height = size.Height;
@@ -408,7 +399,7 @@ namespace Emby.Drawing
/// <summary>
/// Gets the size of the image.
/// </summary>
- public ImageDimensions GetImageSize(string path)
+ public ImageDimensions GetImageDimensions(string path)
=> _imageEncoder.GetImageSize(path);
/// <summary>
@@ -481,7 +472,7 @@ namespace Emby.Drawing
return (originalImagePath, dateModified);
}
- if (!_imageEncoder.SupportedInputFormats.Contains(inputFormat, StringComparer.OrdinalIgnoreCase))
+ if (!_imageEncoder.SupportedInputFormats.Contains(inputFormat))
{
try
{
diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs
index 14f0424ac..fc4a5af9f 100644
--- a/Emby.Drawing/NullImageEncoder.cs
+++ b/Emby.Drawing/NullImageEncoder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Model.Drawing;
@@ -6,15 +7,11 @@ namespace Emby.Drawing
{
public class NullImageEncoder : IImageEncoder
{
- public string[] SupportedInputFormats =>
- new[]
- {
- "png",
- "jpeg",
- "jpg"
- };
-
- public ImageFormat[] SupportedOutputFormats => new[] { ImageFormat.Jpg, ImageFormat.Png };
+ public IReadOnlyCollection<string> SupportedInputFormats
+ => new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "png", "jpeg", "jpg" };
+
+ public IReadOnlyCollection<ImageFormat> SupportedOutputFormats
+ => new HashSet<ImageFormat>() { ImageFormat.Jpg, ImageFormat.Png };
public void CropWhiteSpace(string inputPath, string outputPath)
{
diff --git a/Emby.Notifications/Notifications.cs b/Emby.Notifications/Notifications.cs
index 045aa6f16..d3290479f 100644
--- a/Emby.Notifications/Notifications.cs
+++ b/Emby.Notifications/Notifications.cs
@@ -20,7 +20,6 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Notifications;
using MediaBrowser.Model.Tasks;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Notifications
@@ -40,9 +39,8 @@ namespace Emby.Notifications
private readonly ILibraryManager _libraryManager;
private readonly ISessionManager _sessionManager;
private readonly IServerApplicationHost _appHost;
- private readonly ITimerFactory _timerFactory;
- private ITimer LibraryUpdateTimer { get; set; }
+ private Timer LibraryUpdateTimer { get; set; }
private readonly object _libraryChangedSyncLock = new object();
private readonly IConfigurationManager _config;
@@ -52,7 +50,7 @@ namespace Emby.Notifications
private string[] _coreNotificationTypes;
- public Notifications(IInstallationManager installationManager, IActivityManager activityManager, ILocalizationManager localization, IUserManager userManager, ILogger logger, ITaskManager taskManager, INotificationManager notificationManager, ILibraryManager libraryManager, ISessionManager sessionManager, IServerApplicationHost appHost, IConfigurationManager config, IDeviceManager deviceManager, ITimerFactory timerFactory)
+ public Notifications(IInstallationManager installationManager, IActivityManager activityManager, ILocalizationManager localization, IUserManager userManager, ILogger logger, ITaskManager taskManager, INotificationManager notificationManager, ILibraryManager libraryManager, ISessionManager sessionManager, IServerApplicationHost appHost, IConfigurationManager config, IDeviceManager deviceManager)
{
_installationManager = installationManager;
_userManager = userManager;
@@ -64,7 +62,6 @@ namespace Emby.Notifications
_appHost = appHost;
_config = config;
_deviceManager = deviceManager;
- _timerFactory = timerFactory;
_localization = localization;
_activityManager = activityManager;
@@ -159,7 +156,7 @@ namespace Emby.Notifications
{
if (LibraryUpdateTimer == null)
{
- LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, 5000,
+ LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, 5000,
Timeout.Infinite);
}
else
diff --git a/Emby.Photos/PhotoProvider.cs b/Emby.Photos/PhotoProvider.cs
index aaebe1a21..f3457d105 100644
--- a/Emby.Photos/PhotoProvider.cs
+++ b/Emby.Photos/PhotoProvider.cs
@@ -181,7 +181,7 @@ namespace Emby.Photos
try
{
- var size = _imageProcessor.GetImageSize(item, img, false);
+ var size = _imageProcessor.GetImageDimensions(item, img, false);
if (size.Width > 0 && size.Height > 0)
{
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 365eb5856..bb475eb2c 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -12,7 +12,6 @@ using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using Emby.Common.Implementations.Serialization;
using Emby.Dlna;
using Emby.Dlna.Main;
using Emby.Dlna.Ssdp;
@@ -43,7 +42,6 @@ using Emby.Server.Implementations.ScheduledTasks;
using Emby.Server.Implementations.Security;
using Emby.Server.Implementations.Serialization;
using Emby.Server.Implementations.Session;
-using Emby.Server.Implementations.Threading;
using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates;
using Emby.Server.Implementations.Xml;
@@ -99,7 +97,6 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
-using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Updates;
using MediaBrowser.Model.Xml;
using MediaBrowser.Providers.Chapters;
@@ -347,7 +344,6 @@ namespace Emby.Server.Implementations
internal IImageEncoder ImageEncoder { get; private set; }
protected IProcessFactory ProcessFactory { get; private set; }
- protected ITimerFactory TimerFactory { get; private set; }
protected ICryptoProvider CryptographyProvider = new CryptographyProvider();
protected readonly IXmlSerializer XmlSerializer;
@@ -772,9 +768,6 @@ namespace Emby.Server.Implementations
ProcessFactory = new ProcessFactory();
RegisterSingleInstance(ProcessFactory);
- TimerFactory = new TimerFactory();
- RegisterSingleInstance(TimerFactory);
-
var streamHelper = CreateStreamHelper();
ApplicationHost.StreamHelper = streamHelper;
RegisterSingleInstance(streamHelper);
@@ -837,7 +830,7 @@ namespace Emby.Server.Implementations
var musicManager = new MusicManager(LibraryManager);
RegisterSingleInstance<IMusicManager>(new MusicManager(LibraryManager));
- LibraryMonitor = new LibraryMonitor(LoggerFactory, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory, EnvironmentInfo);
+ LibraryMonitor = new LibraryMonitor(LoggerFactory, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, EnvironmentInfo);
RegisterSingleInstance(LibraryMonitor);
RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LoggerFactory, LibraryManager, UserManager));
@@ -869,7 +862,7 @@ namespace Emby.Server.Implementations
DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LoggerFactory, NetworkManager);
RegisterSingleInstance(DeviceManager);
- MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, TimerFactory, () => MediaEncoder);
+ MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder);
RegisterSingleInstance(MediaSourceManager);
SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager);
@@ -884,7 +877,7 @@ namespace Emby.Server.Implementations
ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager);
RegisterSingleInstance(ChannelManager);
- SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager, TimerFactory);
+ SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager);
RegisterSingleInstance(SessionManager);
var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this, assemblyInfo);
@@ -905,7 +898,7 @@ namespace Emby.Server.Implementations
NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager);
RegisterSingleInstance(NotificationManager);
- RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory, TimerFactory));
+ RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory));
ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository);
RegisterSingleInstance(ChapterManager);
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index f5634690f..983eb51e6 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -1418,7 +1418,7 @@ namespace Emby.Server.Implementations.Dto
try
{
- size = _imageProcessor.GetImageSize(item, imageInfo);
+ size = _imageProcessor.GetImageDimensions(item, imageInfo);
if (size.Width <= 0 || size.Height <= 0)
{
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 92e3172f1..af01001a5 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -43,7 +43,7 @@
<EmbeddedResource Include="Localization\iso6392.txt" />
<EmbeddedResource Include="Localization\countries.json" />
<EmbeddedResource Include="Localization\Core\*.json" />
- <EmbeddedResource Include="Localization\Ratings\*.txt" />
+ <EmbeddedResource Include="Localization\Ratings\*.csv" />
</ItemGroup>
</Project>
diff --git a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
index 361656ff2..19ea09359 100644
--- a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
@@ -9,7 +9,6 @@ using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Tasks;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
@@ -22,11 +21,10 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly ISessionManager _sessionManager;
private readonly IServerConfigurationManager _config;
private readonly ILiveTvManager _liveTvManager;
- private readonly ITimerFactory _timerFactory;
- private ITimer _timer;
+ private Timer _timer;
- public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager, ITimerFactory timerFactory)
+ public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager)
{
_appHost = appHost;
_logger = logger;
@@ -34,7 +32,6 @@ namespace Emby.Server.Implementations.EntryPoints
_sessionManager = sessionManager;
_config = config;
_liveTvManager = liveTvManager;
- _timerFactory = timerFactory;
}
public Task RunAsync()
@@ -53,7 +50,7 @@ namespace Emby.Server.Implementations.EntryPoints
if (_appHost.HasPendingRestart)
{
- _timer = _timerFactory.Create(TimerCallback, null, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(15));
+ _timer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(15));
}
}
diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 56c730c80..f26a70586 100644
--- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -10,7 +10,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
using Mono.Nat;
@@ -24,19 +23,17 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly IServerConfigurationManager _config;
private readonly IDeviceDiscovery _deviceDiscovery;
- private ITimer _timer;
- private readonly ITimerFactory _timerFactory;
+ private Timer _timer;
private NatManager _natManager;
- public ExternalPortForwarding(ILoggerFactory loggerFactory, IServerApplicationHost appHost, IServerConfigurationManager config, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, ITimerFactory timerFactory)
+ public ExternalPortForwarding(ILoggerFactory loggerFactory, IServerApplicationHost appHost, IServerConfigurationManager config, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient)
{
_logger = loggerFactory.CreateLogger("PortMapper");
_appHost = appHost;
_config = config;
_deviceDiscovery = deviceDiscovery;
_httpClient = httpClient;
- _timerFactory = timerFactory;
_config.ConfigurationUpdated += _config_ConfigurationUpdated1;
}
@@ -94,7 +91,7 @@ namespace Emby.Server.Implementations.EntryPoints
_natManager.StartDiscovery();
}
- _timer = _timerFactory.Create(ClearCreatedRules, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));
+ _timer = new Timer(ClearCreatedRules, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index 9b61809c7..038965647 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -14,7 +14,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Extensions;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
@@ -29,7 +28,6 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly ISessionManager _sessionManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger;
- private readonly ITimerFactory _timerFactory;
/// <summary>
/// The _library changed sync lock
@@ -47,7 +45,7 @@ namespace Emby.Server.Implementations.EntryPoints
/// Gets or sets the library update timer.
/// </summary>
/// <value>The library update timer.</value>
- private ITimer LibraryUpdateTimer { get; set; }
+ private Timer LibraryUpdateTimer { get; set; }
/// <summary>
/// The library update duration
@@ -56,13 +54,12 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly IProviderManager _providerManager;
- public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IUserManager userManager, ILogger logger, ITimerFactory timerFactory, IProviderManager providerManager)
+ public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IUserManager userManager, ILogger logger, IProviderManager providerManager)
{
_libraryManager = libraryManager;
_sessionManager = sessionManager;
_userManager = userManager;
_logger = logger;
- _timerFactory = timerFactory;
_providerManager = providerManager;
}
@@ -191,7 +188,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (LibraryUpdateTimer == null)
{
- LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
+ LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
Timeout.Infinite);
}
else
@@ -225,7 +222,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (LibraryUpdateTimer == null)
{
- LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
+ LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
Timeout.Infinite);
}
else
@@ -253,7 +250,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (LibraryUpdateTimer == null)
{
- LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
+ LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
Timeout.Infinite);
}
else
diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
index d91a2d581..774ed09da 100644
--- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
@@ -10,7 +10,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Session;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
@@ -23,19 +22,17 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly IUserManager _userManager;
private readonly object _syncLock = new object();
- private ITimer UpdateTimer { get; set; }
- private readonly ITimerFactory _timerFactory;
+ private Timer UpdateTimer { get; set; }
private const int UpdateDuration = 500;
private readonly Dictionary<Guid, List<BaseItem>> _changedItems = new Dictionary<Guid, List<BaseItem>>();
- public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, ILogger logger, IUserManager userManager, ITimerFactory timerFactory)
+ public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, ILogger logger, IUserManager userManager)
{
_userDataManager = userDataManager;
_sessionManager = sessionManager;
_logger = logger;
_userManager = userManager;
- _timerFactory = timerFactory;
}
public Task RunAsync()
@@ -56,7 +53,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (UpdateTimer == null)
{
- UpdateTimer = _timerFactory.Create(UpdateTimerCallback, null, UpdateDuration,
+ UpdateTimer = new Timer(UpdateTimerCallback, null, UpdateDuration,
Timeout.Infinite);
}
else
diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs
index 1cac0ba5c..3668f6a7a 100644
--- a/Emby.Server.Implementations/IO/FileRefresher.cs
+++ b/Emby.Server.Implementations/IO/FileRefresher.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
@@ -9,7 +10,6 @@ using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.IO
@@ -22,8 +22,7 @@ namespace Emby.Server.Implementations.IO
private IServerConfigurationManager ConfigurationManager { get; set; }
private readonly IFileSystem _fileSystem;
private readonly List<string> _affectedPaths = new List<string>();
- private ITimer _timer;
- private readonly ITimerFactory _timerFactory;
+ private Timer _timer;
private readonly object _timerLock = new object();
public string Path { get; private set; }
@@ -31,7 +30,7 @@ namespace Emby.Server.Implementations.IO
private readonly IEnvironmentInfo _environmentInfo;
private readonly ILibraryManager _libraryManager;
- public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ITaskManager taskManager, ILogger logger, ITimerFactory timerFactory, IEnvironmentInfo environmentInfo, ILibraryManager libraryManager1)
+ public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ITaskManager taskManager, ILogger logger, IEnvironmentInfo environmentInfo, ILibraryManager libraryManager1)
{
logger.LogDebug("New file refresher created for {0}", path);
Path = path;
@@ -41,7 +40,6 @@ namespace Emby.Server.Implementations.IO
LibraryManager = libraryManager;
TaskManager = taskManager;
Logger = logger;
- _timerFactory = timerFactory;
_environmentInfo = environmentInfo;
_libraryManager = libraryManager1;
AddPath(path);
@@ -90,7 +88,7 @@ namespace Emby.Server.Implementations.IO
if (_timer == null)
{
- _timer = _timerFactory.Create(OnTimerCallback, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
+ _timer = new Timer(OnTimerCallback, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
}
else
{
diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs
index 3a746ef60..607a4d333 100644
--- a/Emby.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs
@@ -11,7 +11,6 @@ using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.IO
@@ -35,7 +34,7 @@ namespace Emby.Server.Implementations.IO
/// <summary>
/// Any file name ending in any of these will be ignored by the watchers
/// </summary>
- private readonly string[] _alwaysIgnoreFiles = new string[]
+ private readonly HashSet<string> _alwaysIgnoreFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"small.jpg",
"albumart.jpg",
@@ -54,7 +53,7 @@ namespace Emby.Server.Implementations.IO
".actors"
};
- private readonly string[] _alwaysIgnoreExtensions = new string[]
+ private readonly HashSet<string> _alwaysIgnoreExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
// thumbs.db
".db",
@@ -134,7 +133,6 @@ namespace Emby.Server.Implementations.IO
private IServerConfigurationManager ConfigurationManager { get; set; }
private readonly IFileSystem _fileSystem;
- private readonly ITimerFactory _timerFactory;
private readonly IEnvironmentInfo _environmentInfo;
/// <summary>
@@ -146,7 +144,6 @@ namespace Emby.Server.Implementations.IO
ILibraryManager libraryManager,
IServerConfigurationManager configurationManager,
IFileSystem fileSystem,
- ITimerFactory timerFactory,
IEnvironmentInfo environmentInfo)
{
if (taskManager == null)
@@ -159,7 +156,6 @@ namespace Emby.Server.Implementations.IO
Logger = loggerFactory.CreateLogger(GetType().Name);
ConfigurationManager = configurationManager;
_fileSystem = fileSystem;
- _timerFactory = timerFactory;
_environmentInfo = environmentInfo;
}
@@ -460,8 +456,8 @@ namespace Emby.Server.Implementations.IO
var filename = Path.GetFileName(path);
var monitorPath = !string.IsNullOrEmpty(filename) &&
- !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) &&
- !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase) &&
+ !_alwaysIgnoreFiles.Contains(filename) &&
+ !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path)) &&
_alwaysIgnoreSubstrings.All(i => path.IndexOf(i, StringComparison.OrdinalIgnoreCase) == -1);
// Ignore certain files
@@ -545,7 +541,7 @@ namespace Emby.Server.Implementations.IO
}
}
- var newRefresher = new FileRefresher(path, _fileSystem, ConfigurationManager, LibraryManager, TaskManager, Logger, _timerFactory, _environmentInfo, LibraryManager);
+ var newRefresher = new FileRefresher(path, _fileSystem, ConfigurationManager, LibraryManager, TaskManager, Logger, _environmentInfo, LibraryManager);
newRefresher.Completed += NewRefresher_Completed;
_activeRefreshers.Add(newRefresher);
}
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index 4f72651d4..24ab8e761 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -20,7 +20,6 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library
@@ -36,7 +35,6 @@ namespace Emby.Server.Implementations.Library
private IMediaSourceProvider[] _providers;
private readonly ILogger _logger;
private readonly IUserDataManager _userDataManager;
- private readonly ITimerFactory _timerFactory;
private readonly Func<IMediaEncoder> _mediaEncoder;
private ILocalizationManager _localizationManager;
private IApplicationPaths _appPaths;
@@ -51,7 +49,6 @@ namespace Emby.Server.Implementations.Library
IJsonSerializer jsonSerializer,
IFileSystem fileSystem,
IUserDataManager userDataManager,
- ITimerFactory timerFactory,
Func<IMediaEncoder> mediaEncoder)
{
_itemRepo = itemRepo;
@@ -61,7 +58,6 @@ namespace Emby.Server.Implementations.Library
_jsonSerializer = jsonSerializer;
_fileSystem = fileSystem;
_userDataManager = userDataManager;
- _timerFactory = timerFactory;
_mediaEncoder = mediaEncoder;
_localizationManager = localizationManager;
_appPaths = applicationPaths;
diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
index 9de766767..a3298c580 100644
--- a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using MediaBrowser.Controller.Drawing;
@@ -85,7 +86,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
return false;
}
- private static readonly string[] IgnoreFiles =
+ private static readonly HashSet<string> IgnoreFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"folder",
"thumb",
@@ -102,7 +103,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
{
var filename = Path.GetFileNameWithoutExtension(path) ?? string.Empty;
- if (IgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase))
+ if (IgnoreFiles.Contains(filename))
{
return false;
}
@@ -112,7 +113,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
return false;
}
- return imageProcessor.SupportedInputFormats.Contains((Path.GetExtension(path) ?? string.Empty).TrimStart('.'), StringComparer.OrdinalIgnoreCase);
+ return imageProcessor.SupportedInputFormats.Contains((Path.GetExtension(path) ?? string.Empty).TrimStart('.'));
}
}
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 6dd9366b0..3ff84382f 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -448,30 +448,30 @@ namespace Emby.Server.Implementations.Library
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
{
- if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0)
+ if (user.Policy.InvalidLoginAttemptCount == newValue || newValue <= 0)
{
- user.Policy.InvalidLoginAttemptCount = newValue;
+ return;
+ }
- var maxCount = user.Policy.IsAdministrator ? 3 : 5;
+ user.Policy.InvalidLoginAttemptCount = newValue;
- // TODO: Fix
- /*
- var fireLockout = false;
+ var maxCount = user.Policy.IsAdministrator ? 3 : 5;
- if (newValue >= maxCount)
- {
- _logger.LogDebug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture));
- user.Policy.IsDisabled = true;
+ var fireLockout = false;
- fireLockout = true;
- }*/
+ if (newValue >= maxCount)
+ {
+ _logger.LogDebug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue);
+ user.Policy.IsDisabled = true;
- UpdateUserPolicy(user, user.Policy, false);
+ fireLockout = true;
+ }
- /* if (fireLockout)
- {
- UserLockedOut?.Invoke(this, new GenericEventArgs<User>(user));
- }*/
+ UpdateUserPolicy(user, user.Policy, false);
+
+ if (fireLockout)
+ {
+ UserLockedOut?.Invoke(this, new GenericEventArgs<User>(user));
}
}
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index c5ab568ae..84ca130b7 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -35,7 +35,6 @@ using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Reflection;
using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.LiveTv.EmbyTV
@@ -64,7 +63,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
public static EmbyTV Current;
- public event EventHandler DataSourceChanged;
public event EventHandler<GenericEventArgs<TimerInfo>> TimerCreated;
public event EventHandler<GenericEventArgs<string>> TimerCancelled;
@@ -87,7 +85,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
ILibraryMonitor libraryMonitor,
IProviderManager providerManager,
IMediaEncoder mediaEncoder,
- ITimerFactory timerFactory,
IProcessFactory processFactory)
{
Current = this;
@@ -109,7 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
_streamHelper = streamHelper;
_seriesTimerProvider = new SeriesTimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers"));
- _timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers"), _logger, timerFactory);
+ _timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers"), _logger);
_timerProvider.TimerFired += _timerProvider_TimerFired;
_config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated;
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs
index 7f67d70a9..1dcb02f43 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs
@@ -2,29 +2,27 @@ using System;
using System.Collections.Concurrent;
using System.Globalization;
using System.Linq;
+using System.Threading;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
public class TimerManager : ItemDataProvider<TimerInfo>
{
- private readonly ConcurrentDictionary<string, ITimer> _timers = new ConcurrentDictionary<string, ITimer>(StringComparer.OrdinalIgnoreCase);
+ private readonly ConcurrentDictionary<string, Timer> _timers = new ConcurrentDictionary<string, Timer>(StringComparer.OrdinalIgnoreCase);
private readonly ILogger _logger;
public event EventHandler<GenericEventArgs<TimerInfo>> TimerFired;
- private readonly ITimerFactory _timerFactory;
- public TimerManager(IFileSystem fileSystem, IJsonSerializer jsonSerializer, ILogger logger, string dataPath, ILogger logger1, ITimerFactory timerFactory)
+ public TimerManager(IFileSystem fileSystem, IJsonSerializer jsonSerializer, ILogger logger, string dataPath, ILogger logger1)
: base(fileSystem, jsonSerializer, logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
{
_logger = logger1;
- _timerFactory = timerFactory;
}
public void RestartTimers()
@@ -125,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private void StartTimer(TimerInfo item, TimeSpan dueTime)
{
- var timer = _timerFactory.Create(TimerCallback, item.Id, dueTime, TimeSpan.Zero);
+ var timer = new Timer(TimerCallback, item.Id, dueTime, TimeSpan.Zero);
if (_timers.TryAdd(item.Id, timer))
{
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index f152ac465..69b10e6da 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -17,7 +17,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
using Microsoft.Extensions.Logging;
-namespace Jellyfin.Server.Implementations.LiveTv.Listings
+namespace Emby.Server.Implementations.LiveTv.Listings
{
public class XmlTvListingsProvider : IListingsProvider
{
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index c3437bcda..a36302876 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.LiveTv
private readonly LiveTvDtoService _tvDtoService;
- private ILiveTvService[] _services = new ILiveTvService[] { };
+ private ILiveTvService[] _services = Array.Empty<ILiveTvService>();
private ITunerHost[] _tunerHosts = Array.Empty<ITunerHost>();
private IListingsProvider[] _listingProviders = Array.Empty<IListingsProvider>();
@@ -127,8 +127,6 @@ namespace Emby.Server.Implementations.LiveTv
foreach (var service in _services)
{
- service.DataSourceChanged += service_DataSourceChanged;
-
if (service is EmbyTV.EmbyTV embyTv)
{
embyTv.TimerCreated += EmbyTv_TimerCreated;
@@ -184,14 +182,6 @@ namespace Emby.Server.Implementations.LiveTv
return EmbyTV.EmbyTV.Current.DiscoverTuners(newDevicesOnly, cancellationToken);
}
- void service_DataSourceChanged(object sender, EventArgs e)
- {
- if (!_isDisposed)
- {
- _taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
- }
- }
-
public QueryResult<BaseItem> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken)
{
var user = query.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(query.UserId);
@@ -2153,17 +2143,28 @@ namespace Emby.Server.Implementations.LiveTv
Dispose(true);
}
- private bool _isDisposed = false;
+ private bool _disposed = false;
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
+ if (_disposed)
+ {
+ return;
+ }
+
if (dispose)
{
- _isDisposed = true;
+ // TODO: Dispose stuff
}
+
+ _services = null;
+ _listingProviders = null;
+ _tunerHosts = null;
+
+ _disposed = true;
}
private LiveTvServiceInfo[] GetServiceInfos()
diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs
index 262ca24ec..31217730b 100644
--- a/Emby.Server.Implementations/Localization/LocalizationManager.cs
+++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs
@@ -60,29 +60,35 @@ namespace Emby.Server.Implementations.Localization
public async Task LoadAll()
{
- const string ratingsResource = "Emby.Server.Implementations.Ratings.";
+ const string ratingsResource = "Emby.Server.Implementations.Localization.Ratings.";
Directory.CreateDirectory(LocalizationPath);
var existingFiles = GetRatingsFiles(LocalizationPath).Select(Path.GetFileName);
// Extract from the assembly
- foreach (var resource in _assembly.GetManifestResourceNames()
- .Where(i => i.StartsWith(ratingsResource)))
+ foreach (var resource in _assembly.GetManifestResourceNames())
{
+ if (!resource.StartsWith(ratingsResource))
+ {
+ continue;
+ }
+
string filename = "ratings-" + resource.Substring(ratingsResource.Length);
- if (!existingFiles.Contains(filename))
+ if (existingFiles.Contains(filename))
{
- using (var stream = _assembly.GetManifestResourceStream(resource))
- {
- string target = Path.Combine(LocalizationPath, filename);
- _logger.LogInformation("Extracting ratings to {0}", target);
+ continue;
+ }
- using (var fs = _fileSystem.GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
- {
- await stream.CopyToAsync(fs);
- }
+ using (var stream = _assembly.GetManifestResourceStream(resource))
+ {
+ string target = Path.Combine(LocalizationPath, filename);
+ _logger.LogInformation("Extracting ratings to {0}", target);
+
+ using (var fs = _fileSystem.GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
+ {
+ await stream.CopyToAsync(fs);
}
}
}
@@ -289,7 +295,8 @@ namespace Emby.Server.Implementations.Localization
/// <returns>Dictionary{System.StringParentalRating}.</returns>
private async Task LoadRatings(string file)
{
- Dictionary<string, ParentalRating> dict = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase);
+ Dictionary<string, ParentalRating> dict
+ = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase);
using (var str = File.OpenRead(file))
using (var reader = new StreamReader(str))
@@ -309,7 +316,10 @@ namespace Emby.Server.Implementations.Localization
dict.Add(parts[0], (new ParentalRating { Name = parts[0], Value = value }));
}
#if DEBUG
- _logger.LogWarning("Misformed line in {Path}", file);
+ else
+ {
+ _logger.LogWarning("Misformed line in {Path}", file);
+ }
#endif
}
}
@@ -450,11 +460,19 @@ namespace Emby.Server.Implementations.Localization
{
using (var stream = _assembly.GetManifestResourceStream(resourcePath))
{
- var dict = await _jsonSerializer.DeserializeFromStreamAsync<Dictionary<string, string>>(stream);
+ // 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);
- foreach (var key in dict.Keys)
+ foreach (var key in dict.Keys)
+ {
+ dictionary[key] = dict[key];
+ }
+ }
+ else
{
- dictionary[key] = dict[key];
+ _logger.LogError("Missing translation/culture resource: {ResourcePath}", resourcePath);
}
}
}
@@ -479,29 +497,23 @@ namespace Emby.Server.Implementations.Localization
=> new LocalizationOption[]
{
new LocalizationOption("Arabic", "ar"),
- new LocalizationOption("Belarusian (Belarus)", "be-BY"),
new LocalizationOption("Bulgarian (Bulgaria)", "bg-BG"),
new LocalizationOption("Catalan", "ca"),
new LocalizationOption("Chinese Simplified", "zh-CN"),
new LocalizationOption("Chinese Traditional", "zh-TW"),
- new LocalizationOption("Chinese Traditional (Hong Kong)", "zh-HK"),
new LocalizationOption("Croatian", "hr"),
new LocalizationOption("Czech", "cs"),
new LocalizationOption("Danish", "da"),
new LocalizationOption("Dutch", "nl"),
new LocalizationOption("English (United Kingdom)", "en-GB"),
new LocalizationOption("English (United States)", "en-US"),
- new LocalizationOption("Finnish", "fi"),
new LocalizationOption("French", "fr"),
new LocalizationOption("French (Canada)", "fr-CA"),
new LocalizationOption("German", "de"),
new LocalizationOption("Greek", "el"),
new LocalizationOption("Hebrew", "he"),
- new LocalizationOption("Hindi (India)", "hi-IN"),
new LocalizationOption("Hungarian", "hu"),
- new LocalizationOption("Indonesian", "id"),
new LocalizationOption("Italian", "it"),
- new LocalizationOption("Japanese", "ja"),
new LocalizationOption("Kazakh", "kk"),
new LocalizationOption("Korean", "ko"),
new LocalizationOption("Lithuanian", "lt-LT"),
@@ -511,18 +523,15 @@ namespace Emby.Server.Implementations.Localization
new LocalizationOption("Polish", "pl"),
new LocalizationOption("Portuguese (Brazil)", "pt-BR"),
new LocalizationOption("Portuguese (Portugal)", "pt-PT"),
- new LocalizationOption("Romanian", "ro"),
new LocalizationOption("Russian", "ru"),
new LocalizationOption("Slovak", "sk"),
new LocalizationOption("Slovenian (Slovenia)", "sl-SI"),
new LocalizationOption("Spanish", "es"),
- new LocalizationOption("Spanish (Latin America)", "es-419"),
+ new LocalizationOption("Spanish (Argentina)", "es-AR"),
new LocalizationOption("Spanish (Mexico)", "es-MX"),
new LocalizationOption("Swedish", "sv"),
new LocalizationOption("Swiss German", "gsw"),
- new LocalizationOption("Turkish", "tr"),
- new LocalizationOption("Ukrainian", "uk"),
- new LocalizationOption("Vietnamese", "vi")
+ new LocalizationOption("Turkish", "tr")
};
}
}
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs b/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
index 447cbf403..e4e944839 100644
--- a/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
+++ b/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
@@ -1,11 +1,10 @@
+using System;
using System.Collections.Generic;
+using System.Numerics;
+using System.Text;
-namespace System.Net
+namespace Emby.Server.Implementations.Networking.IPNetwork
{
- using System;
- using System.Numerics;
- using System.Text;
-
/// <summary>
/// Extension methods to convert <see cref="BigInteger"/>
/// instances to hexadecimal, octal, and binary strings.
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs b/Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs
index c5853135c..a0c5f73af 100644
--- a/Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs
+++ b/Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs
@@ -1,8 +1,10 @@
+using System;
using System.Collections;
using System.Collections.Generic;
+using System.Net;
using System.Numerics;
-namespace System.Net
+namespace Emby.Server.Implementations.Networking.IPNetwork
{
public class IPAddressCollection : IEnumerable<IPAddress>, IEnumerator<IPAddress>
{
@@ -29,7 +31,7 @@ namespace System.Net
{
throw new ArgumentOutOfRangeException(nameof(i));
}
- byte width = this._ipnetwork.AddressFamily == Sockets.AddressFamily.InterNetwork ? (byte)32 : (byte)128;
+ byte width = this._ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? (byte)32 : (byte)128;
var ipn = this._ipnetwork.Subnet(width);
return ipn[i].Network;
}
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs b/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
index 16f39daf7..d6de61c0c 100644
--- a/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
+++ b/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
@@ -1,10 +1,12 @@
+using System;
using System.Collections.Generic;
using System.IO;
+using System.Net;
using System.Net.Sockets;
using System.Numerics;
using System.Text.RegularExpressions;
-namespace System.Net
+namespace Emby.Server.Implementations.Networking.IPNetwork
{
/// <summary>
/// IP Network utility class.
@@ -60,7 +62,7 @@ namespace System.Net
get
{
- int width = this._family == Sockets.AddressFamily.InterNetwork ? 4 : 16;
+ int width = this._family == System.Net.Sockets.AddressFamily.InterNetwork ? 4 : 16;
var uintBroadcast = this._network + this._netmask.PositiveReverse(width);
return uintBroadcast;
}
@@ -73,7 +75,7 @@ namespace System.Net
{
get
{
- if (this._family == Sockets.AddressFamily.InterNetworkV6)
+ if (this._family == System.Net.Sockets.AddressFamily.InterNetworkV6)
{
return null;
}
@@ -88,7 +90,7 @@ namespace System.Net
{
get
{
- var fisrt = this._family == Sockets.AddressFamily.InterNetworkV6
+ var fisrt = this._family == System.Net.Sockets.AddressFamily.InterNetworkV6
? this._network
: (this.Usable <= 0) ? this._network : this._network + 1;
return IPNetwork.ToIPAddress(fisrt, this._family);
@@ -102,7 +104,7 @@ namespace System.Net
{
get
{
- var last = this._family == Sockets.AddressFamily.InterNetworkV6
+ var last = this._family == System.Net.Sockets.AddressFamily.InterNetworkV6
? this._broadcast
: (this.Usable <= 0) ? this._network : this._broadcast - 1;
return IPNetwork.ToIPAddress(last, this._family);
@@ -117,7 +119,7 @@ namespace System.Net
get
{
- if (this._family == Sockets.AddressFamily.InterNetworkV6)
+ if (this._family == System.Net.Sockets.AddressFamily.InterNetworkV6)
{
return this.Total;
}
@@ -136,7 +138,7 @@ namespace System.Net
get
{
- int max = this._family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
+ int max = this._family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
var count = BigInteger.Pow(2, (max - _cidr));
return count;
}
@@ -161,7 +163,7 @@ namespace System.Net
IPNetwork(BigInteger ipaddress, AddressFamily family, byte cidr)
{
- int maxCidr = family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
+ int maxCidr = family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
if (cidr > maxCidr)
{
throw new ArgumentOutOfRangeException(nameof(cidr));
@@ -930,7 +932,7 @@ namespace System.Net
/// return;
/// }
- int maxCidr = family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
+ int maxCidr = family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
if (cidr > maxCidr)
{
if (tryParse == false)
@@ -1303,7 +1305,7 @@ namespace System.Net
return;
}
- int maxCidr = network._family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
+ int maxCidr = network._family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
if (cidr > maxCidr)
{
if (trySubnet == false)
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs b/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs
index 7d3106624..4cda421e5 100644
--- a/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs
+++ b/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs
@@ -1,8 +1,9 @@
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
-namespace System.Net
+namespace Emby.Server.Implementations.Networking.IPNetwork
{
public class IPNetworkCollection : IEnumerable<IPNetwork>, IEnumerator<IPNetwork>
{
@@ -25,7 +26,7 @@ namespace System.Net
IPNetworkCollection(IPNetwork ipnetwork, byte cidrSubnet)
{
- int maxCidr = ipnetwork.AddressFamily == Sockets.AddressFamily.InterNetwork ? 32 : 128;
+ int maxCidr = ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
if (cidrSubnet > maxCidr)
{
throw new ArgumentOutOfRangeException(nameof(cidrSubnet));
@@ -61,7 +62,7 @@ namespace System.Net
throw new ArgumentOutOfRangeException(nameof(i));
}
- var last = this._ipnetwork.AddressFamily == Sockets.AddressFamily.InterNetworkV6
+ var last = this._ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6
? this._lastUsable : this._broadcast;
var increment = (last - this._network) / this.Count;
var uintNetwork = this._network + ((increment + 1) * i);
diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs
index aa884664f..60cc9b88e 100644
--- a/Emby.Server.Implementations/Networking/NetworkManager.cs
+++ b/Emby.Server.Implementations/Networking/NetworkManager.cs
@@ -281,7 +281,7 @@ namespace Emby.Server.Implementations.Networking
if (normalizedSubnet.IndexOf('/') != -1)
{
- var ipnetwork = IPNetwork.Parse(normalizedSubnet);
+ var ipnetwork = IPNetwork.IPNetwork.Parse(normalizedSubnet);
if (ipnetwork.Contains(address))
{
return true;
diff --git a/Emby.Server.Implementations/Serialization/JsonSerializer.cs b/Emby.Server.Implementations/Serialization/JsonSerializer.cs
index 53ef5d60c..44898d498 100644
--- a/Emby.Server.Implementations/Serialization/JsonSerializer.cs
+++ b/Emby.Server.Implementations/Serialization/JsonSerializer.cs
@@ -3,9 +3,8 @@ using System.IO;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
-using Microsoft.Extensions.Logging;
-namespace Emby.Common.Implementations.Serialization
+namespace Emby.Server.Implementations.Serialization
{
/// <summary>
/// Provides a wrapper around third party json serialization.
diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs
index 16de1a083..dc9975347 100644
--- a/Emby.Server.Implementations/Services/ResponseHelper.cs
+++ b/Emby.Server.Implementations/Services/ResponseHelper.cs
@@ -70,7 +70,7 @@ namespace Emby.Server.Implementations.Services
response.ContentType = defaultContentType;
}
- if (new HashSet<string> { "application/json", }.Contains(response.ContentType))
+ if (response.ContentType == "application/json")
{
response.ContentType += "; charset=utf-8";
}
diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs
index aa67a3601..79f5c59e6 100644
--- a/Emby.Server.Implementations/Services/ServiceExec.cs
+++ b/Emby.Server.Implementations/Services/ServiceExec.cs
@@ -23,8 +23,6 @@ namespace Emby.Server.Implementations.Services
"POLL", "SUBSCRIBE", "UNSUBSCRIBE"
};
- public static HashSet<string> AllVerbsSet = new HashSet<string>(AllVerbs);
-
public static List<MethodInfo> GetActions(this Type serviceType)
{
var list = new List<MethodInfo>();
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index b03345e03..fa0ab62d3 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -27,7 +27,6 @@ using MediaBrowser.Model.Library;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Session
@@ -60,7 +59,6 @@ namespace Emby.Server.Implementations.Session
private readonly IAuthenticationRepository _authRepo;
private readonly IDeviceManager _deviceManager;
- private readonly ITimerFactory _timerFactory;
/// <summary>
/// The _active connections
@@ -103,8 +101,7 @@ namespace Emby.Server.Implementations.Session
IHttpClient httpClient,
IAuthenticationRepository authRepo,
IDeviceManager deviceManager,
- IMediaSourceManager mediaSourceManager,
- ITimerFactory timerFactory)
+ IMediaSourceManager mediaSourceManager)
{
_userDataManager = userDataManager;
_logger = loggerFactory.CreateLogger(nameof(SessionManager));
@@ -119,7 +116,6 @@ namespace Emby.Server.Implementations.Session
_authRepo = authRepo;
_deviceManager = deviceManager;
_mediaSourceManager = mediaSourceManager;
- _timerFactory = timerFactory;
_deviceManager.DeviceOptionsUpdated += _deviceManager_DeviceOptionsUpdated;
}
@@ -503,13 +499,13 @@ namespace Emby.Server.Implementations.Session
return users;
}
- private ITimer _idleTimer;
+ private Timer _idleTimer;
private void StartIdleCheckTimer()
{
if (_idleTimer == null)
{
- _idleTimer = _timerFactory.Create(CheckForIdlePlayback, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
+ _idleTimer = new Timer(CheckForIdlePlayback, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
}
}
private void StopIdleCheckTimer()
@@ -606,7 +602,7 @@ namespace Emby.Server.Implementations.Session
ClearTranscodingInfo(session.DeviceId);
}
- session.StartAutomaticProgress(_timerFactory, info);
+ session.StartAutomaticProgress(info);
var users = GetUsers(session);
@@ -717,7 +713,7 @@ namespace Emby.Server.Implementations.Session
if (!isAutomated)
{
- session.StartAutomaticProgress(_timerFactory, info);
+ session.StartAutomaticProgress(info);
}
StartIdleCheckTimer();
diff --git a/Emby.Server.Implementations/Threading/CommonTimer.cs b/Emby.Server.Implementations/Threading/CommonTimer.cs
deleted file mode 100644
index 5a05da564..000000000
--- a/Emby.Server.Implementations/Threading/CommonTimer.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Threading;
-using MediaBrowser.Model.Threading;
-
-namespace Emby.Server.Implementations.Threading
-{
- public class CommonTimer : ITimer
- {
- private readonly Timer _timer;
-
- public CommonTimer(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period)
- {
- _timer = new Timer(new TimerCallback(callback), state, dueTime, period);
- }
-
- public CommonTimer(Action<object> callback, object state, int dueTimeMs, int periodMs)
- {
- _timer = new Timer(new TimerCallback(callback), state, dueTimeMs, periodMs);
- }
-
- public void Change(TimeSpan dueTime, TimeSpan period)
- {
- _timer.Change(dueTime, period);
- }
-
- public void Change(int dueTimeMs, int periodMs)
- {
- _timer.Change(dueTimeMs, periodMs);
- }
-
- public void Dispose()
- {
- _timer.Dispose();
- }
- }
-}
diff --git a/Emby.Server.Implementations/Threading/TimerFactory.cs b/Emby.Server.Implementations/Threading/TimerFactory.cs
deleted file mode 100644
index ca50064c7..000000000
--- a/Emby.Server.Implementations/Threading/TimerFactory.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using MediaBrowser.Model.Threading;
-
-namespace Emby.Server.Implementations.Threading
-{
- public class TimerFactory : ITimerFactory
- {
- public ITimer Create(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period)
- {
- return new CommonTimer(callback, state, dueTime, period);
- }
-
- public ITimer Create(Action<object> callback, object state, int dueTimeMs, int periodMs)
- {
- return new CommonTimer(callback, state, dueTimeMs, periodMs);
- }
- }
-}
diff --git a/Emby.Server.Implementations/UserViews/FolderImageProvider.cs b/Emby.Server.Implementations/UserViews/FolderImageProvider.cs
index 7629f6039..c810004ab 100644
--- a/Emby.Server.Implementations/UserViews/FolderImageProvider.cs
+++ b/Emby.Server.Implementations/UserViews/FolderImageProvider.cs
@@ -11,7 +11,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Querying;
-namespace Emby.Server.Implementations.Photos
+namespace Emby.Server.Implementations.UserViews
{
public abstract class BaseFolderImageProvider<T> : BaseDynamicImageProvider<T>
where T : Folder, new()
diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
index f1b886ec6..dc714ed18 100644
--- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs
+++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -35,8 +36,8 @@ namespace Jellyfin.Drawing.Skia
LogVersion();
}
- public string[] SupportedInputFormats =>
- new[]
+ public IReadOnlyCollection<string> SupportedInputFormats =>
+ new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"jpeg",
"jpg",
@@ -62,7 +63,8 @@ namespace Jellyfin.Drawing.Skia
"arw"
};
- public ImageFormat[] SupportedOutputFormats => new[] { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
+ public IReadOnlyCollection<ImageFormat> SupportedOutputFormats
+ => new HashSet<ImageFormat>() { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
private void LogVersion()
{
@@ -253,7 +255,8 @@ namespace Jellyfin.Drawing.Skia
}
}
- private static string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" };
+ private static readonly HashSet<string> TransparentImageTypes
+ = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".png", ".gif", ".webp" };
internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem fileSystem, ImageOrientation? orientation, out SKEncodedOrigin origin)
{
@@ -262,7 +265,7 @@ namespace Jellyfin.Drawing.Skia
throw new FileNotFoundException("File not found", path);
}
- var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty);
+ var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path));
if (requiresTransparencyHack || forceCleanBitmap)
{
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index 5182ab4d7..315e34a04 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.Reflection;
using Emby.Server.Implementations;
using Emby.Server.Implementations.HttpServer;
-using Jellyfin.SocketSharp;
+using Jellyfin.Server.SocketSharp;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.System;
using Microsoft.Extensions.Logging;
diff --git a/Jellyfin.Server/SocketSharp/HttpFile.cs b/Jellyfin.Server/SocketSharp/HttpFile.cs
index 77ce03510..89c75e536 100644
--- a/Jellyfin.Server/SocketSharp/HttpFile.cs
+++ b/Jellyfin.Server/SocketSharp/HttpFile.cs
@@ -1,7 +1,7 @@
using System.IO;
using MediaBrowser.Model.Services;
-namespace Jellyfin.SocketSharp
+namespace Jellyfin.Server.SocketSharp
{
public class HttpFile : IHttpFile
{
diff --git a/Jellyfin.Server/SocketSharp/RequestMono.cs b/Jellyfin.Server/SocketSharp/RequestMono.cs
index f09197fb3..a8ba4cdb5 100644
--- a/Jellyfin.Server/SocketSharp/RequestMono.cs
+++ b/Jellyfin.Server/SocketSharp/RequestMono.cs
@@ -7,11 +7,11 @@ using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
-namespace Jellyfin.SocketSharp
+namespace Jellyfin.Server.SocketSharp
{
public partial class WebSocketSharpRequest : IHttpRequest
{
- static internal string GetParameter(string header, string attr)
+ internal static string GetParameter(string header, string attr)
{
int ap = header.IndexOf(attr);
if (ap == -1)
@@ -40,7 +40,7 @@ namespace Jellyfin.SocketSharp
return header.Substring(ap + 1, end - ap - 1);
}
- async Task LoadMultiPart(WebROCollection form)
+ private async Task LoadMultiPart(WebROCollection form)
{
string boundary = GetParameter(ContentType, "; boundary=");
if (boundary == null)
@@ -50,8 +50,8 @@ namespace Jellyfin.SocketSharp
using (var requestStream = InputStream)
{
- //DB: 30/01/11 - Hack to get around non-seekable stream and received HTTP request
- //Not ending with \r\n?
+ // DB: 30/01/11 - Hack to get around non-seekable stream and received HTTP request
+ // Not ending with \r\n?
var ms = new MemoryStream(32 * 1024);
await requestStream.CopyToAsync(ms).ConfigureAwait(false);
@@ -62,9 +62,9 @@ namespace Jellyfin.SocketSharp
input.Position = 0;
// Uncomment to debug
- //var content = new StreamReader(ms).ReadToEnd();
- //Console.WriteLine(boundary + "::" + content);
- //input.Position = 0;
+ // var content = new StreamReader(ms).ReadToEnd();
+ // Console.WriteLine(boundary + "::" + content);
+ // input.Position = 0;
var multi_part = new HttpMultipart(input, boundary, ContentEncoding);
@@ -111,7 +111,7 @@ namespace Jellyfin.SocketSharp
// Setting this before calling the validator prevents
// possible endless recursion
checked_form = true;
- ValidateNameValueCollection ("Form", query_string_nvc, RequestValidationSource.Form);
+ ValidateNameValueCollection("Form", query_string_nvc, RequestValidationSource.Form);
} else
#endif
if (validate_form && !checked_form)
@@ -130,7 +130,7 @@ namespace Jellyfin.SocketSharp
protected bool validate_cookies, validate_query_string, validate_form;
protected bool checked_cookies, checked_query_string, checked_form;
- static void ThrowValidationException(string name, string key, string value)
+ private static void ThrowValidationException(string name, string key, string value)
{
string v = "\"" + value + "\"";
if (v.Length > 20)
@@ -144,7 +144,7 @@ namespace Jellyfin.SocketSharp
throw new Exception(msg);
}
- static void ValidateNameValueCollection(string name, QueryParamCollection coll)
+ private static void ValidateNameValueCollection(string name, QueryParamCollection coll)
{
if (coll == null)
{
@@ -209,7 +209,7 @@ namespace Jellyfin.SocketSharp
validate_form = true;
}
- bool IsContentType(string ct, bool starts_with)
+ private bool IsContentType(string ct, bool starts_with)
{
if (ct == null || ContentType == null)
{
@@ -224,7 +224,7 @@ namespace Jellyfin.SocketSharp
return string.Equals(ContentType, ct, StringComparison.OrdinalIgnoreCase);
}
- async Task LoadWwwForm(WebROCollection form)
+ private async Task LoadWwwForm(WebROCollection form)
{
using (var input = InputStream)
{
@@ -280,7 +280,7 @@ namespace Jellyfin.SocketSharp
}
}
- static void AddRawKeyValue(WebROCollection form, StringBuilder key, StringBuilder value)
+ private static void AddRawKeyValue(WebROCollection form, StringBuilder key, StringBuilder value)
{
form.Add(WebUtility.UrlDecode(key.ToString()), WebUtility.UrlDecode(value.ToString()));
@@ -288,9 +288,9 @@ namespace Jellyfin.SocketSharp
value.Length = 0;
}
- Dictionary<string, HttpPostedFile> files;
+ private Dictionary<string, HttpPostedFile> files;
- class WebROCollection : QueryParamCollection
+ private class WebROCollection : QueryParamCollection
{
public override string ToString()
{
@@ -317,16 +317,16 @@ namespace Jellyfin.SocketSharp
public sealed class HttpPostedFile
{
- string name;
- string content_type;
- Stream stream;
+ private string name;
+ private string content_type;
+ private Stream stream;
- class ReadSubStream : Stream
+ private class ReadSubStream : Stream
{
- Stream s;
- long offset;
- long end;
- long position;
+ private Stream s;
+ private long offset;
+ private long end;
+ private long position;
public ReadSubStream(Stream s, long offset, long length)
{
@@ -429,7 +429,7 @@ namespace Jellyfin.SocketSharp
real = position + d;
break;
default:
- throw new ArgumentException();
+ throw new ArgumentException(nameof(origin));
}
long virt = real - offset;
@@ -491,7 +491,7 @@ namespace Jellyfin.SocketSharp
public Stream InputStream => stream;
}
- class Helpers
+ private class Helpers
{
public static readonly CultureInfo InvariantCulture = CultureInfo.InvariantCulture;
}
@@ -614,7 +614,7 @@ namespace Jellyfin.SocketSharp
private static string GetContentDispositionAttribute(string l, string name)
{
- int idx = l.IndexOf(name + "=\"");
+ int idx = l.IndexOf(name + "=\"", StringComparison.Ordinal);
if (idx < 0)
{
return null;
@@ -637,7 +637,7 @@ namespace Jellyfin.SocketSharp
private string GetContentDispositionAttributeWithEncoding(string l, string name)
{
- int idx = l.IndexOf(name + "=\"");
+ int idx = l.IndexOf(name + "=\"", StringComparison.Ordinal);
if (idx < 0)
{
return null;
@@ -669,11 +669,12 @@ namespace Jellyfin.SocketSharp
{
try
{
- string line = ReadLine();
- while (line == string.Empty)
+ string line;
+ do
{
line = ReadLine();
}
+ while (line.Length == 0);
if (line[0] != '-' || line[1] != '-')
{
diff --git a/Jellyfin.Server/SocketSharp/SharpWebSocket.cs b/Jellyfin.Server/SocketSharp/SharpWebSocket.cs
index d0dcd86eb..f371cb25a 100644
--- a/Jellyfin.Server/SocketSharp/SharpWebSocket.cs
+++ b/Jellyfin.Server/SocketSharp/SharpWebSocket.cs
@@ -5,7 +5,7 @@ using System.Threading.Tasks;
using Emby.Server.Implementations.Net;
using Microsoft.Extensions.Logging;
-namespace Jellyfin.SocketSharp
+namespace Jellyfin.Server.SocketSharp
{
public class SharpWebSocket : IWebSocket
{
diff --git a/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs b/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs
index c7f9f01b5..a44343ab2 100644
--- a/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs
+++ b/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs
@@ -15,7 +15,7 @@ using MediaBrowser.Model.System;
using Microsoft.Extensions.Logging;
using SocketHttpListener.Net;
-namespace Jellyfin.SocketSharp
+namespace Jellyfin.Server.SocketSharp
{
public class WebSocketSharpListener : IHttpListener
{
diff --git a/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs b/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs
index 2e8dd9185..ebeb18ea0 100644
--- a/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs
+++ b/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs
@@ -11,7 +11,7 @@ using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest;
using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
using IResponse = MediaBrowser.Model.Services.IResponse;
-namespace Jellyfin.SocketSharp
+namespace Jellyfin.Server.SocketSharp
{
public partial class WebSocketSharpRequest : IHttpRequest
{
@@ -80,15 +80,13 @@ namespace Jellyfin.SocketSharp
private string remoteIp;
public string RemoteIp =>
remoteIp ??
- (remoteIp = (CheckBadChars(XForwardedFor)) ??
- (NormalizeIp(CheckBadChars(XRealIp)) ??
+ (remoteIp = CheckBadChars(XForwardedFor) ??
+ NormalizeIp(CheckBadChars(XRealIp) ??
(request.RemoteEndPoint != null ? NormalizeIp(request.RemoteEndPoint.Address.ToString()) : null)));
private static readonly char[] HttpTrimCharacters = new char[] { (char)0x09, (char)0xA, (char)0xB, (char)0xC, (char)0xD, (char)0x20 };
- //
// CheckBadChars - throws on invalid chars to be not found in header name/value
- //
internal static string CheckBadChars(string name)
{
if (name == null || name.Length == 0)
@@ -97,11 +95,11 @@ namespace Jellyfin.SocketSharp
}
// VALUE check
- //Trim spaces from both ends
+ // Trim spaces from both ends
name = name.Trim(HttpTrimCharacters);
- //First, check for correctly formed multi-line value
- //Second, check for absenece of CTL characters
+ // First, check for correctly formed multi-line value
+ // Second, check for absenece of CTL characters
int crlf = 0;
for (int i = 0; i < name.Length; ++i)
{
@@ -198,9 +196,12 @@ namespace Jellyfin.SocketSharp
public static string GetResponseContentType(IRequest httpReq)
{
var specifiedContentType = GetQueryStringContentType(httpReq);
- if (!string.IsNullOrEmpty(specifiedContentType)) return specifiedContentType;
+ if (!string.IsNullOrEmpty(specifiedContentType))
+ {
+ return specifiedContentType;
+ }
- var serverDefaultContentType = "application/json";
+ const string serverDefaultContentType = "application/json";
var acceptContentTypes = httpReq.AcceptTypes;
string defaultContentType = null;
@@ -210,7 +211,7 @@ namespace Jellyfin.SocketSharp
}
var acceptsAnything = false;
- var hasDefaultContentType = !string.IsNullOrEmpty(defaultContentType);
+ var hasDefaultContentType = defaultContentType != null;
if (acceptContentTypes != null)
{
foreach (var acceptsType in acceptContentTypes)
@@ -237,7 +238,7 @@ namespace Jellyfin.SocketSharp
return Soap11;
}
- //We could also send a '406 Not Acceptable', but this is allowed also
+ // We could also send a '406 Not Acceptable', but this is allowed also
return serverDefaultContentType;
}
@@ -252,7 +253,10 @@ namespace Jellyfin.SocketSharp
foreach (var contentType in contentTypes)
{
- if (IsContentType(request, contentType)) return true;
+ if (IsContentType(request, contentType))
+ {
+ return true;
+ }
}
return false;
@@ -274,10 +278,12 @@ namespace Jellyfin.SocketSharp
{
return null;
}
+
if (pi[0] == '/')
{
pi = pi.Substring(1);
}
+
format = LeftPart(pi, '/');
if (format.Length > formatMaxLength)
{
@@ -285,7 +291,7 @@ namespace Jellyfin.SocketSharp
}
}
- format = LeftPart(format, '.').ToLowerInvariant();
+ format = LeftPart(format, '.');
if (format.Contains("json", StringComparison.OrdinalIgnoreCase))
{
return "application/json";
@@ -305,7 +311,7 @@ namespace Jellyfin.SocketSharp
return null;
}
- var pos = strVal.IndexOf(needle);
+ var pos = strVal.IndexOf(needle, StringComparison.Ordinal);
return pos == -1 ? strVal : strVal.Substring(0, pos);
}
@@ -349,7 +355,7 @@ namespace Jellyfin.SocketSharp
return pathInfo;
}
- //Wildcard mode relies on this to work out the handlerPath
+ // Wildcard mode relies on this to work out the handlerPath
pathInfo = ResolvePathInfoFromMappedPath(fullPath, appPath);
if (!string.IsNullOrEmpty(pathInfo))
{
@@ -391,6 +397,7 @@ namespace Jellyfin.SocketSharp
}
}
}
+
if (!pathRootFound)
{
return null;
@@ -501,10 +508,10 @@ namespace Jellyfin.SocketSharp
public static string NormalizePathInfo(string pathInfo, string handlerPath)
{
- if (handlerPath != null && pathInfo.TrimStart('/').StartsWith(
- handlerPath, StringComparison.OrdinalIgnoreCase))
+ var trimmed = pathInfo.TrimStart('/');
+ if (handlerPath != null && trimmed.StartsWith(handlerPath, StringComparison.OrdinalIgnoreCase))
{
- return pathInfo.TrimStart('/').Substring(handlerPath.Length);
+ return trimmed.Substring(handlerPath.Length);
}
return pathInfo;
diff --git a/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs b/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs
index 21bfac55d..cabc96b23 100644
--- a/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs
+++ b/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs
@@ -14,7 +14,7 @@ using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
using IRequest = MediaBrowser.Model.Services.IRequest;
-namespace Jellyfin.SocketSharp
+namespace Jellyfin.Server.SocketSharp
{
public class WebSocketSharpResponse : IHttpResponse
{
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index 88654a42c..8dbc26356 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
@@ -17,7 +18,6 @@ using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Session;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
@@ -47,7 +47,6 @@ namespace MediaBrowser.Api
private readonly ISessionManager _sessionManager;
private readonly IFileSystem _fileSystem;
private readonly IMediaSourceManager _mediaSourceManager;
- public readonly ITimerFactory TimerFactory;
public readonly IProcessFactory ProcessFactory;
/// <summary>
@@ -58,6 +57,8 @@ namespace MediaBrowser.Api
private readonly Dictionary<string, SemaphoreSlim> _transcodingLocks =
new Dictionary<string, SemaphoreSlim>();
+ private bool _disposed = false;
+
/// <summary>
/// Initializes a new instance of the <see cref="ApiEntryPoint" /> class.
/// </summary>
@@ -66,20 +67,27 @@ namespace MediaBrowser.Api
/// <param name="config">The configuration.</param>
/// <param name="fileSystem">The file system.</param>
/// <param name="mediaSourceManager">The media source manager.</param>
- public ApiEntryPoint(ILogger logger, ISessionManager sessionManager, IServerConfigurationManager config, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager, ITimerFactory timerFactory, IProcessFactory processFactory, IHttpResultFactory resultFactory)
+ public ApiEntryPoint(
+ ILogger logger,
+ ISessionManager sessionManager,
+ IServerConfigurationManager config,
+ IFileSystem fileSystem,
+ IMediaSourceManager mediaSourceManager,
+ IProcessFactory processFactory,
+ IHttpResultFactory resultFactory)
{
Logger = logger;
_sessionManager = sessionManager;
_config = config;
_fileSystem = fileSystem;
_mediaSourceManager = mediaSourceManager;
- TimerFactory = timerFactory;
ProcessFactory = processFactory;
ResultFactory = resultFactory;
- Instance = this;
_sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress;
_sessionManager.PlaybackStart += _sessionManager_PlaybackStart;
+
+ Instance = this;
}
public static string[] Split(string value, char separator, bool removeEmpty)
@@ -185,17 +193,40 @@ namespace MediaBrowser.Api
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
- var list = _activeTranscodingJobs.ToList();
- var jobCount = list.Count;
+ if (_disposed)
+ {
+ return;
+ }
- Parallel.ForEach(list, j => KillTranscodingJob(j, false, path => true));
+ if (dispose)
+ {
+ // TODO: dispose
+ }
- // Try to allow for some time to kill the ffmpeg processes and delete the partial stream files
+ var jobs = _activeTranscodingJobs.ToList();
+ var jobCount = jobs.Count;
+
+ IEnumerable<Task> GetKillJobs()
+ {
+ foreach (var job in jobs)
+ {
+ yield return KillTranscodingJob(job, false, path => true);
+ }
+ }
+
+ // Wait for all processes to be killed
if (jobCount > 0)
{
- var task = Task.Delay(1000);
- Task.WaitAll(task);
+ Task.WaitAll(GetKillJobs().ToArray());
}
+
+ _activeTranscodingJobs.Clear();
+ _transcodingLocks.Clear();
+
+ _sessionManager.PlaybackProgress -= _sessionManager_PlaybackProgress;
+ _sessionManager.PlaybackStart -= _sessionManager_PlaybackStart;
+
+ _disposed = true;
}
@@ -212,19 +243,20 @@ namespace MediaBrowser.Api
/// <param name="state">The state.</param>
/// <param name="cancellationTokenSource">The cancellation token source.</param>
/// <returns>TranscodingJob.</returns>
- public TranscodingJob OnTranscodeBeginning(string path,
+ public TranscodingJob OnTranscodeBeginning(
+ string path,
string playSessionId,
string liveStreamId,
string transcodingJobId,
TranscodingJobType type,
- IProcess process,
+ Process process,
string deviceId,
StreamState state,
CancellationTokenSource cancellationTokenSource)
{
lock (_activeTranscodingJobs)
{
- var job = new TranscodingJob(Logger, TimerFactory)
+ var job = new TranscodingJob(Logger)
{
Type = type,
Path = path,
@@ -446,7 +478,7 @@ namespace MediaBrowser.Api
/// Called when [transcode kill timer stopped].
/// </summary>
/// <param name="state">The state.</param>
- private void OnTranscodeKillTimerStopped(object state)
+ private async void OnTranscodeKillTimerStopped(object state)
{
var job = (TranscodingJob)state;
@@ -463,7 +495,7 @@ namespace MediaBrowser.Api
Logger.LogInformation("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId);
- KillTranscodingJob(job, true, path => true).GetAwaiter().GetResult();
+ await KillTranscodingJob(job, true, path => true);
}
/// <summary>
@@ -551,7 +583,7 @@ namespace MediaBrowser.Api
{
if (job.TranscodingThrottler != null)
{
- job.TranscodingThrottler.Stop();
+ job.TranscodingThrottler.Stop().GetAwaiter().GetResult();
}
var process = job.Process;
@@ -562,7 +594,7 @@ namespace MediaBrowser.Api
{
try
{
- Logger.LogInformation("Stopping ffmpeg process with q command for {path}", job.Path);
+ Logger.LogInformation("Stopping ffmpeg process with q command for {Path}", job.Path);
//process.Kill();
process.StandardInput.WriteLine("q");
@@ -570,13 +602,13 @@ namespace MediaBrowser.Api
// Need to wait because killing is asynchronous
if (!process.WaitForExit(5000))
{
- Logger.LogInformation("Killing ffmpeg process for {path}", job.Path);
+ Logger.LogInformation("Killing ffmpeg process for {Path}", job.Path);
process.Kill();
}
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error killing transcoding job for {path}", job.Path);
+ Logger.LogError(ex, "Error killing transcoding job for {Path}", job.Path);
}
}
}
@@ -606,7 +638,7 @@ namespace MediaBrowser.Api
return;
}
- Logger.LogInformation("Deleting partial stream file(s) {0}", path);
+ Logger.LogInformation("Deleting partial stream file(s) {Path}", path);
await Task.Delay(delayMs).ConfigureAwait(false);
@@ -627,13 +659,13 @@ namespace MediaBrowser.Api
}
catch (IOException ex)
{
- Logger.LogError(ex, "Error deleting partial stream file(s) {path}", path);
+ Logger.LogError(ex, "Error deleting partial stream file(s) {Path}", path);
await DeletePartialStreamFiles(path, jobType, retryCount + 1, 500).ConfigureAwait(false);
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error deleting partial stream file(s) {path}", path);
+ Logger.LogError(ex, "Error deleting partial stream file(s) {Path}", path);
}
}
@@ -674,7 +706,7 @@ namespace MediaBrowser.Api
catch (IOException ex)
{
e = ex;
- Logger.LogError(ex, "Error deleting HLS file {path}", file);
+ Logger.LogError(ex, "Error deleting HLS file {Path}", file);
}
}
@@ -718,7 +750,7 @@ namespace MediaBrowser.Api
/// Gets or sets the process.
/// </summary>
/// <value>The process.</value>
- public IProcess Process { get; set; }
+ public Process Process { get; set; }
public ILogger Logger { get; private set; }
/// <summary>
/// Gets or sets the active request count.
@@ -729,9 +761,7 @@ namespace MediaBrowser.Api
/// Gets or sets the kill timer.
/// </summary>
/// <value>The kill timer.</value>
- private ITimer KillTimer { get; set; }
-
- private readonly ITimerFactory _timerFactory;
+ private Timer KillTimer { get; set; }
public string DeviceId { get; set; }
@@ -761,10 +791,9 @@ namespace MediaBrowser.Api
public DateTime LastPingDate { get; set; }
public int PingTimeout { get; set; }
- public TranscodingJob(ILogger logger, ITimerFactory timerFactory)
+ public TranscodingJob(ILogger logger)
{
Logger = logger;
- _timerFactory = timerFactory;
}
public void StopKillTimer()
@@ -807,7 +836,7 @@ namespace MediaBrowser.Api
if (KillTimer == null)
{
//Logger.LogDebug("Starting kill timer at {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
- KillTimer = _timerFactory.Create(callback, this, intervalMs, Timeout.Infinite);
+ KillTimer = new Timer(new TimerCallback(callback), this, intervalMs, Timeout.Infinite);
}
else
{
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 4a484b718..451ee72dd 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -43,7 +43,7 @@ namespace MediaBrowser.Api
public static string[] SplitValue(string value, char delim)
{
- if (string.IsNullOrWhiteSpace(value))
+ if (value == null)
{
return Array.Empty<string>();
}
@@ -53,8 +53,14 @@ namespace MediaBrowser.Api
public static Guid[] GetGuids(string value)
{
- // Unfortunately filtermenu.js was using |. This can be deprecated after a while.
- return (value ?? string.Empty).Split(new[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries).Select(i => new Guid(i)).ToArray();
+ if (value == null)
+ {
+ return Array.Empty<Guid>();
+ }
+
+ return value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(i => new Guid(i))
+ .ToArray();
}
/// <summary>
@@ -118,7 +124,8 @@ namespace MediaBrowser.Api
options.Fields = hasFields.GetItemFields();
}
- if (!options.ContainsField(Model.Querying.ItemFields.RecursiveItemCount) || !options.ContainsField(Model.Querying.ItemFields.ChildCount))
+ if (!options.ContainsField(Model.Querying.ItemFields.RecursiveItemCount)
+ || !options.ContainsField(Model.Querying.ItemFields.ChildCount))
{
var client = authContext.GetAuthorizationInfo(Request).Client ?? string.Empty;
if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
@@ -145,8 +152,7 @@ namespace MediaBrowser.Api
}
}
- var hasDtoOptions = request as IHasDtoOptions;
- if (hasDtoOptions != null)
+ if (request is IHasDtoOptions hasDtoOptions)
{
options.EnableImages = hasDtoOptions.EnableImages ?? true;
@@ -294,7 +300,7 @@ namespace MediaBrowser.Api
return pathInfo[index];
}
- private List<string> Parse(string pathUri)
+ private string[] Parse(string pathUri)
{
var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None);
@@ -308,7 +314,7 @@ namespace MediaBrowser.Api
var args = pathInfo.Split('/');
- return args.Skip(1).ToList();
+ return args.Skip(1).ToArray();
}
/// <summary>
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index b5e23476e..61db7b8d4 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -324,7 +324,7 @@ namespace MediaBrowser.Api.Images
var fileInfo = _fileSystem.GetFileInfo(info.Path);
length = fileInfo.Length;
- ImageDimensions size = _imageProcessor.GetImageSize(item, info, true);
+ ImageDimensions size = _imageProcessor.GetImageDimensions(item, info, true);
width = size.Width;
height = size.Height;
diff --git a/MediaBrowser.Api/LocalizationService.cs b/MediaBrowser.Api/LocalizationService.cs
index 3b2e18852..eeff67e13 100644
--- a/MediaBrowser.Api/LocalizationService.cs
+++ b/MediaBrowser.Api/LocalizationService.cs
@@ -1,3 +1,4 @@
+using System.Threading.Tasks;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
@@ -81,9 +82,9 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Get(GetCountries request)
+ public async Task<object> Get(GetCountries request)
{
- var result = _localization.GetCountries();
+ var result = await _localization.GetCountries();
return ToOptimizedResult(result);
}
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index ec42cad33..073686298 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -68,10 +69,8 @@ namespace MediaBrowser.Api.Playback
protected IDeviceManager DeviceManager { get; private set; }
protected ISubtitleEncoder SubtitleEncoder { get; private set; }
protected IMediaSourceManager MediaSourceManager { get; private set; }
- protected IZipClient ZipClient { get; private set; }
protected IJsonSerializer JsonSerializer { get; private set; }
- public static IServerApplicationHost AppHost;
public static IHttpClient HttpClient;
protected IAuthorizationContext AuthorizationContext { get; private set; }
@@ -80,21 +79,33 @@ namespace MediaBrowser.Api.Playback
/// <summary>
/// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
/// </summary>
- protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext)
+ protected BaseStreamingService(
+ IServerConfigurationManager serverConfig,
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IIsoManager isoManager,
+ IMediaEncoder mediaEncoder,
+ IFileSystem fileSystem,
+ IDlnaManager dlnaManager,
+ ISubtitleEncoder subtitleEncoder,
+ IDeviceManager deviceManager,
+ IMediaSourceManager mediaSourceManager,
+ IJsonSerializer jsonSerializer,
+ IAuthorizationContext authorizationContext)
{
- JsonSerializer = jsonSerializer;
- AuthorizationContext = authorizationContext;
- ZipClient = zipClient;
- MediaSourceManager = mediaSourceManager;
- DeviceManager = deviceManager;
- SubtitleEncoder = subtitleEncoder;
- DlnaManager = dlnaManager;
- FileSystem = fileSystem;
ServerConfigurationManager = serverConfig;
UserManager = userManager;
LibraryManager = libraryManager;
IsoManager = isoManager;
MediaEncoder = mediaEncoder;
+ FileSystem = fileSystem;
+ DlnaManager = dlnaManager;
+ SubtitleEncoder = subtitleEncoder;
+ DeviceManager = deviceManager;
+ MediaSourceManager = mediaSourceManager;
+ JsonSerializer = jsonSerializer;
+ AuthorizationContext = authorizationContext;
+
EncodingHelper = new EncodingHelper(MediaEncoder, FileSystem, SubtitleEncoder);
}
@@ -187,7 +198,8 @@ namespace MediaBrowser.Api.Playback
/// <param name="cancellationTokenSource">The cancellation token source.</param>
/// <param name="workingDirectory">The working directory.</param>
/// <returns>Task.</returns>
- protected async Task<TranscodingJob> StartFfMpeg(StreamState state,
+ protected async Task<TranscodingJob> StartFfMpeg(
+ StreamState state,
string outputPath,
CancellationTokenSource cancellationTokenSource,
string workingDirectory = null)
@@ -215,24 +227,27 @@ namespace MediaBrowser.Api.Playback
var transcodingId = Guid.NewGuid().ToString("N");
var commandLineArgs = GetCommandLineArguments(outputPath, encodingOptions, state, true);
- var process = ApiEntryPoint.Instance.ProcessFactory.Create(new ProcessOptions
+ var process = new Process()
{
- CreateNoWindow = true,
- UseShellExecute = false,
-
- // Must consume both stdout and stderr or deadlocks may occur
- //RedirectStandardOutput = true,
- RedirectStandardError = true,
- RedirectStandardInput = true,
-
- FileName = MediaEncoder.EncoderPath,
- Arguments = commandLineArgs,
-
- IsHidden = true,
- ErrorDialog = false,
- EnableRaisingEvents = true,
- WorkingDirectory = !string.IsNullOrWhiteSpace(workingDirectory) ? workingDirectory : null
- });
+ StartInfo = new ProcessStartInfo()
+ {
+ WindowStyle = ProcessWindowStyle.Hidden,
+ CreateNoWindow = true,
+ UseShellExecute = false,
+
+ // Must consume both stdout and stderr or deadlocks may occur
+ //RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ RedirectStandardInput = true,
+
+ FileName = MediaEncoder.EncoderPath,
+ Arguments = commandLineArgs,
+ WorkingDirectory = string.IsNullOrWhiteSpace(workingDirectory) ? null : workingDirectory,
+
+ ErrorDialog = false
+ },
+ EnableRaisingEvents = true
+ };
var transcodingJob = ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath,
state.Request.PlaySessionId,
@@ -248,13 +263,17 @@ namespace MediaBrowser.Api.Playback
Logger.LogInformation(commandLineLogMessage);
var logFilePrefix = "ffmpeg-transcode";
- if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
- {
- logFilePrefix = "ffmpeg-directstream";
- }
- else if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (state.VideoRequest != null)
{
- logFilePrefix = "ffmpeg-remux";
+ if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)
+ && string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ {
+ logFilePrefix = "ffmpeg-directstream";
+ }
+ else if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ {
+ logFilePrefix = "ffmpeg-remux";
+ }
}
var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt");
@@ -317,7 +336,7 @@ namespace MediaBrowser.Api.Playback
{
if (EnableThrottling(state))
{
- transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager, ApiEntryPoint.Instance.TimerFactory, FileSystem);
+ transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager, FileSystem);
state.TranscodingThrottler.Start();
}
}
@@ -341,7 +360,7 @@ namespace MediaBrowser.Api.Playback
/// <param name="process">The process.</param>
/// <param name="job">The job.</param>
/// <param name="state">The state.</param>
- private void OnFfMpegProcessExited(IProcess process, TranscodingJob job, StreamState state)
+ private void OnFfMpegProcessExited(Process process, TranscodingJob job, StreamState state)
{
if (job != null)
{
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 08a2183f8..1acc42ea5 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -55,17 +55,6 @@ namespace MediaBrowser.Api.Playback.Hls
protected override TranscodingJobType TranscodingJobType => TranscodingJobType.Hls;
/// <summary>
- /// Processes the request.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <param name="isLive">if set to <c>true</c> [is live].</param>
- /// <returns>System.Object.</returns>
- protected async Task<object> ProcessRequest(StreamRequest request, bool isLive)
- {
- return await ProcessRequestAsync(request, isLive).ConfigureAwait(false);
- }
-
- /// <summary>
/// Processes the request async.
/// </summary>
/// <param name="request">The request.</param>
@@ -74,7 +63,7 @@ namespace MediaBrowser.Api.Playback.Hls
/// <exception cref="ArgumentException">A video bitrate is required
/// or
/// An audio bitrate is required</exception>
- private async Task<object> ProcessRequestAsync(StreamRequest request, bool isLive)
+ protected async Task<object> ProcessRequestAsync(StreamRequest request, bool isLive)
{
var cancellationTokenSource = new CancellationTokenSource();
@@ -324,7 +313,31 @@ namespace MediaBrowser.Api.Playback.Hls
return 0;
}
- public BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, authorizationContext)
+ public BaseHlsService(
+ IServerConfigurationManager serverConfig,
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IIsoManager isoManager,
+ IMediaEncoder mediaEncoder,
+ IFileSystem fileSystem,
+ IDlnaManager dlnaManager,
+ ISubtitleEncoder subtitleEncoder,
+ IDeviceManager deviceManager,
+ IMediaSourceManager mediaSourceManager,
+ IJsonSerializer jsonSerializer,
+ IAuthorizationContext authorizationContext)
+ : base(serverConfig,
+ userManager,
+ libraryManager,
+ isoManager,
+ mediaEncoder,
+ fileSystem,
+ dlnaManager,
+ subtitleEncoder,
+ deviceManager,
+ mediaSourceManager,
+ jsonSerializer,
+ authorizationContext)
{
}
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 30696ec97..45f003cae 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -95,7 +95,32 @@ namespace MediaBrowser.Api.Playback.Hls
public class DynamicHlsService : BaseHlsService
{
- public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, authorizationContext)
+ public DynamicHlsService(
+ IServerConfigurationManager serverConfig,
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IIsoManager isoManager,
+ IMediaEncoder mediaEncoder,
+ IFileSystem fileSystem,
+ IDlnaManager dlnaManager,
+ ISubtitleEncoder subtitleEncoder,
+ IDeviceManager deviceManager,
+ IMediaSourceManager mediaSourceManager,
+ IJsonSerializer jsonSerializer,
+ IAuthorizationContext authorizationContext,
+ INetworkManager networkManager)
+ : base(serverConfig,
+ userManager,
+ libraryManager,
+ isoManager,
+ mediaEncoder,
+ fileSystem,
+ dlnaManager,
+ subtitleEncoder,
+ deviceManager,
+ mediaSourceManager,
+ jsonSerializer,
+ authorizationContext)
{
NetworkManager = networkManager;
}
@@ -209,7 +234,7 @@ namespace MediaBrowser.Api.Playback.Hls
// If the playlist doesn't already exist, startup ffmpeg
try
{
- ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, p => false);
+ await ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, p => false);
if (currentTranscodingIndex.HasValue)
{
@@ -233,7 +258,7 @@ namespace MediaBrowser.Api.Playback.Hls
job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
if (job.TranscodingThrottler != null)
{
- job.TranscodingThrottler.UnpauseTranscoding();
+ await job.TranscodingThrottler.UnpauseTranscoding();
}
}
}
diff --git a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
index 02b837912..6a2c7ae03 100644
--- a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
+++ b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
@@ -102,9 +102,9 @@ namespace MediaBrowser.Api.Playback.Hls
return GetFileResult(file, file);
}
- public void Delete(StopEncodingProcess request)
+ public Task Delete(StopEncodingProcess request)
{
- ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, path => true);
+ return ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, path => true);
}
/// <summary>
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index 142dc2dfd..eb1bbfb74 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Dlna;
@@ -24,9 +25,9 @@ namespace MediaBrowser.Api.Playback.Hls
[Authenticated]
public class VideoHlsService : BaseHlsService
{
- public object Get(GetLiveHlsStream request)
+ public Task<object> Get(GetLiveHlsStream request)
{
- return ProcessRequest(request, true);
+ return ProcessRequestAsync(request, true);
}
/// <summary>
@@ -130,7 +131,31 @@ namespace MediaBrowser.Api.Playback.Hls
return args;
}
- public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, authorizationContext)
+ public VideoHlsService(
+ IServerConfigurationManager serverConfig,
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IIsoManager isoManager,
+ IMediaEncoder mediaEncoder,
+ IFileSystem fileSystem,
+ IDlnaManager dlnaManager,
+ ISubtitleEncoder subtitleEncoder,
+ IDeviceManager deviceManager,
+ IMediaSourceManager mediaSourceManager,
+ IJsonSerializer jsonSerializer,
+ IAuthorizationContext authorizationContext)
+ : base(serverConfig,
+ userManager,
+ libraryManager,
+ isoManager,
+ mediaEncoder,
+ fileSystem,
+ dlnaManager,
+ subtitleEncoder,
+ deviceManager,
+ mediaSourceManager,
+ jsonSerializer,
+ authorizationContext)
{
}
}
diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
index 150571ce9..208a5560d 100644
--- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
@@ -32,7 +32,33 @@ namespace MediaBrowser.Api.Playback.Progressive
//[Authenticated]
public class AudioService : BaseProgressiveStreamingService
{
- public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext, IImageProcessor imageProcessor, IEnvironmentInfo environmentInfo) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, authorizationContext, imageProcessor, environmentInfo)
+ public AudioService(
+ IServerConfigurationManager serverConfig,
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IIsoManager isoManager,
+ IMediaEncoder mediaEncoder,
+ IFileSystem fileSystem,
+ IDlnaManager dlnaManager,
+ ISubtitleEncoder subtitleEncoder,
+ IDeviceManager deviceManager,
+ IMediaSourceManager mediaSourceManager,
+ IJsonSerializer jsonSerializer,
+ IAuthorizationContext authorizationContext,
+ IEnvironmentInfo environmentInfo)
+ : base(serverConfig,
+ userManager,
+ libraryManager,
+ isoManager,
+ mediaEncoder,
+ fileSystem,
+ dlnaManager,
+ subtitleEncoder,
+ deviceManager,
+ mediaSourceManager,
+ jsonSerializer,
+ authorizationContext,
+ environmentInfo)
{
}
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 621d1ff88..c197de173 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -25,12 +25,35 @@ namespace MediaBrowser.Api.Playback.Progressive
/// </summary>
public abstract class BaseProgressiveStreamingService : BaseStreamingService
{
- protected readonly IImageProcessor ImageProcessor;
protected readonly IEnvironmentInfo EnvironmentInfo;
- public BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext, IImageProcessor imageProcessor, IEnvironmentInfo environmentInfo) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, authorizationContext)
+ public BaseProgressiveStreamingService(
+ IServerConfigurationManager serverConfig,
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IIsoManager isoManager,
+ IMediaEncoder mediaEncoder,
+ IFileSystem fileSystem,
+ IDlnaManager dlnaManager,
+ ISubtitleEncoder subtitleEncoder,
+ IDeviceManager deviceManager,
+ IMediaSourceManager mediaSourceManager,
+ IJsonSerializer jsonSerializer,
+ IAuthorizationContext authorizationContext,
+ IEnvironmentInfo environmentInfo)
+ : base(serverConfig,
+ userManager,
+ libraryManager,
+ isoManager,
+ mediaEncoder,
+ fileSystem,
+ dlnaManager,
+ subtitleEncoder,
+ deviceManager,
+ mediaSourceManager,
+ jsonSerializer,
+ authorizationContext)
{
- ImageProcessor = imageProcessor;
EnvironmentInfo = environmentInfo;
}
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index 00b79ccdd..a0ea5c62d 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -68,7 +68,33 @@ namespace MediaBrowser.Api.Playback.Progressive
//[Authenticated]
public class VideoService : BaseProgressiveStreamingService
{
- public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IAuthorizationContext authorizationContext, IImageProcessor imageProcessor, IEnvironmentInfo environmentInfo) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, authorizationContext, imageProcessor, environmentInfo)
+ public VideoService(
+ IServerConfigurationManager serverConfig,
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IIsoManager isoManager,
+ IMediaEncoder mediaEncoder,
+ IFileSystem fileSystem,
+ IDlnaManager dlnaManager,
+ ISubtitleEncoder subtitleEncoder,
+ IDeviceManager deviceManager,
+ IMediaSourceManager mediaSourceManager,
+ IJsonSerializer jsonSerializer,
+ IAuthorizationContext authorizationContext,
+ IEnvironmentInfo environmentInfo)
+ : base(serverConfig,
+ userManager,
+ libraryManager,
+ isoManager,
+ mediaEncoder,
+ fileSystem,
+ dlnaManager,
+ subtitleEncoder,
+ deviceManager,
+ mediaSourceManager,
+ jsonSerializer,
+ authorizationContext,
+ environmentInfo)
{
}
diff --git a/MediaBrowser.Api/Playback/TranscodingThrottler.cs b/MediaBrowser.Api/Playback/TranscodingThrottler.cs
index 97f21c8f3..0e73d77ef 100644
--- a/MediaBrowser.Api/Playback/TranscodingThrottler.cs
+++ b/MediaBrowser.Api/Playback/TranscodingThrottler.cs
@@ -1,8 +1,9 @@
using System;
+using System.Threading;
+using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Playback
@@ -11,18 +12,16 @@ namespace MediaBrowser.Api.Playback
{
private readonly TranscodingJob _job;
private readonly ILogger _logger;
- private ITimer _timer;
+ private Timer _timer;
private bool _isPaused;
private readonly IConfigurationManager _config;
- private readonly ITimerFactory _timerFactory;
private readonly IFileSystem _fileSystem;
- public TranscodingThrottler(TranscodingJob job, ILogger logger, IConfigurationManager config, ITimerFactory timerFactory, IFileSystem fileSystem)
+ public TranscodingThrottler(TranscodingJob job, ILogger logger, IConfigurationManager config, IFileSystem fileSystem)
{
_job = job;
_logger = logger;
_config = config;
- _timerFactory = timerFactory;
_fileSystem = fileSystem;
}
@@ -33,10 +32,10 @@ namespace MediaBrowser.Api.Playback
public void Start()
{
- _timer = _timerFactory.Create(TimerCallback, null, 5000, 5000);
+ _timer = new Timer(TimerCallback, null, 5000, 5000);
}
- private void TimerCallback(object state)
+ private async void TimerCallback(object state)
{
if (_job.HasExited)
{
@@ -48,15 +47,15 @@ namespace MediaBrowser.Api.Playback
if (options.EnableThrottling && IsThrottleAllowed(_job, options.ThrottleDelaySeconds))
{
- PauseTranscoding();
+ await PauseTranscoding();
}
else
{
- UnpauseTranscoding();
+ await UnpauseTranscoding();
}
}
- private void PauseTranscoding()
+ private async Task PauseTranscoding()
{
if (!_isPaused)
{
@@ -64,7 +63,7 @@ namespace MediaBrowser.Api.Playback
try
{
- _job.Process.StandardInput.Write("c");
+ await _job.Process.StandardInput.WriteAsync("c");
_isPaused = true;
}
catch (Exception ex)
@@ -74,7 +73,7 @@ namespace MediaBrowser.Api.Playback
}
}
- public void UnpauseTranscoding()
+ public async Task UnpauseTranscoding()
{
if (_isPaused)
{
@@ -82,7 +81,7 @@ namespace MediaBrowser.Api.Playback
try
{
- _job.Process.StandardInput.WriteLine();
+ await _job.Process.StandardInput.WriteLineAsync();
_isPaused = false;
}
catch (Exception ex)
@@ -153,10 +152,10 @@ namespace MediaBrowser.Api.Playback
return false;
}
- public void Stop()
+ public async Task Stop()
{
DisposeTimer();
- UnpauseTranscoding();
+ await UnpauseTranscoding();
}
public void Dispose()
diff --git a/MediaBrowser.Api/Playback/UniversalAudioService.cs b/MediaBrowser.Api/Playback/UniversalAudioService.cs
index 1aa77792c..e07770a4c 100644
--- a/MediaBrowser.Api/Playback/UniversalAudioService.cs
+++ b/MediaBrowser.Api/Playback/UniversalAudioService.cs
@@ -287,7 +287,6 @@ namespace MediaBrowser.Api.Playback
SubtitleEncoder,
DeviceManager,
MediaSourceManager,
- ZipClient,
JsonSerializer,
AuthorizationContext,
NetworkManager)
@@ -334,10 +333,8 @@ namespace MediaBrowser.Api.Playback
SubtitleEncoder,
DeviceManager,
MediaSourceManager,
- ZipClient,
JsonSerializer,
AuthorizationContext,
- ImageProcessor,
EnvironmentInfo)
{
Request = Request
diff --git a/MediaBrowser.Controller/Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
index 5b8c9da6f..4eaecd0a0 100644
--- a/MediaBrowser.Controller/Drawing/IImageEncoder.cs
+++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using MediaBrowser.Model.Drawing;
namespace MediaBrowser.Controller.Drawing
@@ -9,12 +10,12 @@ namespace MediaBrowser.Controller.Drawing
/// Gets the supported input formats.
/// </summary>
/// <value>The supported input formats.</value>
- string[] SupportedInputFormats { get; }
+ IReadOnlyCollection<string> SupportedInputFormats { get; }
/// <summary>
/// Gets the supported output formats.
/// </summary>
/// <value>The supported output formats.</value>
- ImageFormat[] SupportedOutputFormats { get; }
+ IReadOnlyCollection<ImageFormat> SupportedOutputFormats { get; }
/// <summary>
/// Encodes the image.
diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
index 783182730..a11e2186f 100644
--- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs
+++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.Controller.Drawing
/// Gets the supported input formats.
/// </summary>
/// <value>The supported input formats.</value>
- string[] SupportedInputFormats { get; }
+ IReadOnlyCollection<string> SupportedInputFormats { get; }
/// <summary>
/// Gets the image enhancers.
@@ -26,16 +26,29 @@ namespace MediaBrowser.Controller.Drawing
/// <value>The image enhancers.</value>
IImageEnhancer[] ImageEnhancers { get; }
- ImageDimensions GetImageSize(string path);
+ /// <summary>
+ /// Gets the dimensions of the image.
+ /// </summary>
+ /// <param name="path">Path to the image file.</param>
+ /// <returns>ImageDimensions</returns>
+ ImageDimensions GetImageDimensions(string path);
/// <summary>
- /// Gets the size of the image.
+ /// Gets the dimensions of the image.
/// </summary>
+ /// <param name="item">The base item.</param>
/// <param name="info">The information.</param>
- /// <returns>ImageSize.</returns>
- ImageDimensions GetImageSize(BaseItem item, ItemImageInfo info);
+ /// <returns>ImageDimensions</returns>
+ ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info);
- ImageDimensions GetImageSize(BaseItem item, ItemImageInfo info, bool updateItem);
+ /// <summary>
+ /// Gets the dimensions of the image.
+ /// </summary>
+ /// <param name="item">The base item.</param>
+ /// <param name="info">The information.</param>
+ /// <param name="updateItem">Whether or not the item info should be updated.</param>
+ /// <returns>ImageDimensions</returns>
+ ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem);
/// <summary>
/// Adds the parts.
@@ -96,8 +109,8 @@ namespace MediaBrowser.Controller.Drawing
/// <summary>
/// Gets the supported image output formats.
/// </summary>
- /// <returns>ImageOutputFormat[].</returns>
- ImageFormat[] GetSupportedImageOutputFormats();
+ /// <returns>IReadOnlyCollection{ImageOutput}.</returns>
+ IReadOnlyCollection<ImageFormat> GetSupportedImageOutputFormats();
/// <summary>
/// Creates the image collage.
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
index ba3813d8a..b71a76648 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
@@ -13,11 +13,6 @@ namespace MediaBrowser.Controller.LiveTv
public interface ILiveTvService
{
/// <summary>
- /// Occurs when [data source changed].
- /// </summary>
- event EventHandler DataSourceChanged;
-
- /// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
index 4e7e1c8ed..4242a00e2 100644
--- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
+++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
@@ -6,7 +6,6 @@ using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Controller.Net
@@ -23,8 +22,8 @@ namespace MediaBrowser.Controller.Net
/// <summary>
/// The _active connections
/// </summary>
- protected readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>> ActiveConnections =
- new List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>>();
+ protected readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType>> ActiveConnections =
+ new List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType>>();
/// <summary>
/// Gets the name.
@@ -44,8 +43,6 @@ namespace MediaBrowser.Controller.Net
/// </summary>
protected ILogger Logger;
- protected ITimerFactory TimerFactory { get; private set; }
-
protected BasePeriodicWebSocketListener(ILogger logger)
{
if (logger == null)
@@ -111,7 +108,7 @@ namespace MediaBrowser.Controller.Net
Logger.LogDebug("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name);
var timer = SendOnTimer ?
- TimerFactory.Create(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) :
+ new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) :
null;
var state = new TStateType
@@ -122,7 +119,7 @@ namespace MediaBrowser.Controller.Net
lock (ActiveConnections)
{
- ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>(message.Connection, cancellationTokenSource, timer, state));
+ ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType>(message.Connection, cancellationTokenSource, timer, state));
}
if (timer != null)
@@ -139,7 +136,7 @@ namespace MediaBrowser.Controller.Net
{
var connection = (IWebSocketConnection)state;
- Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType> tuple;
+ Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType> tuple;
lock (ActiveConnections)
{
@@ -162,7 +159,7 @@ namespace MediaBrowser.Controller.Net
protected void SendData(bool force)
{
- Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>[] tuples;
+ Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType>[] tuples;
lock (ActiveConnections)
{
@@ -190,7 +187,7 @@ namespace MediaBrowser.Controller.Net
}
}
- private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType> tuple)
+ private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType> tuple)
{
var connection = tuple.Item1;
@@ -249,7 +246,7 @@ namespace MediaBrowser.Controller.Net
/// Disposes the connection.
/// </summary>
/// <param name="connection">The connection.</param>
- private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType> connection)
+ private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType> connection)
{
Logger.LogDebug("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name);
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index d698795dd..f0e81e8e7 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -1,10 +1,10 @@
using System;
using System.Linq;
+using System.Threading;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
-using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Controller.Session
@@ -268,10 +268,10 @@ namespace MediaBrowser.Controller.Session
}
private readonly object _progressLock = new object();
- private ITimer _progressTimer;
+ private Timer _progressTimer;
private PlaybackProgressInfo _lastProgressInfo;
- public void StartAutomaticProgress(ITimerFactory timerFactory, PlaybackProgressInfo progressInfo)
+ public void StartAutomaticProgress(PlaybackProgressInfo progressInfo)
{
if (_disposed)
{
@@ -284,7 +284,7 @@ namespace MediaBrowser.Controller.Session
if (_progressTimer == null)
{
- _progressTimer = timerFactory.Create(OnProgressTimerCallback, null, 1000, 1000);
+ _progressTimer = new Timer(OnProgressTimerCallback, null, 1000, 1000);
}
else
{
diff --git a/MediaBrowser.Model/Drawing/ImageSize.cs b/MediaBrowser.Model/Drawing/ImageDimensions.cs
index 75591d83d..e7805ac49 100644
--- a/MediaBrowser.Model/Drawing/ImageSize.cs
+++ b/MediaBrowser.Model/Drawing/ImageDimensions.cs
@@ -1,7 +1,7 @@
namespace MediaBrowser.Model.Drawing
{
/// <summary>
- /// Struct ImageSize
+ /// Struct ImageDimensions
/// </summary>
public struct ImageDimensions
{
diff --git a/MediaBrowser.Model/Threading/ITimer.cs b/MediaBrowser.Model/Threading/ITimer.cs
deleted file mode 100644
index 2bec22266..000000000
--- a/MediaBrowser.Model/Threading/ITimer.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace MediaBrowser.Model.Threading
-{
- public interface ITimer : IDisposable
- {
- void Change(TimeSpan dueTime, TimeSpan period);
- void Change(int dueTimeMs, int periodMs);
- }
-}
diff --git a/MediaBrowser.Model/Threading/ITimerFactory.cs b/MediaBrowser.Model/Threading/ITimerFactory.cs
deleted file mode 100644
index 1161958a4..000000000
--- a/MediaBrowser.Model/Threading/ITimerFactory.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace MediaBrowser.Model.Threading
-{
- public interface ITimerFactory
- {
- ITimer Create(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period);
- ITimer Create(Action<object> callback, object state, int dueTimeMs, int periodMs);
- }
-}
diff --git a/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs b/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs
index b87f688e1..10ff2515c 100644
--- a/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs
+++ b/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs
@@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
+//TODO Fix namespace or replace
namespace Priority_Queue
{
/// <summary>
diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
index 4a94bcb1a..70d187bf5 100644
--- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
@@ -20,6 +20,7 @@ using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Music;
using MediaBrowser.Providers.TV;
+using MediaBrowser.Providers.TV.FanArt;
namespace MediaBrowser.Providers.Movies
{
diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
index 2efeb6985..75b4213c5 100644
--- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
@@ -20,6 +20,7 @@ using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.TV;
+using MediaBrowser.Providers.TV.FanArt;
namespace MediaBrowser.Providers.Music
{
diff --git a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs
index cf2acdf49..181e88820 100644
--- a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs
+++ b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs
@@ -18,6 +18,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Xml;
using MediaBrowser.Providers.TV;
+using MediaBrowser.Providers.TV.TheTVDB;
namespace MediaBrowser.Providers.People
{
diff --git a/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs
index 493729446..58356910f 100644
--- a/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs
@@ -19,7 +19,7 @@ using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.FanArt
{
public class FanArtSeasonProvider : IRemoteImageProvider, IHasOrder
{
diff --git a/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs b/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs
index 172a7d2b8..49cd9596e 100644
--- a/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs
@@ -22,7 +22,7 @@ using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Music;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.FanArt
{
public class FanartSeriesProvider : IRemoteImageProvider, IHasOrder
{
diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
index 4ac012399..25ad36620 100644
--- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
@@ -16,6 +16,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
+using MediaBrowser.Providers.TV.TheTVDB;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Providers.TV
diff --git a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs
index 6f7d9f791..d0749405b 100644
--- a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs
@@ -14,7 +14,7 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Omdb;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.Omdb
{
class OmdbEpisodeProvider :
IRemoteMetadataProvider<Episode, EpisodeInfo>,
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs
index 2482aa8d4..e4248afe1 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs
@@ -16,7 +16,7 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Movies;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheMovieDb
{
public class MovieDbEpisodeImageProvider :
MovieDbProviderBase,
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs
index 347c91742..44590515e 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs
@@ -18,7 +18,7 @@ using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheMovieDb
{
class MovieDbEpisodeProvider :
MovieDbProviderBase,
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs
index 9f1102946..6e438ebd8 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs
@@ -12,7 +12,7 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Movies;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheMovieDb
{
public abstract class MovieDbProviderBase
{
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs
index 790b38074..6be1b101d 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs
@@ -18,7 +18,7 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Movies;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheMovieDb
{
public class MovieDbSeasonProvider : IRemoteMetadataProvider<Season, SeasonInfo>
{
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs
index fdc8cd7f1..26686356f 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs
@@ -14,7 +14,7 @@ using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Movies;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheMovieDb
{
public class MovieDbSeriesImageProvider : IRemoteImageProvider, IHasOrder
{
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs
index 76031a7cd..b51fb6af8 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs
@@ -20,7 +20,7 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Providers.Movies;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheMovieDb
{
public class MovieDbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
{
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs
index 39d2fa77a..102a3d4ec 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs
@@ -14,7 +14,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Providers;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheTVDB
{
public class TvdbEpisodeImageProvider : IRemoteImageProvider
{
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs
index 25fc214b5..be137e879 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs
@@ -18,7 +18,7 @@ using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheTVDB
{
/// <summary>
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs
index 6f7cb72d3..d45696057 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs
@@ -19,7 +19,7 @@ using MediaBrowser.Model.Net;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheTVDB
{
/// <summary>
/// Class TvdbPrescanTask
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs
index af36d1ebf..01ede44bb 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs
@@ -19,7 +19,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Xml;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheTVDB
{
public class TvdbSeasonImageProvider : IRemoteImageProvider, IHasOrder
{
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs
index 82fa14f49..2b4337ed1 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs
@@ -19,7 +19,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Xml;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheTVDB
{
public class TvdbSeriesImageProvider : IRemoteImageProvider, IHasOrder
{
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
index 6006ed052..52e60a8ed 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
@@ -23,7 +23,7 @@ using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
-namespace MediaBrowser.Providers.TV
+namespace MediaBrowser.Providers.TV.TheTVDB
{
public class TvdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
{
diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs
index 001ce1465..5c246e300 100644
--- a/MediaBrowser.Providers/TV/TvExternalIds.cs
+++ b/MediaBrowser.Providers/TV/TvExternalIds.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Providers.TV.TheTVDB;
namespace MediaBrowser.Providers.TV
{
diff --git a/README.md b/README.md
index dfa8457de..d869c8978 100644
--- a/README.md
+++ b/README.md
@@ -5,13 +5,17 @@
<p align="center">
<img alt="Logo banner" src="https://raw.githubusercontent.com/jellyfin/jellyfin-ux/master/branding/SVG/banner-logo-solid.svg?sanitize=true"/>
-<br/></br>
-<a href="https://github.com/jellyfin/jellyfin"><img alt="GPL 2.0 License" src="https://img.shields.io/github/license/jellyfin/jellyfin.svg"></a>
-<a href="https://cloud.drone.io/jellyfin/jellyfin"><img alt="Build Status" src="https://cloud.drone.io/api/badges/jellyfin/jellyfin/status.svg"></a>
-<a href="https://hub.docker.com/r/jellyfin/jellyfin"><img alt="Docker Pull Count" src="https://img.shields.io/docker/pulls/jellyfin/jellyfin.svg"></a>
-<a href="https://jellyfin.readthedocs.io"><img alt="Documentation" src="https://img.shields.io/readthedocs/jellyfin.svg"></a>
-<a href="https://matrix.to/#/+jellyfin:matrix.org"><img alt="Chat on Matrix" src="https://img.shields.io/matrix/jellyfin:matrix.org.svg?logo=matrix"></a>
-<a href="https://www.reddit.com/r/jellyfin/"><img alt="Join our Subreddit" src="https://img.shields.io/badge/reddit-r%2Fjellyfin-%23FF5700.svg"></a>
+<br/><br/>
+<a href="https://github.com/jellyfin/jellyfin"><img alt="GPL 2.0 License" src="https://img.shields.io/github/license/jellyfin/jellyfin.svg"/></a>
+<a href="https://github.com/jellyfin/jellyfin/releases"><img alt="Current Release" src="https://img.shields.io/github/release/jellyfin/jellyfin.svg"/></a>
+<a href="https://translate.jellyfin.org/engage/jellyfin/?utm_source=widget"><img alt="Translations" src="https://translate.jellyfin.org/widgets/jellyfin/-/svg-badge.svg"/></a>
+<a href="https://cloud.drone.io/jellyfin/jellyfin"><img alt="Build Status" src="https://cloud.drone.io/api/badges/jellyfin/jellyfin/status.svg"/></a>
+<a href="https://hub.docker.com/r/jellyfin/jellyfin"><img alt="Docker Pull Count" src="https://img.shields.io/docker/pulls/jellyfin/jellyfin.svg"/></a>
+</br>
+<a href="https://opencollective.com/jellyfin"><img alt="Donate" src="https://img.shields.io/opencollective/all/jellyfin.svg?label=backers"/></a>
+<a href="https://forum.jellyfin.org"/><img alt="Discuss on our Forum" src="https://img.shields.io/discourse/https/forum.jellyfin.org/users.svg"/></a>
+<a href="https://matrix.to/#/+jellyfin:matrix.org"><img alt="Chat on Matrix" src="https://img.shields.io/matrix/jellyfin:matrix.org.svg?logo=matrix"/></a>
+<a href="https://www.reddit.com/r/jellyfin/"><img alt="Join our Subreddit" src="https://img.shields.io/badge/reddit-r%2Fjellyfin-%23FF5700.svg"/></a>
</p>
---
@@ -24,13 +28,13 @@ For more information about the project, please see our [about page](https://jell
<p align="center">
<strong>Want to get started?</strong>
-<em>Choose from <a href="https://jellyfin.readthedocs.io/en/latest/user-docs/installing/">Prebuilt Packages</a> or <a href="https://jellyfin.readthedocs.io/en/latest/user-docs/building/">Build from Source</a>, then see our <a href="https://jellyfin.readthedocs.io/en/latest/user-docs/quick-start/">Quickstart guide</a>.</em>
+<em>Choose from <a href="https://jellyfin.readthedocs.io/en/latest/administrator-docs/installing/">Prebuilt Packages</a> or <a href="https://jellyfin.readthedocs.io/en/latest/administrator-docs/building/">Build from Source</a>, then see our <a href="https://jellyfin.readthedocs.io/en/latest/administrator-docs/first-time/">first-time setup guide</a>.</em>
</p>
<p align="center">
<strong>Want to contribute?</strong>
-<em>Check out <a href="https://jellyfin.readthedocs.io/en/latest/developer-docs/contributing/">our documentation for guidelines</a>.</em>
+<em>Check out <a href="https://jellyfin.readthedocs.io/en/latest/contributor-docs/contributing/">our documentation for guidelines</a>.</em>
</p>
<p align="center">
<strong>New idea or improvement? Something not working right?</strong>
-<em>Open an <a href="https://jellyfin.readthedocs.io/en/latest/developer-docs/issues/">Issue</a>.</em>
+<em>Open an <a href="https://jellyfin.readthedocs.io/en/latest/contributor-docs/issues/">Issue</a>.</em>
</p>
diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs
index 1348cce8d..128bdfcbb 100644
--- a/RSSDP/SsdpDeviceLocator.cs
+++ b/RSSDP/SsdpDeviceLocator.cs
@@ -8,7 +8,6 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
-using MediaBrowser.Model.Threading;
namespace Rssdp.Infrastructure
{
@@ -23,8 +22,7 @@ namespace Rssdp.Infrastructure
private List<DiscoveredSsdpDevice> _Devices;
private ISsdpCommunicationsServer _CommunicationsServer;
- private ITimer _BroadcastTimer;
- private ITimerFactory _timerFactory;
+ private Timer _BroadcastTimer;
private object _timerLock = new object();
private readonly TimeSpan DefaultSearchWaitTime = TimeSpan.FromSeconds(4);
@@ -37,12 +35,11 @@ namespace Rssdp.Infrastructure
/// <summary>
/// Default constructor.
/// </summary>
- public SsdpDeviceLocator(ISsdpCommunicationsServer communicationsServer, ITimerFactory timerFactory)
+ public SsdpDeviceLocator(ISsdpCommunicationsServer communicationsServer)
{
if (communicationsServer == null) throw new ArgumentNullException(nameof(communicationsServer));
_CommunicationsServer = communicationsServer;
- _timerFactory = timerFactory;
_CommunicationsServer.ResponseReceived += CommsServer_ResponseReceived;
_Devices = new List<DiscoveredSsdpDevice>();
@@ -94,7 +91,7 @@ namespace Rssdp.Infrastructure
{
if (_BroadcastTimer == null)
{
- _BroadcastTimer = _timerFactory.Create(OnBroadcastTimerCallback, null, dueTime, period);
+ _BroadcastTimer = new Timer(OnBroadcastTimerCallback, null, dueTime, period);
}
else
{
diff --git a/RSSDP/SsdpDevicePublisher.cs b/RSSDP/SsdpDevicePublisher.cs
index 8a73e6a2d..ce64ba117 100644
--- a/RSSDP/SsdpDevicePublisher.cs
+++ b/RSSDP/SsdpDevicePublisher.cs
@@ -7,7 +7,6 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
-using MediaBrowser.Model.Threading;
using Rssdp;
namespace Rssdp.Infrastructure
@@ -27,8 +26,7 @@ namespace Rssdp.Infrastructure
private IList<SsdpRootDevice> _Devices;
private IReadOnlyList<SsdpRootDevice> _ReadOnlyDevices;
- private ITimer _RebroadcastAliveNotificationsTimer;
- private ITimerFactory _timerFactory;
+ private Timer _RebroadcastAliveNotificationsTimer;
private IDictionary<string, SearchRequest> _RecentSearchRequests;
@@ -39,7 +37,7 @@ namespace Rssdp.Infrastructure
/// <summary>
/// Default constructor.
/// </summary>
- public SsdpDevicePublisher(ISsdpCommunicationsServer communicationsServer, ITimerFactory timerFactory, string osName, string osVersion)
+ public SsdpDevicePublisher(ISsdpCommunicationsServer communicationsServer, string osName, string osVersion)
{
if (communicationsServer == null) throw new ArgumentNullException(nameof(communicationsServer));
if (osName == null) throw new ArgumentNullException(nameof(osName));
@@ -48,7 +46,6 @@ namespace Rssdp.Infrastructure
if (osVersion.Length == 0) throw new ArgumentException("osVersion cannot be an empty string.", nameof(osName));
_SupportPnpRootDevice = true;
- _timerFactory = timerFactory;
_Devices = new List<SsdpRootDevice>();
_ReadOnlyDevices = new ReadOnlyCollection<SsdpRootDevice>(_Devices);
_RecentSearchRequests = new Dictionary<string, SearchRequest>(StringComparer.OrdinalIgnoreCase);
@@ -64,7 +61,7 @@ namespace Rssdp.Infrastructure
public void StartBroadcastingAliveMessages(TimeSpan interval)
{
- _RebroadcastAliveNotificationsTimer = _timerFactory.Create(SendAllAliveNotifications, null, TimeSpan.FromSeconds(5), interval);
+ _RebroadcastAliveNotificationsTimer = new Timer(SendAllAliveNotifications, null, TimeSpan.FromSeconds(5), interval);
}
/// <summary>