PlaylistItemsProvider.cs 5.0 KB

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