PlaylistItemsProvider.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #pragma warning disable CS1591
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using MediaBrowser.Controller.Entities;
  9. using MediaBrowser.Controller.Library;
  10. using MediaBrowser.Controller.Playlists;
  11. using MediaBrowser.Controller.Providers;
  12. using MediaBrowser.Model.IO;
  13. using Microsoft.Extensions.Logging;
  14. using PlaylistsNET.Content;
  15. namespace MediaBrowser.Providers.Playlists
  16. {
  17. public class PlaylistItemsProvider : ICustomMetadataProvider<Playlist>,
  18. IHasOrder,
  19. IForcedProvider,
  20. IPreRefreshProvider,
  21. IHasItemChangeMonitor
  22. {
  23. private readonly ILogger<PlaylistItemsProvider> _logger;
  24. private IFileSystem _fileSystem;
  25. public PlaylistItemsProvider(IFileSystem fileSystem, ILogger<PlaylistItemsProvider> logger)
  26. {
  27. _fileSystem = fileSystem;
  28. _logger = logger;
  29. }
  30. public string Name => "Playlist Reader";
  31. public Task<ItemUpdateType> FetchAsync(Playlist item, MetadataRefreshOptions options, CancellationToken cancellationToken)
  32. {
  33. var path = item.Path;
  34. if (!Playlist.IsPlaylistFile(path))
  35. {
  36. return Task.FromResult(ItemUpdateType.None);
  37. }
  38. var extension = Path.GetExtension(path);
  39. if (!Playlist.SupportedExtensions.Contains(extension ?? string.Empty, StringComparer.OrdinalIgnoreCase))
  40. {
  41. return Task.FromResult(ItemUpdateType.None);
  42. }
  43. using (var stream = File.OpenRead(path))
  44. {
  45. var items = GetItems(stream, extension).ToArray();
  46. item.LinkedChildren = items;
  47. }
  48. return Task.FromResult(ItemUpdateType.None);
  49. }
  50. private IEnumerable<LinkedChild> GetItems(Stream stream, string extension)
  51. {
  52. if (string.Equals(".wpl", extension, StringComparison.OrdinalIgnoreCase))
  53. {
  54. return GetWplItems(stream);
  55. }
  56. if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase))
  57. {
  58. return GetZplItems(stream);
  59. }
  60. if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase))
  61. {
  62. return GetM3uItems(stream);
  63. }
  64. if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase))
  65. {
  66. return GetM3u8Items(stream);
  67. }
  68. if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase))
  69. {
  70. return GetPlsItems(stream);
  71. }
  72. return new List<LinkedChild>();
  73. }
  74. private IEnumerable<LinkedChild> GetPlsItems(Stream stream)
  75. {
  76. var content = new PlsContent();
  77. var playlist = content.GetFromStream(stream);
  78. return playlist.PlaylistEntries.Select(i => new LinkedChild
  79. {
  80. Path = i.Path,
  81. Type = LinkedChildType.Manual
  82. });
  83. }
  84. private IEnumerable<LinkedChild> GetM3u8Items(Stream stream)
  85. {
  86. var content = new M3uContent();
  87. var playlist = content.GetFromStream(stream);
  88. return playlist.PlaylistEntries.Select(i => new LinkedChild
  89. {
  90. Path = i.Path,
  91. Type = LinkedChildType.Manual
  92. });
  93. }
  94. private IEnumerable<LinkedChild> GetM3uItems(Stream stream)
  95. {
  96. var content = new M3uContent();
  97. var playlist = content.GetFromStream(stream);
  98. return playlist.PlaylistEntries.Select(i => new LinkedChild
  99. {
  100. Path = i.Path,
  101. Type = LinkedChildType.Manual
  102. });
  103. }
  104. private IEnumerable<LinkedChild> GetZplItems(Stream stream)
  105. {
  106. var content = new ZplContent();
  107. var playlist = content.GetFromStream(stream);
  108. return playlist.PlaylistEntries.Select(i => new LinkedChild
  109. {
  110. Path = i.Path,
  111. Type = LinkedChildType.Manual
  112. });
  113. }
  114. private IEnumerable<LinkedChild> GetWplItems(Stream stream)
  115. {
  116. var content = new WplContent();
  117. var playlist = content.GetFromStream(stream);
  118. return playlist.PlaylistEntries.Select(i => new LinkedChild
  119. {
  120. Path = i.Path,
  121. Type = LinkedChildType.Manual
  122. });
  123. }
  124. public bool HasChanged(BaseItem item, IDirectoryService directoryService)
  125. {
  126. var path = item.Path;
  127. if (!string.IsNullOrWhiteSpace(path) && item.IsFileProtocol)
  128. {
  129. var file = directoryService.GetFile(path);
  130. if (file != null && file.LastWriteTimeUtc != item.DateModified)
  131. {
  132. _logger.LogDebug("Refreshing {0} due to date modified timestamp change.", path);
  133. return true;
  134. }
  135. }
  136. return false;
  137. }
  138. // Run last
  139. public int Order => 100;
  140. }
  141. }