VLCNetworkServerBrowserVLCMedia.m 5.74 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*****************************************************************************
 * VLCNetworkServerBrowserVLCMedia.m
 * VLC for iOS
 *****************************************************************************
 * Copyright (c) 2015 VideoLAN. All rights reserved.
 * $Id$
 *
 * Authors: Tobias Conradi <videolan # tobias-conradi.de>
 *
 * Refer to the COPYING file of the official project for license.
 *****************************************************************************/

#import "VLCNetworkServerBrowserVLCMedia.h"
14
#import "NSString+SupportedMedia.h"
15

16
@interface VLCNetworkServerBrowserVLCMedia () <VLCMediaListDelegate, VLCMediaDelegate>
17 18 19 20
{
    BOOL _needsNotifyDelegate;
}

21 22
@property (nonatomic) VLCMedia *rootMedia;
@property (nonatomic) VLCMediaList *mediaList;
23
@property (nonatomic) VLCMediaList *mediaListUnfiltered;
24
@property (nonatomic) NSMutableArray<id<VLCNetworkServerBrowserItem>> *mutableItems;
25 26
@property (nonatomic, readonly) NSDictionary *mediaOptions;

27 28 29 30
@end
@implementation VLCNetworkServerBrowserVLCMedia
@synthesize delegate = _delegate;

31
- (instancetype)initWithMedia:(VLCMedia *)media options:(nonnull NSDictionary *)mediaOptions
32 33 34 35
{
    self = [super init];
    if (self) {
        _mutableItems = [[NSMutableArray alloc] init];
36
        _mediaList = [[VLCMediaList alloc] init];
37
        _rootMedia = media;
38
        _rootMedia.delegate = self;
39
        [media parseWithOptions:VLCMediaParseNetwork];
40 41 42 43 44
        _mediaListUnfiltered = [_rootMedia subitems];
        _mediaListUnfiltered.delegate = self;
        NSMutableDictionary *mediaOptionsNoFilter = [mediaOptions mutableCopy];
        [mediaOptionsNoFilter setObject:@" " forKey:@":ignore-filetypes"];
        _mediaOptions = [mediaOptionsNoFilter copy];
45
        [self _addMediaListRootItemsToList];
46 47 48
    }
    return self;
}
49

50 51
- (BOOL)shouldFilterMedia:(VLCMedia *)media
{
52 53
    NSString *absoluteString = media.url.absoluteString;
    return ![absoluteString isSupportedAudioMediaFormat] && ![absoluteString isSupportedMediaFormat] && ![absoluteString isSupportedPlaylistFormat] && media.mediaType != VLCMediaTypeDirectory;
54 55
}

56 57 58 59 60 61 62
- (void)_addMediaListRootItemsToList
{
    VLCMediaList *rootItems = _rootMedia.subitems;
    [rootItems lock];
    NSUInteger count = rootItems.count;
    for (NSUInteger i = 0; i < count; i++) {
        VLCMedia *media = [rootItems mediaAtIndex:i];
63 64 65 66 67
        if (![self shouldFilterMedia:media]) {
            NSInteger mediaIndex = self.mutableItems.count;
            [self.mediaList insertMedia:media atIndex:mediaIndex];
            [self.mutableItems insertObject:[[VLCNetworkServerBrowserItemVLCMedia alloc] initWithMedia:media options:self.mediaOptions] atIndex:mediaIndex];
        }
68 69 70 71
    }
    [rootItems unlock];
}

72
- (void)update {
73
    int ret = [self.rootMedia parseWithOptions:VLCMediaParseNetwork];
74 75 76
    if (ret == -1) {
        [self.delegate networkServerBrowserDidUpdate:self];
    }
77 78 79
}

- (NSString *)title {
80
    return [self.rootMedia metadataForKey:VLCMetaInformationTitle];
81 82 83 84 85 86 87 88
}

- (NSArray<id<VLCNetworkServerBrowserItem>> *)items {
    return self.mutableItems.copy;
}

#pragma mark - media list delegate

89
- (void)mediaList:(VLCMediaList *)aMediaList mediaAdded:(VLCMedia *)media atIndex:(NSUInteger)index
90
{
91
    [media addOptions:self.mediaOptions];
92 93 94 95 96 97
    if (![self shouldFilterMedia:media]) {
        NSInteger mediaIndex = self.mutableItems.count;
        [self.mediaList insertMedia:media atIndex:mediaIndex];
        [self.mutableItems insertObject:[[VLCNetworkServerBrowserItemVLCMedia alloc] initWithMedia:media options:self.mediaOptions] atIndex:mediaIndex];
    }

98 99 100
    [self.delegate networkServerBrowserDidUpdate:self];
}

101
- (void)mediaList:(VLCMediaList *)aMediaList mediaRemovedAtIndex:(NSUInteger)index
102
{
103 104 105 106
    VLCMedia *media = [self.mediaListUnfiltered mediaAtIndex:index];
    NSInteger mediaIndex = [self.mediaList indexOfMedia:media];
    [self.mediaList removeMediaAtIndex:mediaIndex];
    [self.mutableItems removeObjectAtIndex:mediaIndex];
107 108 109
    [self.delegate networkServerBrowserDidUpdate:self];
}

110 111 112 113
#pragma mark - media delegate

- (void)mediaDidFinishParsing:(VLCMedia *)aMedia
{
114
    [self setNeedsNotifyDelegateForDidUpdate];
115 116 117
}
- (void)mediaMetaDataDidChange:(VLCMedia *)aMedia
{
118 119 120 121 122 123 124 125 126 127 128 129 130
    [self setNeedsNotifyDelegateForDidUpdate];
}

- (void)setNeedsNotifyDelegateForDidUpdate
{
    if (_needsNotifyDelegate) {
        return;
    }
    _needsNotifyDelegate = YES;

    double amountOfSeconds = 0.1;
    dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(amountOfSeconds * NSEC_PER_SEC));
    dispatch_after(delayTime, dispatch_get_main_queue(), ^{
131
        self->_needsNotifyDelegate = NO;
132 133
        [self.delegate networkServerBrowserDidUpdate:self];
    });
134 135 136
}

@end
137

138
@interface VLCNetworkServerBrowserItemVLCMedia () <VLCMediaDelegate>
139 140
@property (nonatomic, readonly) NSDictionary *mediaOptions;

141 142
@end
@implementation VLCNetworkServerBrowserItemVLCMedia
143
@synthesize name = _name, container = _container, fileSizeBytes = _fileSizeBytes, URL = _URL, media = _media, downloadable = _downloadable;
144

145
- (instancetype)initWithMedia:(VLCMedia *)media options:(NSDictionary *)mediaOptions;
146 147 148 149 150
{
    self = [super init];
    if (self) {
        _media = media;
        _container = media.mediaType == VLCMediaTypeDirectory;
151
        NSString *title = [media metadataForKey:VLCMetaInformationTitle];
152
        if (!title) {
153
            title = [media.url.lastPathComponent stringByRemovingPercentEncoding];
154 155
        }
        if (!title) {
156
            title = [media.url.absoluteString stringByRemovingPercentEncoding];
157 158 159
        }
        _name = title;
        _URL = media.url;
160
        _mediaOptions = [mediaOptions copy];
161
        _downloadable = NO;
162 163 164 165 166
    }
    return self;
}

- (id<VLCNetworkServerBrowser>)containerBrowser {
167
    return [[VLCNetworkServerBrowserVLCMedia alloc] initWithMedia:self.media options:self.mediaOptions];
168 169 170
}

@end