VLCNetworkServerBrowserVLCMedia.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*****************************************************************************
  2. * VLCNetworkServerBrowserVLCMedia.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2015 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Tobias Conradi <videolan # tobias-conradi.de>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. #import "VLCNetworkServerBrowserVLCMedia.h"
  13. #import "NSString+SupportedMedia.h"
  14. @interface VLCNetworkServerBrowserVLCMedia () <VLCMediaListDelegate, VLCMediaDelegate>
  15. {
  16. BOOL _needsNotifyDelegate;
  17. }
  18. @property (nonatomic) VLCMedia *rootMedia;
  19. @property (nonatomic) VLCMediaList *mediaList;
  20. @property (nonatomic) VLCMediaList *mediaListUnfiltered;
  21. @property (nonatomic) NSMutableArray<id<VLCNetworkServerBrowserItem>> *mutableItems;
  22. @property (nonatomic, readonly) NSDictionary *mediaOptions;
  23. @end
  24. @implementation VLCNetworkServerBrowserVLCMedia
  25. @synthesize delegate = _delegate;
  26. - (instancetype)initWithMedia:(VLCMedia *)media options:(nonnull NSDictionary *)mediaOptions
  27. {
  28. self = [super init];
  29. if (self) {
  30. _mutableItems = [[NSMutableArray alloc] init];
  31. _mediaList = [[VLCMediaList alloc] init];
  32. _rootMedia = media;
  33. _rootMedia.delegate = self;
  34. [media parseWithOptions:VLCMediaParseNetwork];
  35. _mediaListUnfiltered = [_rootMedia subitems];
  36. _mediaListUnfiltered.delegate = self;
  37. NSMutableDictionary *mediaOptionsNoFilter = [mediaOptions mutableCopy];
  38. [mediaOptionsNoFilter setObject:@" " forKey:@":ignore-filetypes"];
  39. _mediaOptions = [mediaOptionsNoFilter copy];
  40. [self _addMediaListRootItemsToList];
  41. }
  42. return self;
  43. }
  44. - (BOOL)shouldFilterMedia:(VLCMedia *)media
  45. {
  46. return ![media.url.absoluteString isSupportedAudioMediaFormat] && ![media.url.absoluteString isSupportedMediaFormat] && media.mediaType != VLCMediaTypeDirectory;
  47. }
  48. - (void)_addMediaListRootItemsToList
  49. {
  50. VLCMediaList *rootItems = _rootMedia.subitems;
  51. [rootItems lock];
  52. NSUInteger count = rootItems.count;
  53. for (NSUInteger i = 0; i < count; i++) {
  54. VLCMedia *media = [rootItems mediaAtIndex:i];
  55. VLCMedia *newMedia = [VLCMedia mediaWithURL:media.url];
  56. newMedia.delegate = self;
  57. [newMedia addOptions:self.mediaOptions];
  58. [newMedia parseWithOptions:VLCMediaParseNetwork];
  59. if (![self shouldFilterMedia:media]) {
  60. NSInteger mediaIndex = self.mutableItems.count;
  61. [self.mediaList insertMedia:media atIndex:mediaIndex];
  62. [self.mutableItems insertObject:[[VLCNetworkServerBrowserItemVLCMedia alloc] initWithMedia:media options:self.mediaOptions] atIndex:mediaIndex];
  63. }
  64. }
  65. [rootItems unlock];
  66. }
  67. - (void)update {
  68. int ret = [self.rootMedia parseWithOptions:VLCMediaParseNetwork];
  69. if (ret == -1) {
  70. [self.delegate networkServerBrowserDidUpdate:self];
  71. }
  72. }
  73. - (NSString *)title {
  74. if (self.rootMedia.isParsed)
  75. return [self.rootMedia metadataForKey:VLCMetaInformationTitle];
  76. return @"";
  77. }
  78. - (NSArray<id<VLCNetworkServerBrowserItem>> *)items {
  79. return self.mutableItems.copy;
  80. }
  81. #pragma mark - media list delegate
  82. - (void)mediaList:(VLCMediaList *)aMediaList mediaAdded:(VLCMedia *)media atIndex:(NSInteger)index
  83. {
  84. [media addOptions:self.mediaOptions];
  85. if (![self shouldFilterMedia:media]) {
  86. NSInteger mediaIndex = self.mutableItems.count;
  87. [self.mediaList insertMedia:media atIndex:mediaIndex];
  88. [self.mutableItems insertObject:[[VLCNetworkServerBrowserItemVLCMedia alloc] initWithMedia:media options:self.mediaOptions] atIndex:mediaIndex];
  89. }
  90. [self.delegate networkServerBrowserDidUpdate:self];
  91. }
  92. - (void)mediaList:(VLCMediaList *)aMediaList mediaRemovedAtIndex:(NSInteger)index
  93. {
  94. VLCMedia *media = [self.mediaListUnfiltered mediaAtIndex:index];
  95. NSInteger mediaIndex = [self.mediaList indexOfMedia:media];
  96. [self.mediaList removeMediaAtIndex:mediaIndex];
  97. [self.mutableItems removeObjectAtIndex:mediaIndex];
  98. [self.delegate networkServerBrowserDidUpdate:self];
  99. }
  100. #pragma mark - media delegate
  101. - (void)mediaDidFinishParsing:(VLCMedia *)aMedia
  102. {
  103. [self setNeedsNotifyDelegateForDidUpdate];
  104. }
  105. - (void)mediaMetaDataDidChange:(VLCMedia *)aMedia
  106. {
  107. [self setNeedsNotifyDelegateForDidUpdate];
  108. }
  109. - (void)setNeedsNotifyDelegateForDidUpdate
  110. {
  111. if (_needsNotifyDelegate) {
  112. return;
  113. }
  114. _needsNotifyDelegate = YES;
  115. double amountOfSeconds = 0.1;
  116. dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(amountOfSeconds * NSEC_PER_SEC));
  117. dispatch_after(delayTime, dispatch_get_main_queue(), ^{
  118. _needsNotifyDelegate = NO;
  119. [self.delegate networkServerBrowserDidUpdate:self];
  120. });
  121. }
  122. @end
  123. @interface VLCNetworkServerBrowserItemVLCMedia () <VLCMediaDelegate>
  124. @property (nonatomic, readonly) NSDictionary *mediaOptions;
  125. @end
  126. @implementation VLCNetworkServerBrowserItemVLCMedia
  127. @synthesize name = _name, container = _container, fileSizeBytes = _fileSizeBytes, URL = _URL, media = _media, downloadable = _downloadable;
  128. - (instancetype)initWithMedia:(VLCMedia *)media options:(NSDictionary *)mediaOptions;
  129. {
  130. self = [super init];
  131. if (self) {
  132. _media = media;
  133. _container = media.mediaType == VLCMediaTypeDirectory;
  134. NSString *title;
  135. if (media.isParsed) {
  136. title = [media metadataForKey:VLCMetaInformationTitle];
  137. }
  138. if (!title) {
  139. title = media.url.lastPathComponent;
  140. }
  141. if (!title) {
  142. title = media.url.absoluteString;
  143. }
  144. _name = title;
  145. _URL = media.url;
  146. _mediaOptions = [mediaOptions copy];
  147. _downloadable = NO;
  148. }
  149. return self;
  150. }
  151. - (id<VLCNetworkServerBrowser>)containerBrowser {
  152. return [[VLCNetworkServerBrowserVLCMedia alloc] initWithMedia:self.media options:self.mediaOptions];
  153. }
  154. @end