浏览代码

network server list and discovery list: implement SMB browsing and playback

Felix Paul Kühne 10 年之前
父节点
当前提交
d8c2d7bda6
共有 3 个文件被更改,包括 127 次插入80 次删除
  1. 1 1
      Sources/VLCDiscoveryListViewController.h
  2. 52 25
      Sources/VLCDiscoveryListViewController.m
  3. 74 54
      Sources/VLCServerListViewController.m

+ 1 - 1
Sources/VLCDiscoveryListViewController.h

@@ -14,6 +14,6 @@
 
 @interface VLCDiscoveryListViewController : VLCNetworkListViewController
 
-- (instancetype)initWithMedia:(VLCMedia*)media;
+- (instancetype)initWithMedia:(VLCMedia*)media options:(NSDictionary *)options;
 
 @end

+ 52 - 25
Sources/VLCDiscoveryListViewController.m

@@ -12,32 +12,33 @@
 
 #import "VLCDiscoveryListViewController.h"
 #import "VLCNetworkListCell.h"
+#import "VLCPlaybackController.h"
 
-@interface VLCDiscoveryListViewController () <VLCNetworkListCellDelegate, UITableViewDataSource, UITableViewDelegate, VLCMediaDelegate>
+@interface VLCDiscoveryListViewController () <UITableViewDataSource, UITableViewDelegate, VLCMediaListDelegate>
 {
     VLCMediaList *_mediaList;
-    VLCMedia *rootMedia;
+    VLCMedia *_rootMedia;
+    NSDictionary *_mediaOptions;
 }
 
 @end
 
 @implementation VLCDiscoveryListViewController
 
-- (instancetype)initWithMedia:(VLCMedia *)media
+- (instancetype)initWithMedia:(VLCMedia *)media options:(NSDictionary *)options
 {
     self = [super init];
 
     if (!self)
         return self;
 
-    _mediaList = [media subitems];
-    self.title = [media metadataForKey:VLCMetaInformationTitle];
+    _rootMedia = media;
+    [_rootMedia parseWithOptions:VLCMediaParseNetwork];
 
-    NSLog(@"media meta %@", media.metaDictionary);
+    _mediaList = [_rootMedia subitems];
+    _mediaList.delegate = self;
 
-    NSLog(@"count %lu", _mediaList.count);
-
-    rootMedia = media;
+    self.title = [_rootMedia metadataForKey:VLCMetaInformationTitle];
 
     return self;
 }
@@ -45,21 +46,19 @@
 - (void)viewWillAppear:(BOOL)animated
 {
     [self.tableView reloadData];
-
-    [rootMedia setDelegate:self];
-    [rootMedia parseWithOptions:VLCMediaParseNetwork | VLCMediaFetchNetwork];
 }
 
-#pragma mark - media delegate
 
-- (void)mediaDidFinishParsing:(VLCMedia *)aMedia
+#pragma mark - media list delegate
+- (void)mediaList:(VLCMediaList *)aMediaList mediaAdded:(VLCMedia *)media atIndex:(NSInteger)index
 {
-    NSLog(@"finished parsing %@, sub items %@", aMedia, [aMedia subitems]);
+    [media parseWithOptions:VLCMediaParseNetwork];
+    [self.tableView reloadData];
 }
 
-- (void)mediaMetaDataDidChange:(VLCMedia *)aMedia
+- (void)mediaList:(VLCMediaList *)aMediaList mediaRemovedAtIndex:(NSInteger)index
 {
-    NSLog(@"metadata changed %@, meta %@", aMedia, [aMedia metaDictionary]);
+    [self.tableView reloadData];
 }
 
 #pragma mark - table view data source, for more see super
@@ -71,25 +70,53 @@
 
 - (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
 {
-    static NSString *CellIdentifier = @"DiscoveryCell";
-
-    VLCNetworkListCell *cell = (VLCNetworkListCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier
-                                                                                     forIndexPath:indexPath];
+    VLCNetworkListCell *cell = (VLCNetworkListCell *)[tableView dequeueReusableCellWithIdentifier:VLCNetworkListCellIdentifier];
     if (cell == nil)
-        cell = [VLCNetworkListCell cellWithReuseIdentifier:CellIdentifier];
+        cell = [VLCNetworkListCell cellWithReuseIdentifier:VLCNetworkListCellIdentifier];
 
     VLCMedia *cellObject = [_mediaList mediaAtIndex:indexPath.row];
-    cell.isDirectory = cellObject.mediaType == VLCMediaTypeDirectory;
+    if (cellObject.mediaType == VLCMediaTypeDirectory) {
+        cell.isDirectory = YES;
+        cell.icon = [UIImage imageNamed:@"folder"];
+    } else {
+        cell.isDirectory = NO;
+        cell.icon = [UIImage imageNamed:@"blank"];
+    }
+
     cell.isDownloadable = NO;
+
+    NSString *title = [cellObject metadataForKey:VLCMetaInformationTitle];
+    if (!title)
+        title = cellObject.url.lastPathComponent;
+    if (!title)
+        title = cellObject.url.absoluteString;
     cell.title = [cellObject metadataForKey:VLCMetaInformationTitle];
     cell.subtitle = cellObject.url.absoluteString;
 
     return cell;
 }
 
-- (void)triggerDownloadForCell:(VLCNetworkListCell *)cell
+#pragma mark - table view delegation
+
+- (void)tableView:(nonnull UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
 {
-    NSLog(@"downloads not implemented");
+    [tableView deselectRowAtIndexPath:indexPath animated:YES];
+    NSInteger row = indexPath.row;
+
+    VLCMedia *cellMedia = [_mediaList mediaAtIndex:row];
+
+    if (cellMedia.mediaType == VLCMediaTypeDirectory) {
+        [cellMedia parseWithOptions:VLCMediaParseNetwork];
+        [cellMedia addOptions:_mediaOptions];
+
+        VLCDiscoveryListViewController *targetViewController = [[VLCDiscoveryListViewController alloc]
+                                                                initWithMedia:cellMedia
+                                                                options:_mediaOptions];
+        [[self navigationController] pushViewController:targetViewController animated:YES];
+    } else {
+        VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
+        [vpc playMediaList:_mediaList firstIndex:(int)row];
+    }
 }
 
 @end

+ 74 - 54
Sources/VLCServerListViewController.m

@@ -211,56 +211,6 @@
     }
 }
 
-- (void)_startUPNPDiscovery
-{
-    if (_reachability.currentReachabilityStatus != ReachableViaWiFi)
-        return;
-
-    UPnPManager *managerInstance = [UPnPManager GetInstance];
-
-    _UPNPdevices = [[managerInstance DB] rootDevices];
-
-    if (_UPNPdevices.count > 0)
-        [self UPnPDBUpdated:nil];
-
-    [[managerInstance DB] addObserver:self];
-
-    //Optional; set User Agent
-    if (!_setup) {
-        [[managerInstance SSDP] setUserAgentProduct:[NSString stringWithFormat:@"VLCforiOS/%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]] andOS:[NSString stringWithFormat:@"iOS/%@", [[UIDevice currentDevice] systemVersion]]];
-        _setup = YES;
-    }
-
-    //Search for UPnP Devices
-    [[managerInstance SSDP] startSSDP];
-    [[managerInstance SSDP] notifySSDPAlive];
-
-    _searchTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:1.0] interval:10.0 target:self selector:@selector(_performSSDPSearch) userInfo:nil repeats:YES];
-    [[NSRunLoop mainRunLoop] addTimer:_searchTimer forMode:NSRunLoopCommonModes];
-    _udnpDiscoveryRunning = YES;
-}
-
-- (void)_performSSDPSearch
-{
-    UPnPManager *managerInstance = [UPnPManager GetInstance];
-    [[managerInstance SSDP] searchSSDP];
-    [[managerInstance SSDP] searchForMediaServer];
-    [[managerInstance SSDP] performSelectorInBackground:@selector(SSDPDBUpdate) withObject:nil];
-}
-
-- (void)_stopUPNPDiscovery
-{
-    if (_udnpDiscoveryRunning) {
-        UPnPManager *managerInstance = [UPnPManager GetInstance];
-        [[managerInstance SSDP] notifySSDPByeBye];
-        [_searchTimer invalidate];
-        _searchTimer = nil;
-        [[managerInstance DB] removeObserver:self];
-        [[managerInstance SSDP] stopSSDP];
-        _udnpDiscoveryRunning = NO;
-    }
-}
-
 - (IBAction)goBack:(id)sender
 {
     [self _stopUPNPDiscovery];
@@ -488,8 +438,14 @@
             if (cellMedia.mediaType != VLCMediaTypeDirectory)
                 return;
 
+            NSDictionary *mediaOptions = @{@"smb-user" : @"",
+                                           @"smb-pwd" : @"",
+                                           @"smb-domain" : @""};
+            [cellMedia addOptions:mediaOptions];
+
             VLCDiscoveryListViewController *targetViewController = [[VLCDiscoveryListViewController alloc]
-                                                                    initWithMedia:cellMedia];
+                                                                    initWithMedia:cellMedia
+                                                                    options:mediaOptions];
             [[self navigationController] pushViewController:targetViewController animated:YES];
             break;
         }
@@ -570,6 +526,19 @@ confirmedWithUsername:(NSString *)username
             [[self navigationController] pushViewController:targetViewController animated:YES];
             break;
         }
+        case VLCServerProtocolSMB:
+        {
+            VLCMedia *media = [VLCMedia mediaWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"smb://%@", server]]];
+            NSDictionary *mediaOptions = @{@"smb-user" : username ? username : @"",
+                                           @"smb-pwd" : password ? password : @"",
+                                           @"smb-domain" : @"WORKGROUP"};
+            [media addOptions:mediaOptions];
+
+            VLCDiscoveryListViewController *targetViewController = [[VLCDiscoveryListViewController alloc]
+                                                                    initWithMedia:media
+                                                                    options:mediaOptions];
+            [[self navigationController] pushViewController:targetViewController animated:YES];
+        }
 
         default:
             APLog(@"Unsupported URL Scheme requested %lu", protocol);
@@ -743,7 +712,57 @@ confirmedWithUsername:(NSString *)username
     }
 }
 
-#pragma mark - UPNP details
+#pragma mark - UPNP discovery
+- (void)_startUPNPDiscovery
+{
+    if (_reachability.currentReachabilityStatus != ReachableViaWiFi)
+        return;
+
+    UPnPManager *managerInstance = [UPnPManager GetInstance];
+
+    _UPNPdevices = [[managerInstance DB] rootDevices];
+
+    if (_UPNPdevices.count > 0)
+        [self UPnPDBUpdated:nil];
+
+    [[managerInstance DB] addObserver:self];
+
+    //Optional; set User Agent
+    if (!_setup) {
+        [[managerInstance SSDP] setUserAgentProduct:[NSString stringWithFormat:@"VLCforiOS/%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]] andOS:[NSString stringWithFormat:@"iOS/%@", [[UIDevice currentDevice] systemVersion]]];
+        _setup = YES;
+    }
+
+    //Search for UPnP Devices
+    [[managerInstance SSDP] startSSDP];
+    [[managerInstance SSDP] notifySSDPAlive];
+
+    _searchTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:1.0] interval:10.0 target:self selector:@selector(_performSSDPSearch) userInfo:nil repeats:YES];
+    [[NSRunLoop mainRunLoop] addTimer:_searchTimer forMode:NSRunLoopCommonModes];
+    _udnpDiscoveryRunning = YES;
+}
+
+- (void)_performSSDPSearch
+{
+    UPnPManager *managerInstance = [UPnPManager GetInstance];
+    [[managerInstance SSDP] searchSSDP];
+    [[managerInstance SSDP] searchForMediaServer];
+    [[managerInstance SSDP] performSelectorInBackground:@selector(SSDPDBUpdate) withObject:nil];
+}
+
+- (void)_stopUPNPDiscovery
+{
+    if (_udnpDiscoveryRunning) {
+        UPnPManager *managerInstance = [UPnPManager GetInstance];
+        [[managerInstance SSDP] notifySSDPByeBye];
+        [_searchTimer invalidate];
+        _searchTimer = nil;
+        [[managerInstance DB] removeObserver:self];
+        [[managerInstance SSDP] stopSSDP];
+        _udnpDiscoveryRunning = NO;
+    }
+}
+
 //protocol UPnPDBObserver
 - (void)UPnPDBWillUpdate:(UPnPDB*)sender
 {
@@ -774,7 +793,8 @@ confirmedWithUsername:(NSString *)username
     if (_reachability.currentReachabilityStatus != ReachableViaWiFi)
         return;
 
-    _sapDiscoverer = [[VLCMediaDiscoverer alloc] initWithName:@"sap"];
+    if (!_sapDiscoverer)
+        _sapDiscoverer = [[VLCMediaDiscoverer alloc] initWithName:@"sap"];
     [_sapDiscoverer startDiscoverer];
     _sapDiscoverer.discoveredMedia.delegate = self;
 }
@@ -787,7 +807,7 @@ confirmedWithUsername:(NSString *)username
 
 - (void)mediaList:(VLCMediaList *)aMediaList mediaAdded:(VLCMedia *)media atIndex:(NSInteger)index
 {
-    NSLog(@"found media %@ of type %lu", media.url.lastPathComponent, media.mediaType);
+    [media parseWithOptions:VLCMediaParseNetwork];
     [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
 }