VLCNetworkServerBrowserVLCMedia.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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. #import "VLC-Swift.h"
  15. @interface VLCNetworkServerBrowserVLCMedia () <VLCMediaListDelegate, VLCMediaDelegate>
  16. {
  17. VLCDialogProvider *_dialogProvider;
  18. VLCCustomDialogRendererHandler *_customDialogHandler;
  19. }
  20. @property (nonatomic) VLCMedia *rootMedia;
  21. @property (nonatomic) VLCMediaList *mediaList;
  22. @property (nonatomic) VLCMediaList *mediaListUnfiltered;
  23. @property (nonatomic) NSMutableArray<id<VLCNetworkServerBrowserItem>> *mutableItems;
  24. @property (nonatomic, readonly) NSDictionary *mediaOptions;
  25. @end
  26. @implementation VLCNetworkServerBrowserVLCMedia
  27. @synthesize delegate = _delegate;
  28. - (instancetype)initWithMedia:(VLCMedia *)media options:(nonnull NSDictionary *)mediaOptions
  29. {
  30. self = [super init];
  31. if (self) {
  32. _mutableItems = [[NSMutableArray alloc] init];
  33. _mediaList = [[VLCMediaList alloc] init];
  34. _rootMedia = media;
  35. _rootMedia.delegate = self;
  36. // Set timeout to 0 in order to avoid getting interrupted in dialogs for timeout reasons
  37. [media parseWithOptions:VLCMediaParseNetwork|VLCMediaDoInteract timeout:0];
  38. _mediaListUnfiltered = [_rootMedia subitems];
  39. _mediaListUnfiltered.delegate = self;
  40. NSMutableDictionary *mediaOptionsNoFilter = [mediaOptions mutableCopy];
  41. [mediaOptionsNoFilter setObject:@" " forKey:@":ignore-filetypes"];
  42. _mediaOptions = [mediaOptionsNoFilter copy];
  43. [self _addMediaListRootItemsToList];
  44. _dialogProvider = [[VLCDialogProvider alloc] initWithLibrary:[VLCLibrary sharedLibrary] customUI:YES];
  45. _customDialogHandler = [[VLCCustomDialogRendererHandler alloc]
  46. initWithDialogProvider:_dialogProvider];
  47. __weak typeof(self) weakSelf = self;
  48. _customDialogHandler.completionHandler = ^(VLCCustomDialogRendererHandlerCompletionType status)
  49. {
  50. [weakSelf customDialogCompletionHandlerWithStatus:status];
  51. };
  52. _dialogProvider.customRenderer = _customDialogHandler;
  53. }
  54. return self;
  55. }
  56. - (void)customDialogCompletionHandlerWithStatus:(VLCCustomDialogRendererHandlerCompletionType)status
  57. {
  58. switch (status) {
  59. case VLCCustomDialogRendererHandlerCompletionTypeError:
  60. // Disable for now, it seems that vlc is sending us a bit too much error callbacks
  61. // [self.delegate networkServerBrowserShouldPopView:self];
  62. break;
  63. default:
  64. break;
  65. }
  66. }
  67. - (BOOL)shouldFilterMedia:(VLCMedia *)media
  68. {
  69. NSString *absoluteString = media.url.absoluteString;
  70. return ![absoluteString isSupportedAudioMediaFormat] && ![absoluteString isSupportedMediaFormat] && ![absoluteString isSupportedPlaylistFormat] && media.mediaType != VLCMediaTypeDirectory;
  71. }
  72. - (void)_addMediaListRootItemsToList
  73. {
  74. VLCMediaList *rootItems = _rootMedia.subitems;
  75. [rootItems lock];
  76. NSUInteger count = rootItems.count;
  77. for (NSUInteger i = 0; i < count; i++) {
  78. VLCMedia *media = [rootItems mediaAtIndex:i];
  79. if (![self shouldFilterMedia:media]) {
  80. NSInteger mediaIndex = self.mutableItems.count;
  81. [self.mediaList insertMedia:media atIndex:mediaIndex];
  82. [self.mutableItems insertObject:[[VLCNetworkServerBrowserItemVLCMedia alloc] initWithMedia:media options:self.mediaOptions] atIndex:mediaIndex];
  83. }
  84. }
  85. [rootItems unlock];
  86. }
  87. - (void)update {
  88. int ret = [self.rootMedia parseWithOptions:VLCMediaParseNetwork];
  89. if (ret == -1) {
  90. [self.delegate networkServerBrowserDidUpdate:self];
  91. }
  92. }
  93. - (NSString *)title {
  94. return [self.rootMedia metadataForKey:VLCMetaInformationTitle];
  95. }
  96. - (NSArray<id<VLCNetworkServerBrowserItem>> *)items {
  97. return self.mutableItems.copy;
  98. }
  99. #pragma mark - media list delegate
  100. - (void)mediaList:(VLCMediaList *)aMediaList mediaAdded:(VLCMedia *)media atIndex:(NSUInteger)index
  101. {
  102. [media addOptions:self.mediaOptions];
  103. if (![self shouldFilterMedia:media]) {
  104. NSInteger mediaIndex = self.mutableItems.count;
  105. [self.mediaList insertMedia:media atIndex:mediaIndex];
  106. [self.mutableItems insertObject:[[VLCNetworkServerBrowserItemVLCMedia alloc] initWithMedia:media options:self.mediaOptions] atIndex:mediaIndex];
  107. }
  108. [self.delegate networkServerBrowserDidUpdate:self];
  109. }
  110. - (void)mediaList:(VLCMediaList *)aMediaList mediaRemovedAtIndex:(NSUInteger)index
  111. {
  112. VLCMedia *media = [self.mediaListUnfiltered mediaAtIndex:index];
  113. NSInteger mediaIndex = [self.mediaList indexOfMedia:media];
  114. [self.mediaList removeMediaAtIndex:mediaIndex];
  115. [self.mutableItems removeObjectAtIndex:mediaIndex];
  116. [self.delegate networkServerBrowserDidUpdate:self];
  117. }
  118. #pragma mark - media delegate
  119. - (void)mediaDidFinishParsing:(VLCMedia *)aMedia
  120. {
  121. if ([aMedia parsedStatus] != VLCMediaParsedStatusDone) {
  122. [self.delegate networkServerBrowserShouldPopView:self];
  123. } else {
  124. [self.delegate networkServerBrowserDidUpdate:self];
  125. }
  126. }
  127. @end
  128. @interface VLCNetworkServerBrowserItemVLCMedia () <VLCMediaDelegate>
  129. @property (nonatomic, readonly) NSDictionary *mediaOptions;
  130. @end
  131. @implementation VLCNetworkServerBrowserItemVLCMedia
  132. @synthesize name = _name, container = _container, fileSizeBytes = _fileSizeBytes, URL = _URL, media = _media, downloadable = _downloadable;
  133. - (instancetype)initWithMedia:(VLCMedia *)media options:(NSDictionary *)mediaOptions;
  134. {
  135. self = [super init];
  136. if (self) {
  137. _media = media;
  138. _container = media.mediaType == VLCMediaTypeDirectory;
  139. NSString *title = [media metadataForKey:VLCMetaInformationTitle];
  140. if (!title) {
  141. title = [media.url.lastPathComponent stringByRemovingPercentEncoding];
  142. }
  143. if (!title) {
  144. title = [media.url.absoluteString stringByRemovingPercentEncoding];
  145. }
  146. _name = title;
  147. _URL = media.url;
  148. _mediaOptions = [mediaOptions copy];
  149. _downloadable = NO;
  150. }
  151. return self;
  152. }
  153. - (id<VLCNetworkServerBrowser>)containerBrowser {
  154. return [[VLCNetworkServerBrowserVLCMedia alloc] initWithMedia:self.media options:self.mediaOptions];
  155. }
  156. @end