Browse Source

Merge pull request #10838 from barronpm/livetv-project

Move Live TV code to Jellyfin.LiveTv
Cody Robibero 1 năm trước cách đây
mục cha
commit
82df226246
100 tập tin đã thay đổi với 218 bổ sung134 xóa
  1. 0 9
      Emby.Server.Implementations/ApplicationHost.cs
  2. 0 1
      Emby.Server.Implementations/Emby.Server.Implementations.csproj
  3. 34 1
      Emby.Server.Implementations/Library/MediaSourceManager.cs
  4. 13 0
      Jellyfin.Server/CoreAppHost.cs
  5. 1 0
      Jellyfin.Server/Jellyfin.Server.csproj
  6. 14 0
      Jellyfin.sln
  7. 9 0
      MediaBrowser.Controller/Library/IMediaSourceManager.cs
  8. 1 1
      src/Jellyfin.LiveTv/Channels/ChannelDynamicMediaSourceProvider.cs
  9. 1 1
      src/Jellyfin.LiveTv/Channels/ChannelImageProvider.cs
  10. 1 1
      src/Jellyfin.LiveTv/Channels/ChannelManager.cs
  11. 1 1
      src/Jellyfin.LiveTv/Channels/ChannelPostScanTask.cs
  12. 1 1
      src/Jellyfin.LiveTv/Channels/RefreshChannelsScheduledTask.cs
  13. 1 2
      src/Jellyfin.LiveTv/EmbyTV/DirectRecorder.cs
  14. 1 35
      src/Jellyfin.LiveTv/EmbyTV/EmbyTV.cs
  15. 1 1
      src/Jellyfin.LiveTv/EmbyTV/EncodedRecorder.cs
  16. 1 1
      src/Jellyfin.LiveTv/EmbyTV/EntryPoint.cs
  17. 1 1
      src/Jellyfin.LiveTv/EmbyTV/EpgChannelData.cs
  18. 1 1
      src/Jellyfin.LiveTv/EmbyTV/IRecorder.cs
  19. 1 1
      src/Jellyfin.LiveTv/EmbyTV/ItemDataProvider.cs
  20. 1 1
      src/Jellyfin.LiveTv/EmbyTV/NfoConfigurationExtensions.cs
  21. 1 1
      src/Jellyfin.LiveTv/EmbyTV/RecordingHelper.cs
  22. 1 1
      src/Jellyfin.LiveTv/EmbyTV/SeriesTimerManager.cs
  23. 1 1
      src/Jellyfin.LiveTv/EmbyTV/TimerManager.cs
  24. 2 1
      src/Jellyfin.LiveTv/ExclusiveLiveStream.cs
  25. 23 0
      src/Jellyfin.LiveTv/Jellyfin.LiveTv.csproj
  26. 4 2
      src/Jellyfin.LiveTv/Listings/SchedulesDirect.cs
  27. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/BroadcasterDto.cs
  28. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/CaptionDto.cs
  29. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/CastDto.cs
  30. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ChannelDto.cs
  31. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ContentRatingDto.cs
  32. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/CrewDto.cs
  33. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/DayDto.cs
  34. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/Description1000Dto.cs
  35. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/Description100Dto.cs
  36. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/DescriptionsProgramDto.cs
  37. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/EventDetailsDto.cs
  38. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/GracenoteDto.cs
  39. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/HeadendsDto.cs
  40. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ImageDataDto.cs
  41. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/LineupDto.cs
  42. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/LineupsDto.cs
  43. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/LogoDto.cs
  44. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MapDto.cs
  45. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MetadataDto.cs
  46. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MetadataProgramsDto.cs
  47. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MetadataScheduleDto.cs
  48. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MovieDto.cs
  49. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MultipartDto.cs
  50. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ProgramDetailsDto.cs
  51. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ProgramDto.cs
  52. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/QualityRatingDto.cs
  53. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/RatingDto.cs
  54. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/RecommendationDto.cs
  55. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/RequestScheduleForChannelDto.cs
  56. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ShowImagesDto.cs
  57. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/StationDto.cs
  58. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/TitleDto.cs
  59. 1 1
      src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/TokenDto.cs
  60. 1 1
      src/Jellyfin.LiveTv/Listings/XmlTvListingsProvider.cs
  61. 1 1
      src/Jellyfin.LiveTv/LiveTvConfigurationFactory.cs
  62. 1 1
      src/Jellyfin.LiveTv/LiveTvDtoService.cs
  63. 3 2
      src/Jellyfin.LiveTv/LiveTvManager.cs
  64. 2 2
      src/Jellyfin.LiveTv/LiveTvMediaSourceProvider.cs
  65. 1 1
      src/Jellyfin.LiveTv/RecordingNotifier.cs
  66. 1 1
      src/Jellyfin.LiveTv/RefreshGuideScheduledTask.cs
  67. 1 1
      src/Jellyfin.LiveTv/StreamHelper.cs
  68. 1 1
      src/Jellyfin.LiveTv/TunerHosts/BaseTunerHost.cs
  69. 1 1
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/Channels.cs
  70. 1 1
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs
  71. 1 1
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunChannelCommands.cs
  72. 4 4
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
  73. 1 1
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs
  74. 2 1
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
  75. 1 1
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/IHdHomerunChannelCommands.cs
  76. 1 1
      src/Jellyfin.LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs
  77. 2 1
      src/Jellyfin.LiveTv/TunerHosts/LiveStream.cs
  78. 1 1
      src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs
  79. 1 1
      src/Jellyfin.LiveTv/TunerHosts/M3uParser.cs
  80. 2 1
      src/Jellyfin.LiveTv/TunerHosts/SharedHttpStream.cs
  81. 2 2
      tests/Jellyfin.LiveTv.Tests/HdHomerunHostTests.cs
  82. 2 2
      tests/Jellyfin.LiveTv.Tests/HdHomerunManagerTests.cs
  83. 29 0
      tests/Jellyfin.LiveTv.Tests/Jellyfin.LiveTv.Tests.csproj
  84. 2 2
      tests/Jellyfin.LiveTv.Tests/Listings/XmlTvListingsProviderTests.cs
  85. 2 2
      tests/Jellyfin.LiveTv.Tests/RecordingHelperTests.cs
  86. 2 2
      tests/Jellyfin.LiveTv.Tests/SchedulesDirect/SchedulesDirectDeserializeTests.cs
  87. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/discover.json
  88. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/lineup.json
  89. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/discover.json
  90. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/lineup.json
  91. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml
  92. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml
  93. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/headends_response.json
  94. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineup_response.json
  95. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineups_response.json
  96. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/metadata_programs_response.json
  97. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/programs_response.json
  98. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_request.json
  99. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_response.json
  100. 0 0
      tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_live_response.json

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

@@ -15,7 +15,6 @@ using System.Security.Cryptography.X509Certificates;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Emby.Naming.Common;
 using Emby.Naming.Common;
 using Emby.Photos;
 using Emby.Photos;
-using Emby.Server.Implementations.Channels;
 using Emby.Server.Implementations.Collections;
 using Emby.Server.Implementations.Collections;
 using Emby.Server.Implementations.Configuration;
 using Emby.Server.Implementations.Configuration;
 using Emby.Server.Implementations.Cryptography;
 using Emby.Server.Implementations.Cryptography;
@@ -25,7 +24,6 @@ using Emby.Server.Implementations.Dto;
 using Emby.Server.Implementations.HttpServer.Security;
 using Emby.Server.Implementations.HttpServer.Security;
 using Emby.Server.Implementations.IO;
 using Emby.Server.Implementations.IO;
 using Emby.Server.Implementations.Library;
 using Emby.Server.Implementations.Library;
-using Emby.Server.Implementations.LiveTv;
 using Emby.Server.Implementations.Localization;
 using Emby.Server.Implementations.Localization;
 using Emby.Server.Implementations.Playlists;
 using Emby.Server.Implementations.Playlists;
 using Emby.Server.Implementations.Plugins;
 using Emby.Server.Implementations.Plugins;
@@ -504,8 +502,6 @@ namespace Emby.Server.Implementations
 
 
             serviceCollection.AddSingleton(_xmlSerializer);
             serviceCollection.AddSingleton(_xmlSerializer);
 
 
-            serviceCollection.AddSingleton<IStreamHelper, StreamHelper>();
-
             serviceCollection.AddSingleton<ICryptoProvider, CryptographyProvider>();
             serviceCollection.AddSingleton<ICryptoProvider, CryptographyProvider>();
 
 
             serviceCollection.AddSingleton<ISocketFactory, SocketFactory>();
             serviceCollection.AddSingleton<ISocketFactory, SocketFactory>();
@@ -557,8 +553,6 @@ namespace Emby.Server.Implementations
             serviceCollection.AddTransient(provider => new Lazy<ILiveTvManager>(provider.GetRequiredService<ILiveTvManager>));
             serviceCollection.AddTransient(provider => new Lazy<ILiveTvManager>(provider.GetRequiredService<ILiveTvManager>));
             serviceCollection.AddSingleton<IDtoService, DtoService>();
             serviceCollection.AddSingleton<IDtoService, DtoService>();
 
 
-            serviceCollection.AddSingleton<IChannelManager, ChannelManager>();
-
             serviceCollection.AddSingleton<ISessionManager, SessionManager>();
             serviceCollection.AddSingleton<ISessionManager, SessionManager>();
 
 
             serviceCollection.AddSingleton<ICollectionManager, CollectionManager>();
             serviceCollection.AddSingleton<ICollectionManager, CollectionManager>();
@@ -567,9 +561,6 @@ namespace Emby.Server.Implementations
 
 
             serviceCollection.AddSingleton<ISyncPlayManager, SyncPlayManager>();
             serviceCollection.AddSingleton<ISyncPlayManager, SyncPlayManager>();
 
 
-            serviceCollection.AddSingleton<LiveTvDtoService>();
-            serviceCollection.AddSingleton<ILiveTvManager, LiveTvManager>();
-
             serviceCollection.AddSingleton<IUserViewManager, UserViewManager>();
             serviceCollection.AddSingleton<IUserViewManager, UserViewManager>();
 
 
             serviceCollection.AddSingleton<IChapterManager, ChapterManager>();
             serviceCollection.AddSingleton<IChapterManager, ChapterManager>();

+ 0 - 1
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -22,7 +22,6 @@
 
 
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="DiscUtils.Udf" />
     <PackageReference Include="DiscUtils.Udf" />
-    <PackageReference Include="Jellyfin.XmlTv" />
     <PackageReference Include="Microsoft.Data.Sqlite" />
     <PackageReference Include="Microsoft.Data.Sqlite" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" />
     <PackageReference Include="Microsoft.Extensions.Caching.Memory" />
     <PackageReference Include="Microsoft.Extensions.Caching.Memory" />

+ 34 - 1
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -11,14 +11,15 @@ using System.Linq;
 using System.Text.Json;
 using System.Text.Json;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using EasyCaching.Core.Configurations;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
 using Jellyfin.Data.Enums;
 using Jellyfin.Extensions.Json;
 using Jellyfin.Extensions.Json;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Providers;
@@ -37,6 +38,7 @@ namespace Emby.Server.Implementations.Library
         // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
         // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
         private const char LiveStreamIdDelimeter = '_';
         private const char LiveStreamIdDelimeter = '_';
 
 
+        private readonly IServerApplicationHost _appHost;
         private readonly IItemRepository _itemRepo;
         private readonly IItemRepository _itemRepo;
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
@@ -55,6 +57,7 @@ namespace Emby.Server.Implementations.Library
         private IMediaSourceProvider[] _providers;
         private IMediaSourceProvider[] _providers;
 
 
         public MediaSourceManager(
         public MediaSourceManager(
+            IServerApplicationHost appHost,
             IItemRepository itemRepo,
             IItemRepository itemRepo,
             IApplicationPaths applicationPaths,
             IApplicationPaths applicationPaths,
             ILocalizationManager localizationManager,
             ILocalizationManager localizationManager,
@@ -66,6 +69,7 @@ namespace Emby.Server.Implementations.Library
             IMediaEncoder mediaEncoder,
             IMediaEncoder mediaEncoder,
             IDirectoryService directoryService)
             IDirectoryService directoryService)
         {
         {
+            _appHost = appHost;
             _itemRepo = itemRepo;
             _itemRepo = itemRepo;
             _userManager = userManager;
             _userManager = userManager;
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
@@ -799,6 +803,35 @@ namespace Emby.Server.Implementations.Library
             return result.Item1;
             return result.Item1;
         }
         }
 
 
+        public async Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken)
+        {
+            var stream = new MediaSourceInfo
+            {
+                EncoderPath = _appHost.GetApiUrlForLocalAccess() + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
+                EncoderProtocol = MediaProtocol.Http,
+                Path = info.Path,
+                Protocol = MediaProtocol.File,
+                Id = info.Id,
+                SupportsDirectPlay = false,
+                SupportsDirectStream = true,
+                SupportsTranscoding = true,
+                IsInfiniteStream = true,
+                RequiresOpening = false,
+                RequiresClosing = false,
+                BufferMs = 0,
+                IgnoreDts = true,
+                IgnoreIndex = true
+            };
+
+            await new LiveStreamHelper(_mediaEncoder, _logger, _appPaths)
+                .AddMediaInfoWithProbe(stream, false, false, cancellationToken).ConfigureAwait(false);
+
+            return new List<MediaSourceInfo>
+            {
+                stream
+            };
+        }
+
         public async Task CloseLiveStream(string id)
         public async Task CloseLiveStream(string id)
         {
         {
             ArgumentException.ThrowIfNullOrEmpty(id);
             ArgumentException.ThrowIfNullOrEmpty(id);

+ 13 - 0
Jellyfin.Server/CoreAppHost.cs

@@ -6,6 +6,8 @@ using Emby.Server.Implementations.Session;
 using Jellyfin.Api.WebSocketListeners;
 using Jellyfin.Api.WebSocketListeners;
 using Jellyfin.Drawing;
 using Jellyfin.Drawing;
 using Jellyfin.Drawing.Skia;
 using Jellyfin.Drawing.Skia;
+using Jellyfin.LiveTv;
+using Jellyfin.LiveTv.Channels;
 using Jellyfin.Server.Implementations;
 using Jellyfin.Server.Implementations;
 using Jellyfin.Server.Implementations.Activity;
 using Jellyfin.Server.Implementations.Activity;
 using Jellyfin.Server.Implementations.Devices;
 using Jellyfin.Server.Implementations.Devices;
@@ -16,15 +18,18 @@ using Jellyfin.Server.Implementations.Users;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Authentication;
 using MediaBrowser.Controller.Authentication;
 using MediaBrowser.Controller.BaseItemManager;
 using MediaBrowser.Controller.BaseItemManager;
+using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Events;
 using MediaBrowser.Controller.Events;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Lyrics;
 using MediaBrowser.Controller.Lyrics;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Security;
 using MediaBrowser.Controller.Security;
 using MediaBrowser.Controller.Trickplay;
 using MediaBrowser.Controller.Trickplay;
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.IO;
 using MediaBrowser.Providers.Lyric;
 using MediaBrowser.Providers.Lyric;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
@@ -96,6 +101,11 @@ namespace Jellyfin.Server
 
 
             serviceCollection.AddScoped<IAuthenticationManager, AuthenticationManager>();
             serviceCollection.AddScoped<IAuthenticationManager, AuthenticationManager>();
 
 
+            serviceCollection.AddSingleton<LiveTvDtoService>();
+            serviceCollection.AddSingleton<ILiveTvManager, LiveTvManager>();
+            serviceCollection.AddSingleton<IChannelManager, ChannelManager>();
+            serviceCollection.AddSingleton<IStreamHelper, StreamHelper>();
+
             foreach (var type in GetExportTypes<ILyricProvider>())
             foreach (var type in GetExportTypes<ILyricProvider>())
             {
             {
                 serviceCollection.AddSingleton(typeof(ILyricProvider), type);
                 serviceCollection.AddSingleton(typeof(ILyricProvider), type);
@@ -117,6 +127,9 @@ namespace Jellyfin.Server
 
 
             // Jellyfin.Server.Implementations
             // Jellyfin.Server.Implementations
             yield return typeof(JellyfinDbContext).Assembly;
             yield return typeof(JellyfinDbContext).Assembly;
+
+            // Jellyfin.LiveTv
+            yield return typeof(LiveTvManager).Assembly;
         }
         }
     }
     }
 }
 }

+ 1 - 0
Jellyfin.Server/Jellyfin.Server.csproj

@@ -58,6 +58,7 @@
     <ProjectReference Include="..\src\Jellyfin.Drawing\Jellyfin.Drawing.csproj" />
     <ProjectReference Include="..\src\Jellyfin.Drawing\Jellyfin.Drawing.csproj" />
     <ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
     <ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
     <ProjectReference Include="..\src\Jellyfin.Drawing.Skia\Jellyfin.Drawing.Skia.csproj" />
     <ProjectReference Include="..\src\Jellyfin.Drawing.Skia\Jellyfin.Drawing.Skia.csproj" />
+    <ProjectReference Include="..\src\Jellyfin.LiveTv\Jellyfin.LiveTv.csproj" />
     <ProjectReference Include="..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" />
     <ProjectReference Include="..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" />
     <ProjectReference Include="..\src\Jellyfin.MediaEncoding.Hls\Jellyfin.MediaEncoding.Hls.csproj" />
     <ProjectReference Include="..\src\Jellyfin.MediaEncoding.Hls\Jellyfin.MediaEncoding.Hls.csproj" />
   </ItemGroup>
   </ItemGroup>

+ 14 - 0
Jellyfin.sln

@@ -87,6 +87,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Hls.
 EndProject
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Keyframes.Tests", "tests\Jellyfin.MediaEncoding.Keyframes.Tests\Jellyfin.MediaEncoding.Keyframes.Tests.csproj", "{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}"
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Keyframes.Tests", "tests\Jellyfin.MediaEncoding.Keyframes.Tests\Jellyfin.MediaEncoding.Keyframes.Tests.csproj", "{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}"
 EndProject
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.LiveTv.Tests", "tests\Jellyfin.LiveTv.Tests\Jellyfin.LiveTv.Tests.csproj", "{C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.LiveTv", "src\Jellyfin.LiveTv\Jellyfin.LiveTv.csproj", "{8C6B2B13-58A4-4506-9DAB-1F882A093FE0}"
+EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Debug|Any CPU = Debug|Any CPU
@@ -233,6 +237,14 @@ Global
 		{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Release|Any CPU.Build.0 = Release|Any CPU
 		{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{8C6B2B13-58A4-4506-9DAB-1F882A093FE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{8C6B2B13-58A4-4506-9DAB-1F882A093FE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{8C6B2B13-58A4-4506-9DAB-1F882A093FE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{8C6B2B13-58A4-4506-9DAB-1F882A093FE0}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE
@@ -259,6 +271,8 @@ Global
 		{08FFF49B-F175-4807-A2B5-73B0EBD9F716} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
 		{08FFF49B-F175-4807-A2B5-73B0EBD9F716} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
 		{154872D9-6C12-4007-96E3-8F70A58386CE} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
 		{154872D9-6C12-4007-96E3-8F70A58386CE} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
 		{0A3FCC4D-C714-4072-B90F-E374A15F9FF9} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
 		{0A3FCC4D-C714-4072-B90F-E374A15F9FF9} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
+		{C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6}
+		{8C6B2B13-58A4-4506-9DAB-1F882A093FE0} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C}
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE}
 		SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE}

+ 9 - 0
MediaBrowser.Controller/Library/IMediaSourceManager.cs

@@ -8,6 +8,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
@@ -116,6 +117,14 @@ namespace MediaBrowser.Controller.Library
         /// <returns>An instance of <see cref="ILiveStream"/>.</returns>
         /// <returns>An instance of <see cref="ILiveStream"/>.</returns>
         public ILiveStream GetLiveStreamInfoByUniqueId(string uniqueId);
         public ILiveStream GetLiveStreamInfoByUniqueId(string uniqueId);
 
 
+        /// <summary>
+        /// Gets the media sources for an active recording.
+        /// </summary>
+        /// <param name="info">The <see cref="ActiveRecordingInfo"/>.</param>
+        /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
+        /// <returns>A task containing the <see cref="MediaSourceInfo"/>'s for the recording.</returns>
+        Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken);
+
         /// <summary>
         /// <summary>
         /// Closes the media source.
         /// Closes the media source.
         /// </summary>
         /// </summary>

+ 1 - 1
Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs → src/Jellyfin.LiveTv/Channels/ChannelDynamicMediaSourceProvider.cs

@@ -8,7 +8,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 
 
-namespace Emby.Server.Implementations.Channels
+namespace Jellyfin.LiveTv.Channels
 {
 {
     /// <summary>
     /// <summary>
     /// A media source provider for channels.
     /// A media source provider for channels.

+ 1 - 1
Emby.Server.Implementations/Channels/ChannelImageProvider.cs → src/Jellyfin.LiveTv/Channels/ChannelImageProvider.cs

@@ -7,7 +7,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 
 
-namespace Emby.Server.Implementations.Channels
+namespace Jellyfin.LiveTv.Channels
 {
 {
     /// <summary>
     /// <summary>
     /// An image provider for channels.
     /// An image provider for channels.

+ 1 - 1
Emby.Server.Implementations/Channels/ChannelManager.cs → src/Jellyfin.LiveTv/Channels/ChannelManager.cs

@@ -34,7 +34,7 @@ using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
 using Season = MediaBrowser.Controller.Entities.TV.Season;
 using Season = MediaBrowser.Controller.Entities.TV.Season;
 using Series = MediaBrowser.Controller.Entities.TV.Series;
 using Series = MediaBrowser.Controller.Entities.TV.Series;
 
 
-namespace Emby.Server.Implementations.Channels
+namespace Jellyfin.LiveTv.Channels
 {
 {
     /// <summary>
     /// <summary>
     /// The LiveTV channel manager.
     /// The LiveTV channel manager.

+ 1 - 1
Emby.Server.Implementations/Channels/ChannelPostScanTask.cs → src/Jellyfin.LiveTv/Channels/ChannelPostScanTask.cs

@@ -8,7 +8,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.Channels
+namespace Jellyfin.LiveTv.Channels
 {
 {
     /// <summary>
     /// <summary>
     /// A task to remove all non-installed channels from the database.
     /// A task to remove all non-installed channels from the database.

+ 1 - 1
Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs → src/Jellyfin.LiveTv/Channels/RefreshChannelsScheduledTask.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.Tasks;
 using MediaBrowser.Model.Tasks;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.Channels
+namespace Jellyfin.LiveTv.Channels
 {
 {
     /// <summary>
     /// <summary>
     /// The "Refresh Channels" scheduled task.
     /// The "Refresh Channels" scheduled task.

+ 1 - 2
Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs → src/Jellyfin.LiveTv/EmbyTV/DirectRecorder.cs

@@ -5,7 +5,6 @@ using System.IO;
 using System.Net.Http;
 using System.Net.Http;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using Jellyfin.Api.Helpers;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Streaming;
 using MediaBrowser.Controller.Streaming;
@@ -13,7 +12,7 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public sealed class DirectRecorder : IRecorder
     public sealed class DirectRecorder : IRecorder
     {
     {

+ 1 - 35
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs → src/Jellyfin.LiveTv/EmbyTV/EmbyTV.cs

@@ -14,14 +14,12 @@ using System.Text;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Xml;
 using System.Xml;
-using Emby.Server.Implementations.Library;
 using Jellyfin.Data.Enums;
 using Jellyfin.Data.Enums;
 using Jellyfin.Data.Events;
 using Jellyfin.Data.Events;
 using Jellyfin.Extensions;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Common.Progress;
-using MediaBrowser.Controller;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
@@ -39,7 +37,7 @@ using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Providers;
 using MediaBrowser.Model.Providers;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public sealed class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable
     public sealed class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable
     {
     {
@@ -47,7 +45,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
 
         private const int TunerDiscoveryDurationMs = 3000;
         private const int TunerDiscoveryDurationMs = 3000;
 
 
-        private readonly IServerApplicationHost _appHost;
         private readonly ILogger<EmbyTV> _logger;
         private readonly ILogger<EmbyTV> _logger;
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IServerConfigurationManager _config;
         private readonly IServerConfigurationManager _config;
@@ -76,7 +73,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         private bool _disposed;
         private bool _disposed;
 
 
         public EmbyTV(
         public EmbyTV(
-            IServerApplicationHost appHost,
             IStreamHelper streamHelper,
             IStreamHelper streamHelper,
             IMediaSourceManager mediaSourceManager,
             IMediaSourceManager mediaSourceManager,
             ILogger<EmbyTV> logger,
             ILogger<EmbyTV> logger,
@@ -91,7 +87,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         {
         {
             Current = this;
             Current = this;
 
 
-            _appHost = appHost;
             _logger = logger;
             _logger = logger;
             _httpClientFactory = httpClientFactory;
             _httpClientFactory = httpClientFactory;
             _config = config;
             _config = config;
@@ -1021,35 +1016,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             throw new NotImplementedException();
             throw new NotImplementedException();
         }
         }
 
 
-        public async Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken)
-        {
-            var stream = new MediaSourceInfo
-            {
-                EncoderPath = _appHost.GetApiUrlForLocalAccess() + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
-                EncoderProtocol = MediaProtocol.Http,
-                Path = info.Path,
-                Protocol = MediaProtocol.File,
-                Id = info.Id,
-                SupportsDirectPlay = false,
-                SupportsDirectStream = true,
-                SupportsTranscoding = true,
-                IsInfiniteStream = true,
-                RequiresOpening = false,
-                RequiresClosing = false,
-                BufferMs = 0,
-                IgnoreDts = true,
-                IgnoreIndex = true
-            };
-
-            await new LiveStreamHelper(_mediaEncoder, _logger, _config.CommonApplicationPaths)
-                .AddMediaInfoWithProbe(stream, false, false, cancellationToken).ConfigureAwait(false);
-
-            return new List<MediaSourceInfo>
-            {
-                stream
-            };
-        }
-
         public Task CloseLiveStream(string id, CancellationToken cancellationToken)
         public Task CloseLiveStream(string id, CancellationToken cancellationToken)
         {
         {
             return Task.CompletedTask;
             return Task.CompletedTask;

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs → src/Jellyfin.LiveTv/EmbyTV/EncodedRecorder.cs

@@ -23,7 +23,7 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public class EncodedRecorder : IRecorder
     public class EncodedRecorder : IRecorder
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs → src/Jellyfin.LiveTv/EmbyTV/EntryPoint.cs

@@ -3,7 +3,7 @@
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Plugins;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public sealed class EntryPoint : IServerEntryPoint
     public sealed class EntryPoint : IServerEntryPoint
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/EpgChannelData.cs → src/Jellyfin.LiveTv/EmbyTV/EpgChannelData.cs

@@ -4,7 +4,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     internal class EpgChannelData
     internal class EpgChannelData
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs → src/Jellyfin.LiveTv/EmbyTV/IRecorder.cs

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public interface IRecorder : IDisposable
     public interface IRecorder : IDisposable
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs → src/Jellyfin.LiveTv/EmbyTV/ItemDataProvider.cs

@@ -9,7 +9,7 @@ using System.Text.Json;
 using Jellyfin.Extensions.Json;
 using Jellyfin.Extensions.Json;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public class ItemDataProvider<T>
     public class ItemDataProvider<T>
         where T : class
         where T : class

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/NfoConfigurationExtensions.cs → src/Jellyfin.LiveTv/EmbyTV/NfoConfigurationExtensions.cs

@@ -1,7 +1,7 @@
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Configuration;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     /// <summary>
     /// <summary>
     /// Class containing extension methods for working with the nfo configuration.
     /// Class containing extension methods for working with the nfo configuration.

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs → src/Jellyfin.LiveTv/EmbyTV/RecordingHelper.cs

@@ -5,7 +5,7 @@ using System.Globalization;
 using System.Text;
 using System.Text;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     internal static class RecordingHelper
     internal static class RecordingHelper
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/SeriesTimerManager.cs → src/Jellyfin.LiveTv/EmbyTV/SeriesTimerManager.cs

@@ -4,7 +4,7 @@ using System;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public class SeriesTimerManager : ItemDataProvider<SeriesTimerInfo>
     public class SeriesTimerManager : ItemDataProvider<SeriesTimerInfo>
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs → src/Jellyfin.LiveTv/EmbyTV/TimerManager.cs

@@ -10,7 +10,7 @@ using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.EmbyTV
+namespace Jellyfin.LiveTv.EmbyTV
 {
 {
     public class TimerManager : ItemDataProvider<TimerInfo>
     public class TimerManager : ItemDataProvider<TimerInfo>
     {
     {

+ 2 - 1
Emby.Server.Implementations/Library/ExclusiveLiveStream.cs → src/Jellyfin.LiveTv/ExclusiveLiveStream.cs

@@ -1,5 +1,6 @@
 #nullable disable
 #nullable disable
 
 
+#pragma warning disable CA1711
 #pragma warning disable CS1591
 #pragma warning disable CS1591
 
 
 using System;
 using System;
@@ -10,7 +11,7 @@ using System.Threading.Tasks;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 
 
-namespace Emby.Server.Implementations.Library
+namespace Jellyfin.LiveTv
 {
 {
     public sealed class ExclusiveLiveStream : ILiveStream
     public sealed class ExclusiveLiveStream : ILiveStream
     {
     {

+ 23 - 0
src/Jellyfin.LiveTv/Jellyfin.LiveTv.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
+      <_Parameter1>Jellyfin.LiveTv.Tests</_Parameter1>
+    </AssemblyAttribute>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Jellyfin.XmlTv" />
+    <PackageReference Include="System.Linq.Async" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
+    <ProjectReference Include="..\..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
+    <ProjectReference Include="..\..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
+  </ItemGroup>
+</Project>

+ 4 - 2
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirect.cs

@@ -16,9 +16,9 @@ using System.Text;
 using System.Text.Json;
 using System.Text.Json;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos;
 using Jellyfin.Extensions;
 using Jellyfin.Extensions;
 using Jellyfin.Extensions.Json;
 using Jellyfin.Extensions.Json;
+using Jellyfin.LiveTv.Listings.SchedulesDirectDtos;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Authentication;
 using MediaBrowser.Controller.Authentication;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
@@ -27,7 +27,7 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings
+namespace Jellyfin.LiveTv.Listings
 {
 {
     public class SchedulesDirect : IListingsProvider, IDisposable
     public class SchedulesDirect : IListingsProvider, IDisposable
     {
     {
@@ -613,6 +613,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 
 
             // Response is automatically disposed in the calling function,
             // Response is automatically disposed in the calling function,
             // so dispose manually if not returning.
             // so dispose manually if not returning.
+#pragma warning disable IDISP016, IDISP017
             response.Dispose();
             response.Dispose();
             if (!enableRetry || (int)response.StatusCode >= 500)
             if (!enableRetry || (int)response.StatusCode >= 500)
             {
             {
@@ -621,6 +622,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
                     null,
                     null,
                     response.StatusCode);
                     response.StatusCode);
             }
             }
+#pragma warning restore IDISP016, IDISP017
 
 
             _tokens.Clear();
             _tokens.Clear();
             options.Headers.TryAddWithoutValidation("token", await GetToken(providerInfo, cancellationToken).ConfigureAwait(false));
             options.Headers.TryAddWithoutValidation("token", await GetToken(providerInfo, cancellationToken).ConfigureAwait(false));

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/BroadcasterDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/BroadcasterDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Broadcaster dto.
     /// Broadcaster dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/CaptionDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/CaptionDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Caption dto.
     /// Caption dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/CastDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/CastDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Cast dto.
     /// Cast dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/ChannelDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ChannelDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Channel dto.
     /// Channel dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/ContentRatingDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ContentRatingDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Content rating dto.
     /// Content rating dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/CrewDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/CrewDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Crew dto.
     /// Crew dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/DayDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/DayDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Day dto.
     /// Day dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/Description1000Dto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/Description1000Dto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Description 1_000 dto.
     /// Description 1_000 dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/Description100Dto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/Description100Dto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Description 100 dto.
     /// Description 100 dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/DescriptionsProgramDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/DescriptionsProgramDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Descriptions program dto.
     /// Descriptions program dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/EventDetailsDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/EventDetailsDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Event details dto.
     /// Event details dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/GracenoteDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/GracenoteDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Gracenote dto.
     /// Gracenote dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/HeadendsDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/HeadendsDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Headends dto.
     /// Headends dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/ImageDataDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ImageDataDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Image data dto.
     /// Image data dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/LineupDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/LineupDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// The lineup dto.
     /// The lineup dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/LineupsDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/LineupsDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Lineups dto.
     /// Lineups dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/LogoDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/LogoDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Logo dto.
     /// Logo dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/MapDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MapDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Map dto.
     /// Map dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/MetadataDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MetadataDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Metadata dto.
     /// Metadata dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/MetadataProgramsDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MetadataProgramsDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Metadata programs dto.
     /// Metadata programs dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/MetadataScheduleDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MetadataScheduleDto.cs

@@ -1,7 +1,7 @@
 using System;
 using System;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Metadata schedule dto.
     /// Metadata schedule dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/MovieDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MovieDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Movie dto.
     /// Movie dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/MultipartDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/MultipartDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Multipart dto.
     /// Multipart dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/ProgramDetailsDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ProgramDetailsDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Program details dto.
     /// Program details dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/ProgramDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ProgramDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Program dto.
     /// Program dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/QualityRatingDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/QualityRatingDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Quality rating dto.
     /// Quality rating dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/RatingDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/RatingDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Rating dto.
     /// Rating dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/RecommendationDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/RecommendationDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Recommendation dto.
     /// Recommendation dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/RequestScheduleForChannelDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/RequestScheduleForChannelDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Request schedule for channel dto.
     /// Request schedule for channel dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/ShowImagesDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/ShowImagesDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Show image dto.
     /// Show image dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/StationDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/StationDto.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Station dto.
     /// Station dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/TitleDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/TitleDto.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// Title dto.
     /// Title dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirectDtos/TokenDto.cs → src/Jellyfin.LiveTv/Listings/SchedulesDirectDtos/TokenDto.cs

@@ -1,7 +1,7 @@
 using System;
 using System;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos
+namespace Jellyfin.LiveTv.Listings.SchedulesDirectDtos
 {
 {
     /// <summary>
     /// <summary>
     /// The token dto.
     /// The token dto.

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs → src/Jellyfin.LiveTv/Listings/XmlTvListingsProvider.cs

@@ -23,7 +23,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.Listings
+namespace Jellyfin.LiveTv.Listings
 {
 {
     public class XmlTvListingsProvider : IListingsProvider
     public class XmlTvListingsProvider : IListingsProvider
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/LiveTvConfigurationFactory.cs → src/Jellyfin.LiveTv/LiveTvConfigurationFactory.cs

@@ -2,7 +2,7 @@ using System.Collections.Generic;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 
 
-namespace Emby.Server.Implementations.LiveTv
+namespace Jellyfin.LiveTv
 {
 {
     /// <summary>
     /// <summary>
     /// <see cref="IConfigurationFactory" /> implementation for <see cref="LiveTvOptions" />.
     /// <see cref="IConfigurationFactory" /> implementation for <see cref="LiveTvOptions" />.

+ 1 - 1
Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs → src/Jellyfin.LiveTv/LiveTvDtoService.cs

@@ -20,7 +20,7 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv
+namespace Jellyfin.LiveTv
 {
 {
     public class LiveTvDtoService
     public class LiveTvDtoService
     {
     {

+ 3 - 2
Emby.Server.Implementations/LiveTv/LiveTvManager.cs → src/Jellyfin.LiveTv/LiveTvManager.cs

@@ -9,7 +9,6 @@ using System.Linq;
 using System.Text.Json;
 using System.Text.Json;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using Emby.Server.Implementations.Library;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
 using Jellyfin.Data.Enums;
 using Jellyfin.Data.Events;
 using Jellyfin.Data.Events;
@@ -34,7 +33,7 @@ using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Tasks;
 using MediaBrowser.Model.Tasks;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv
+namespace Jellyfin.LiveTv
 {
 {
     /// <summary>
     /// <summary>
     /// Class LiveTvManager.
     /// Class LiveTvManager.
@@ -231,7 +230,9 @@ namespace Emby.Server.Implementations.LiveTv
             _logger.LogInformation("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId);
             _logger.LogInformation("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId);
 
 
             MediaSourceInfo info;
             MediaSourceInfo info;
+#pragma warning disable CA1859 // TODO: Analyzer bug?
             ILiveStream liveStream;
             ILiveStream liveStream;
+#pragma warning restore CA1859
             if (service is ISupportsDirectStreamProvider supportsManagedStream)
             if (service is ISupportsDirectStreamProvider supportsManagedStream)
             {
             {
                 liveStream = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(channel.ExternalId, mediaSourceId, currentLiveStreams, cancellationToken).ConfigureAwait(false);
                 liveStream = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(channel.ExternalId, mediaSourceId, currentLiveStreams, cancellationToken).ConfigureAwait(false);

+ 2 - 2
Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs → src/Jellyfin.LiveTv/LiveTvMediaSourceProvider.cs

@@ -16,7 +16,7 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv
+namespace Jellyfin.LiveTv
 {
 {
     public class LiveTvMediaSourceProvider : IMediaSourceProvider
     public class LiveTvMediaSourceProvider : IMediaSourceProvider
     {
     {
@@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.LiveTv
             {
             {
                 if (activeRecordingInfo is not null)
                 if (activeRecordingInfo is not null)
                 {
                 {
-                    sources = await EmbyTV.EmbyTV.Current.GetRecordingStreamMediaSources(activeRecordingInfo, cancellationToken)
+                    sources = await _mediaSourceManager.GetRecordingStreamMediaSources(activeRecordingInfo, cancellationToken)
                         .ConfigureAwait(false);
                         .ConfigureAwait(false);
                 }
                 }
                 else
                 else

+ 1 - 1
Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs → src/Jellyfin.LiveTv/RecordingNotifier.cs

@@ -15,7 +15,7 @@ using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Session;
 using MediaBrowser.Model.Session;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.EntryPoints
+namespace Jellyfin.LiveTv
 {
 {
     public sealed class RecordingNotifier : IServerEntryPoint
     public sealed class RecordingNotifier : IServerEntryPoint
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/RefreshGuideScheduledTask.cs → src/Jellyfin.LiveTv/RefreshGuideScheduledTask.cs

@@ -7,7 +7,7 @@ using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.Tasks;
 using MediaBrowser.Model.Tasks;
 
 
-namespace Emby.Server.Implementations.LiveTv
+namespace Jellyfin.LiveTv
 {
 {
     /// <summary>
     /// <summary>
     /// The "Refresh Guide" scheduled task.
     /// The "Refresh Guide" scheduled task.

+ 1 - 1
Emby.Server.Implementations/IO/StreamHelper.cs → src/Jellyfin.LiveTv/StreamHelper.cs

@@ -7,7 +7,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 
 
-namespace Emby.Server.Implementations.IO
+namespace Jellyfin.LiveTv
 {
 {
     public class StreamHelper : IStreamHelper
     public class StreamHelper : IStreamHelper
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs → src/Jellyfin.LiveTv/TunerHosts/BaseTunerHost.cs

@@ -19,7 +19,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts
+namespace Jellyfin.LiveTv.TunerHosts
 {
 {
     public abstract class BaseTunerHost
     public abstract class BaseTunerHost
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/Channels.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/Channels.cs

@@ -1,6 +1,6 @@
 #nullable disable
 #nullable disable
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     internal class Channels
     internal class Channels
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs

@@ -2,7 +2,7 @@
 
 
 using System;
 using System;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     internal class DiscoverResponse
     internal class DiscoverResponse
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunChannelCommands.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunChannelCommands.cs

@@ -3,7 +3,7 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     public class HdHomerunChannelCommands : IHdHomerunChannelCommands
     public class HdHomerunChannelCommands : IHdHomerunChannelCommands
     {
     {

+ 4 - 4
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -30,7 +30,7 @@ using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.Net;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     public class HdHomerunHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
     public class HdHomerunHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
     {
     {
@@ -143,7 +143,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 if (!throwAllExceptions && ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
                 if (!throwAllExceptions && ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
                 {
                 {
                     const string DefaultValue = "HDHR";
                     const string DefaultValue = "HDHR";
-                    var response = new DiscoverResponse
+                    var discoverResponse = new DiscoverResponse
                     {
                     {
                         ModelNumber = DefaultValue
                         ModelNumber = DefaultValue
                     };
                     };
@@ -152,11 +152,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                         // HDHR4 doesn't have this api
                         // HDHR4 doesn't have this api
                         lock (_modelCache)
                         lock (_modelCache)
                         {
                         {
-                            _modelCache[cacheKey] = response;
+                            _modelCache[cacheKey] = discoverResponse;
                         }
                         }
                     }
                     }
 
 
-                    return response;
+                    return discoverResponse;
                 }
                 }
 
 
                 throw;
                 throw;

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs

@@ -14,7 +14,7 @@ using System.Threading.Tasks;
 using MediaBrowser.Common;
 using MediaBrowser.Common;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     public sealed class HdHomerunManager : IDisposable
     public sealed class HdHomerunManager : IDisposable
     {
     {

+ 2 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs

@@ -1,5 +1,6 @@
 #nullable disable
 #nullable disable
 
 
+#pragma warning disable CA1711
 #pragma warning disable CS1591
 #pragma warning disable CS1591
 
 
 using System;
 using System;
@@ -19,7 +20,7 @@ using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     public class HdHomerunUdpStream : LiveStream, IDirectStreamProvider
     public class HdHomerunUdpStream : LiveStream, IDirectStreamProvider
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/IHdHomerunChannelCommands.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/IHdHomerunChannelCommands.cs

@@ -2,7 +2,7 @@
 
 
 using System.Collections.Generic;
 using System.Collections.Generic;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     public interface IHdHomerunChannelCommands
     public interface IHdHomerunChannelCommands
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs → src/Jellyfin.LiveTv/TunerHosts/HdHomerun/LegacyHdHomerunChannelCommands.cs

@@ -3,7 +3,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
+namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
 {
 {
     public partial class LegacyHdHomerunChannelCommands : IHdHomerunChannelCommands
     public partial class LegacyHdHomerunChannelCommands : IHdHomerunChannelCommands
     {
     {

+ 2 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs → src/Jellyfin.LiveTv/TunerHosts/LiveStream.cs

@@ -1,5 +1,6 @@
 #nullable disable
 #nullable disable
 
 
+#pragma warning disable CA1711
 #pragma warning disable CS1591
 #pragma warning disable CS1591
 
 
 using System;
 using System;
@@ -14,7 +15,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts
+namespace Jellyfin.LiveTv.TunerHosts
 {
 {
     public class LiveStream : ILiveStream
     public class LiveStream : ILiveStream
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs → src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs

@@ -24,7 +24,7 @@ using MediaBrowser.Model.MediaInfo;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 using Microsoft.Net.Http.Headers;
 using Microsoft.Net.Http.Headers;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts
+namespace Jellyfin.LiveTv.TunerHosts
 {
 {
     public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
     public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
     {
     {

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs → src/Jellyfin.LiveTv/TunerHosts/M3uParser.cs

@@ -18,7 +18,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts
+namespace Jellyfin.LiveTv.TunerHosts
 {
 {
     public partial class M3uParser
     public partial class M3uParser
     {
     {

+ 2 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs → src/Jellyfin.LiveTv/TunerHosts/SharedHttpStream.cs

@@ -1,3 +1,4 @@
+#pragma warning disable CA1711
 #pragma warning disable CS1591
 #pragma warning disable CS1591
 
 
 using System;
 using System;
@@ -16,7 +17,7 @@ using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
-namespace Emby.Server.Implementations.LiveTv.TunerHosts
+namespace Jellyfin.LiveTv.TunerHosts
 {
 {
     public class SharedHttpStream : LiveStream, IDirectStreamProvider
     public class SharedHttpStream : LiveStream, IDirectStreamProvider
     {
     {

+ 2 - 2
tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs → tests/Jellyfin.LiveTv.Tests/HdHomerunHostTests.cs

@@ -6,13 +6,13 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using AutoFixture;
 using AutoFixture;
 using AutoFixture.AutoMoq;
 using AutoFixture.AutoMoq;
-using Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun;
+using Jellyfin.LiveTv.TunerHosts.HdHomerun;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Moq;
 using Moq;
 using Moq.Protected;
 using Moq.Protected;
 using Xunit;
 using Xunit;
 
 
-namespace Jellyfin.Server.Implementations.Tests.LiveTv
+namespace Jellyfin.LiveTv.Tests
 {
 {
     public class HdHomerunHostTests
     public class HdHomerunHostTests
     {
     {

+ 2 - 2
tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs → tests/Jellyfin.LiveTv.Tests/HdHomerunManagerTests.cs

@@ -1,9 +1,9 @@
 using System;
 using System;
 using System.Text;
 using System.Text;
-using Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun;
+using Jellyfin.LiveTv.TunerHosts.HdHomerun;
 using Xunit;
 using Xunit;
 
 
-namespace Jellyfin.Server.Implementations.Tests.LiveTv
+namespace Jellyfin.LiveTv.Tests
 {
 {
     public class HdHomerunManagerTests
     public class HdHomerunManagerTests
     {
     {

+ 29 - 0
tests/Jellyfin.LiveTv.Tests/Jellyfin.LiveTv.Tests.csproj

@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <None Include="Test Data\**\*.*">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="AutoFixture" />
+    <PackageReference Include="AutoFixture.AutoMoq" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" />
+    <PackageReference Include="Moq" />
+    <PackageReference Include="xunit" />
+    <PackageReference Include="xunit.runner.visualstudio">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+    <PackageReference Include="Xunit.SkippableFact" />
+    <PackageReference Include="coverlet.collector" />
+  </ItemGroup>
+  
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\Jellyfin.LiveTv\Jellyfin.LiveTv.csproj" />
+  </ItemGroup>
+</Project>

+ 2 - 2
tests/Jellyfin.Server.Implementations.Tests/LiveTv/Listings/XmlTvListingsProviderTests.cs → tests/Jellyfin.LiveTv.Tests/Listings/XmlTvListingsProviderTests.cs

@@ -6,13 +6,13 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using AutoFixture;
 using AutoFixture;
 using AutoFixture.AutoMoq;
 using AutoFixture.AutoMoq;
-using Emby.Server.Implementations.LiveTv.Listings;
+using Jellyfin.LiveTv.Listings;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.LiveTv;
 using Moq;
 using Moq;
 using Moq.Protected;
 using Moq.Protected;
 using Xunit;
 using Xunit;
 
 
-namespace Jellyfin.Server.Implementations.Tests.LiveTv.Listings;
+namespace Jellyfin.LiveTv.Tests.Listings;
 
 
 public class XmlTvListingsProviderTests
 public class XmlTvListingsProviderTests
 {
 {

+ 2 - 2
tests/Jellyfin.Server.Implementations.Tests/LiveTv/RecordingHelperTests.cs → tests/Jellyfin.LiveTv.Tests/RecordingHelperTests.cs

@@ -1,9 +1,9 @@
 using System;
 using System;
-using Emby.Server.Implementations.LiveTv.EmbyTV;
+using Jellyfin.LiveTv.EmbyTV;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
 using Xunit;
 using Xunit;
 
 
-namespace Jellyfin.Server.Implementations.Tests.LiveTv
+namespace Jellyfin.LiveTv.Tests
 {
 {
     public static class RecordingHelperTests
     public static class RecordingHelperTests
     {
     {

+ 2 - 2
tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs → tests/Jellyfin.LiveTv.Tests/SchedulesDirect/SchedulesDirectDeserializeTests.cs

@@ -2,11 +2,11 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;
 using System.Text.Json;
 using System.Text.Json;
-using Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos;
 using Jellyfin.Extensions.Json;
 using Jellyfin.Extensions.Json;
+using Jellyfin.LiveTv.Listings.SchedulesDirectDtos;
 using Xunit;
 using Xunit;
 
 
-namespace Jellyfin.Server.Implementations.Tests.LiveTv.SchedulesDirect
+namespace Jellyfin.LiveTv.Tests.SchedulesDirect
 {
 {
     public class SchedulesDirectDeserializeTests
     public class SchedulesDirectDeserializeTests
     {
     {

+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/discover.json → tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/discover.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/lineup.json → tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/lineup.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/discover.json → tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/discover.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/lineup.json → tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/lineup.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml → tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml → tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/headends_response.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/headends_response.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineup_response.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineup_response.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineups_response.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineups_response.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/metadata_programs_response.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/metadata_programs_response.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/programs_response.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/programs_response.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_request.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_request.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_response.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_response.json


+ 0 - 0
tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_live_response.json → tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_live_response.json


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác