123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /*****************************************************************************
- * VLCNetworkServerBrowserPlex.m
- * VLC for iOS
- *****************************************************************************
- * Copyright (c) 2015-2018 VideoLAN. All rights reserved.
- * $Id$
- *
- * Authors: Tobias Conradi <videolan # tobias-conradi.de>
- * Pierre Sagaspe <pierre.sagaspe # me.com>
- *
- * Refer to the COPYING file of the official project for license.
- *****************************************************************************/
- #import "VLCNetworkServerBrowserPlex.h"
- #import "VLCPlexParser.h"
- #import "VLCPlexWebAPI.h"
- @interface VLCNetworkServerBrowserPlex ()
- @property (nonatomic, readonly) NSString *addressOrName;
- @property (nonatomic, readonly) NSUInteger port;
- @property (nonatomic, readwrite) NSString *title;
- @property (nonatomic, readonly) NSString *plexServerAddress;
- @property (nonatomic, readonly) NSNumber *plexServerPort;
- @property (nonatomic, readonly) NSString *plexServerPath;
- @property (nonatomic) NSString *plexAuthentification;
- @property (nonatomic, readonly) VLCPlexParser *plexParser;
- @property (nonatomic, readonly) VLCPlexWebAPI *plexWebAPI;
- @property (nonatomic, readonly) NSOperationQueue *plexQueue;
- @property (nonatomic, readwrite) NSArray<id<VLCNetworkServerBrowserItem>> *items;
- @end
- @implementation VLCNetworkServerBrowserPlex
- @synthesize title = _title, delegate = _delegate, items = _items, mediaList = _mediaList;
- - (instancetype)initWithLogin:(VLCNetworkServerLoginInformation *)login
- {
- return [self initWithName:login.address
- host:login.address
- portNumber:login.port
- path:@""
- authentificication:@""];
- }
- - (instancetype)initWithName:(NSString *)name host:(NSString *)addressOrName portNumber:(NSNumber *)portNumber path:(NSString *)path authentificication:(NSString *)auth
- {
- self = [super init];
- if (self) {
- _title = name;
- _plexServerAddress = addressOrName;
- _plexServerPort = portNumber.intValue > 0 ? portNumber : @(32400);
- _plexServerPath = path;
- _plexAuthentification = auth;
- _plexParser = [[VLCPlexParser alloc] init];
- _plexWebAPI = [[VLCPlexWebAPI alloc] init];
- _plexQueue = [[NSOperationQueue alloc] init];
- _plexQueue.maxConcurrentOperationCount = 1;
- _plexQueue.name = @"org.videolan.vlc-ios.plex.update";
- _items = [NSArray new];
- }
- return self;
- }
- - (instancetype)initWithName:(NSString *)name url:(NSURL *)url auth:(NSString *)auth {
- return [self initWithName:name host:url.host portNumber:url.port path:url.path authentificication:auth];
- }
- - (void)update {
- [self.plexQueue addOperationWithBlock:^{
- [self loadContents];
- }];
- }
- - (void)loadContents
- {
- NSError *error = nil;
- NSArray *dicts = [self.plexParser PlexMediaServerParser:self.plexServerAddress port:self.plexServerPort navigationPath:self.plexServerPath authentification:self.plexAuthentification error:&error];
- if (error) {
- [[NSOperationQueue mainQueue] addOperationWithBlock:^{
- [self.delegate networkServerBrowser:self requestDidFailWithError:error];
- }];
- return;
- }
- NSDictionary *firstObject = [dicts firstObject];
- NSString *newAuth = firstObject[@"authentification"] ?: @"";
- NSURLComponents *components = [[NSURLComponents alloc] init];
- components.scheme = @"http";
- components.host = self.plexServerAddress;
- components.port = self.plexServerPort;
- components.path = self.plexServerPath;
- NSURL *url = components.URL;
- NSMutableArray *newItems = [NSMutableArray new];
- for (NSDictionary *dict in dicts) {
- VLCNetworkServerBrowserItemPlex *item = [[VLCNetworkServerBrowserItemPlex alloc] initWithDictionary:dict currentURL:url authentificication:newAuth];
- /* warning: we make a http request per item and if the library is big or a weak network, it can slow down the process. */
- if (item.URLcontainer) {
- NSArray *dictItem = [self.plexParser PlexMediaServerParser:self.plexServerAddress port:self.plexServerPort navigationPath:item.URLcontainer.path authentification:self.plexAuthentification error:&error];
- for (NSDictionary *dictx in dictItem) {
- item = [[VLCNetworkServerBrowserItemPlex alloc] initWithDictionary:dictx currentURL:url authentificication:newAuth];
- [newItems addObject:item];
- }
- } else {
- [newItems addObject:item];
- }
- }
- NSString *titleValue = firstObject[@"libTitle"];
- if (titleValue.length) {
- self.title = titleValue;
- }
- self.plexAuthentification = newAuth;
- @synchronized(_items) {
- _items = [newItems copy];
- }
- _mediaList = [self buildMediaList];
- [[NSOperationQueue mainQueue] addOperationWithBlock:^{
- [self.delegate networkServerBrowserDidUpdate:self];
- }];
- }
- - (VLCMediaList *)buildMediaList
- {
- NSMutableArray *mediaArray;
- @synchronized(_items) {
- mediaArray = [NSMutableArray new];
- for (id<VLCNetworkServerBrowserItem> browseritem in _items) {
- VLCMedia *media = [browseritem media];
- if (media)
- [mediaArray addObject:media];
- }
- }
- VLCMediaList *mediaList = [[VLCMediaList alloc] initWithArray:mediaArray];
- return mediaList;
- }
- - (NSString *)_urlAuth:(NSString *)url
- {
- return [self.plexWebAPI urlAuth:url authentification:self.plexAuthentification];
- }
- @end
- @interface VLCNetworkServerBrowserItemPlex()
- @property (nonatomic) NSString *plexAuthentification;
- @end
- @implementation VLCNetworkServerBrowserItemPlex
- @synthesize name = _name, URL = _URL, fileSizeBytes = _fileSizeBytes, container = _container;
- - (instancetype)initWithDictionary:(NSDictionary *)dictionary currentURL:(NSURL *)currentURL authentificication:(NSString *)auth
- {
- self = [super init];
- if (self) {
- _plexAuthentification = auth;
-
- NSURLComponents *components = [[NSURLComponents alloc] initWithURL:currentURL resolvingAgainstBaseURL:NO];
- NSString *path = components.path;
- components.path = nil;
- NSURL *baseURL = components.URL;
- _container = ![dictionary[@"container"] isEqualToString:@"item"];
- NSString *urlPath;
- if (_container) {
- NSString *keyPath = nil;
- NSString *keyValue = dictionary[@"key"];
- if ([keyValue rangeOfString:@"library"].location == NSNotFound)
- keyPath = [path stringByAppendingPathComponent:keyValue];
- else
- keyPath = keyValue;
- if (keyPath)
- urlPath = [baseURL URLByAppendingPathComponent:keyPath].absoluteString;
- } else {
- NSString *keyPath = nil;
- NSString *keyValue = dictionary[@"key"];
- if ([keyValue rangeOfString:@"library"].location == NSNotFound)
- keyPath = [path stringByAppendingPathComponent:keyValue];
- else
- keyPath = keyValue;
- if (keyPath)
- urlPath = [baseURL URLByAppendingPathComponent:keyPath].absoluteString;
- urlPath = [VLCPlexWebAPI urlAuth:urlPath authentification:auth];
- _URLcontainer = [NSURL URLWithString:urlPath];
- urlPath = dictionary[@"keyMedia"];
- }
- urlPath = [VLCPlexWebAPI urlAuth:urlPath authentification:auth];
- _URL = [NSURL URLWithString:urlPath];
- _name = dictionary[@"title"];
- NSString *thumbPath = dictionary[@"thumb"];
- if (thumbPath) {
- thumbPath = [VLCPlexWebAPI urlAuth:thumbPath authentification:auth];
- }
- _thumbnailURL = thumbPath.length ? [NSURL URLWithString:thumbPath] : nil;
- _duration = dictionary[@"duration"];
- _fileSizeBytes = dictionary[@"size"];
- _filename = dictionary[@"namefile"];
- NSString *subtitleURLString = dictionary[@"keySubtitle"];
- if (subtitleURLString)
- subtitleURLString = [VLCPlexWebAPI urlAuth:subtitleURLString authentification:auth];
- _subtitleURL = subtitleURLString.length ? [NSURL URLWithString:subtitleURLString] : nil;
- NSString *subType = dictionary[@"codecSubtitle"];
- _subtitleType = subType.length ? subType : nil;
- }
- return self;
- }
- - (BOOL)isDownloadable
- {
- //VLC also needs an extension in the filename for this to work.
- return YES;
- }
- - (VLCMedia *)media
- {
- if (!_URL)
- return [VLCMedia mediaAsNodeWithName:self.name];
- VLCMedia *media = [VLCMedia mediaWithURL:_URL];
- NSString *title = self.name;
- if (title.length) {
- [media setMetadata:self.name forKey:VLCMetaInformationTitle];
- }
- return media;
- }
- - (id<VLCNetworkServerBrowser>)containerBrowser {
- return [[VLCNetworkServerBrowserPlex alloc] initWithName:self.name url:self.URL auth:self.plexAuthentification];
- }
- @end
|