diff --git a/Limelight.xcodeproj/project.pbxproj b/Limelight.xcodeproj/project.pbxproj index ad3f193..60dfd93 100644 --- a/Limelight.xcodeproj/project.pbxproj +++ b/Limelight.xcodeproj/project.pbxproj @@ -38,6 +38,8 @@ FB290E7919B37D81004C83CF /* MainFrame-iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */; }; FB290E7B19B38036004C83CF /* MainFrame-iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */; }; FB7E794419C8B71B00A15F68 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7E794319C8B71B00A15F68 /* libiconv.dylib */; }; + FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F119EDB08B00929691 /* MDNSManager.m */; }; + FBAB29F619EDE0F800929691 /* Computer.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F519EDE0F800929691 /* Computer.m */; }; FBD8B40519C906230032E027 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD8B3FD19C906230032E027 /* libavcodec.a */; }; FBD8B40619C906230032E027 /* libavdevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD8B3FE19C906230032E027 /* libavdevice.a */; }; FBD8B40719C906230032E027 /* libavfilter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD8B3FF19C906230032E027 /* libavfilter.a */; }; @@ -106,6 +108,10 @@ FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPad.storyboard"; sourceTree = SOURCE_ROOT; }; FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPhone.storyboard"; sourceTree = SOURCE_ROOT; }; FB7E794319C8B71B00A15F68 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; }; + FBAB29F119EDB08B00929691 /* MDNSManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDNSManager.m; sourceTree = ""; }; + FBAB29F319EDB0C400929691 /* MDNSManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDNSManager.h; sourceTree = ""; }; + FBAB29F419EDE0F800929691 /* Computer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Computer.h; sourceTree = ""; }; + FBAB29F519EDE0F800929691 /* Computer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Computer.m; sourceTree = ""; }; FBD8B3FD19C906230032E027 /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavcodec.a; sourceTree = ""; }; FBD8B3FE19C906230032E027 /* libavdevice.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavdevice.a; sourceTree = ""; }; FBD8B3FF19C906230032E027 /* libavfilter.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavfilter.a; sourceTree = ""; }; @@ -300,6 +306,10 @@ FB290D0819B2C406004C83CF /* Images.xcassets */, FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */, FB290CFA19B2C406004C83CF /* Supporting Files */, + FBAB29F119EDB08B00929691 /* MDNSManager.m */, + FBAB29F319EDB0C400929691 /* MDNSManager.h */, + FBAB29F419EDE0F800929691 /* Computer.h */, + FBAB29F519EDE0F800929691 /* Computer.m */, ); path = Limelight; sourceTree = ""; @@ -697,9 +707,11 @@ buildActionMask = 2147483647; files = ( FB290D3D19B2C6E3004C83CF /* VideoDepacketizer.m in Sources */, + FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */, FB290D0719B2C406004C83CF /* Limelight.xcdatamodeld in Sources */, FB290D3E19B2C6E3004C83CF /* VideoRenderer.m in Sources */, FB290D0419B2C406004C83CF /* AppDelegate.m in Sources */, + FBAB29F619EDE0F800929691 /* Computer.m in Sources */, FB290D3A19B2C6E3004C83CF /* StreamFrameViewController.m in Sources */, FB290D0019B2C406004C83CF /* main.m in Sources */, FB290D3919B2C6E3004C83CF /* MainFrameViewController.m in Sources */, diff --git a/Limelight/Computer.h b/Limelight/Computer.h new file mode 100644 index 0000000..17fec12 --- /dev/null +++ b/Limelight/Computer.h @@ -0,0 +1,18 @@ +// +// Computer.h +// Limelight +// +// Created by Diego Waxemberg on 10/14/14. +// Copyright (c) 2014 Limelight Stream. All rights reserved. +// + +#import + +@interface Computer : NSObject +@property NSString* displayName; +@property NSString* hostName; +@property BOOL paired; + +- (id) initWithHost:(NSNetService*)host; + +@end diff --git a/Limelight/Computer.m b/Limelight/Computer.m new file mode 100644 index 0000000..2d03366 --- /dev/null +++ b/Limelight/Computer.m @@ -0,0 +1,22 @@ +// +// Computer.m +// Limelight +// +// Created by Diego Waxemberg on 10/14/14. +// Copyright (c) 2014 Limelight Stream. All rights reserved. +// + +#import "Computer.h" + +@implementation Computer + +- (id) initWithHost:(NSNetService *)host { + self = [super init]; + + self.hostName = [host hostName]; + self.displayName = [host name]; + + return self; +} + +@end diff --git a/Limelight/MDNSManager.h b/Limelight/MDNSManager.h new file mode 100644 index 0000000..b3cb988 --- /dev/null +++ b/Limelight/MDNSManager.h @@ -0,0 +1,28 @@ +// +// MDNSManager.h +// Limelight +// +// Created by Diego Waxemberg on 10/14/14. +// Copyright (c) 2014 Limelight Stream. All rights reserved. +// + +#import + +@protocol MDNSCallback + +- (void) updateHosts:(NSArray*)hosts; + +@end + +@interface MDNSManager : NSObject + +@property id callback; + +- (id) initWithCallback:(id) callback; +- (void) searchForHosts; +- (NSArray*) getFoundHosts; + +@end + + + diff --git a/Limelight/MDNSManager.m b/Limelight/MDNSManager.m new file mode 100644 index 0000000..e8fe692 --- /dev/null +++ b/Limelight/MDNSManager.m @@ -0,0 +1,74 @@ +// +// MDNSManager.m +// Limelight +// +// Created by Diego Waxemberg on 10/14/14. +// Copyright (c) 2014 Limelight Stream. All rights reserved. +// + +#import "MDNSManager.h" +#import "Computer.h" + +@implementation MDNSManager : NSObject +NSNetServiceBrowser* mDNSBrowser; +NSMutableArray* domains; +NSMutableArray* services; + +static NSString* NV_SERVICE_TYPE = @"_nvstream._tcp"; + +- (id) initWithCallback:(id)callback { + self = [super init]; + + self.callback = callback; + + mDNSBrowser = [[NSNetServiceBrowser alloc] init]; + [mDNSBrowser setDelegate:self]; + + domains = [[NSMutableArray alloc] init]; + services = [[NSMutableArray alloc] init]; + + return self; +} + +- (void) searchForHosts { + NSLog(@"Searching for hosts..."); + [mDNSBrowser searchForServicesOfType:NV_SERVICE_TYPE inDomain:@""]; +} + +- (NSArray*) getFoundHosts { + NSMutableArray* hosts = [[NSMutableArray alloc] init]; + for (NSNetService* service in services) { + if (service.hostName != nil) { + [hosts addObject:[[Computer alloc] initWithHost:service]]; + } + } + return [[NSArray alloc] initWithArray:hosts]; +} + +- (void)netServiceDidResolveAddress:(NSNetService *)service { + NSLog(@"Resolved address: %@ -> %@", service, service.hostName); + [self.callback updateHosts:[self getFoundHosts]]; +} + +- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict { + NSLog(@"Did not resolve address for: %@\n%@", sender, [errorDict description]); +} + +- (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing { + NSLog(@"Found service: %@", aNetService); + [aNetService setDelegate:self]; + [aNetService resolveWithTimeout:5]; + [services addObject:aNetService]; +} + +- (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveService:(NSNetService *)aNetService moreComing:(BOOL)moreComing { + NSLog(@"Removing service: %@", aNetService); + [services removeObject:aNetService]; +} + +- (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didNotSearch:(NSDictionary *)errorDict { + NSLog(@"Did not perform search"); + NSLog(@"%@", [errorDict description]); +} + +@end \ No newline at end of file diff --git a/Limelight/MainFrameViewController.h b/Limelight/MainFrameViewController.h index a13c144..f3cae6f 100644 --- a/Limelight/MainFrameViewController.h +++ b/Limelight/MainFrameViewController.h @@ -7,13 +7,16 @@ // #import +#import "MDNSManager.h" -@interface MainFrameViewController : UIViewController +@interface MainFrameViewController : UIViewController +@property (strong, nonatomic) IBOutlet UIPickerView *HostPicker; - (IBAction)StreamButton:(UIButton *)sender; - (IBAction)PairButton:(UIButton *)sender; -@property (strong, nonatomic) IBOutlet UITextField *HostField; + @property (strong, nonatomic) IBOutlet UIPickerView *StreamConfigs; @property (strong, nonatomic) NSArray* streamConfigVals; +@property (strong, nonatomic) NSArray* hostPickerVals; + (const char*)getHostAddr; - (void) segueIntoStream; diff --git a/Limelight/MainFrameViewController.m b/Limelight/MainFrameViewController.m index fbf6567..18ac1dc 100644 --- a/Limelight/MainFrameViewController.m +++ b/Limelight/MainFrameViewController.m @@ -9,13 +9,11 @@ #import "MainFrameViewController.h" #import "VideoDepacketizer.h" #import "ConnectionHandler.h" - -@interface MainFrameViewController () - -@end +#import "Computer.h" @implementation MainFrameViewController -static NSString* hostAddr; +NSString* hostAddr; +MDNSManager* mDNSManager; + (const char*)getHostAddr { @@ -25,14 +23,12 @@ static NSString* hostAddr; - (void)PairButton:(UIButton *)sender { NSLog(@"Pair Button Pressed!"); - hostAddr = self.HostField.text; [ConnectionHandler pairWithHost:hostAddr]; } - (void)StreamButton:(UIButton *)sender { NSLog(@"Stream Button Pressed!"); - hostAddr = self.HostField.text; [ConnectionHandler streamWithHost:hostAddr viewController:self]; } @@ -42,11 +38,24 @@ static NSString* hostAddr; - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { - return [self.streamConfigVals objectAtIndex:row]; + if (pickerView == self.StreamConfigs) { + return [self.streamConfigVals objectAtIndex:row]; + } else if (pickerView == self.HostPicker) { + return ((Computer*)([self.hostPickerVals objectAtIndex:row])).displayName; + } else { + return nil; + } } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { + //self.hostPickerVals = [mDNSManager getFoundHosts]; + + //[self.HostPicker reloadAllComponents]; + if (pickerView == self.HostPicker) { + hostAddr = ((Computer*)([self.hostPickerVals objectAtIndex:[self.HostPicker selectedRowInComponent:0]])).hostName; + } + //TODO: figure out how to save this info!! } @@ -59,14 +68,29 @@ static NSString* hostAddr; // returns the # of rows in each component.. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { - return 4; + if (pickerView == self.StreamConfigs) { + return self.streamConfigVals.count; + } else if (pickerView == self.HostPicker) { + return self.hostPickerVals.count; + } else { + return 0; + } } - (void)viewDidLoad { [super viewDidLoad]; - // Do any additional setup after loading the view. - self.streamConfigVals = [[NSArray alloc] initWithObjects:@"1280x720 (30Hz)",@"1280x720 (60Hz)",@"1920x1080 (30Hz)",@"1920x1080 (60Hz)",nil]; + + self.streamConfigVals = [[NSArray alloc] initWithObjects:@"1280x720 (30Hz)", @"1280x720 (60Hz)", @"1920x1080 (30Hz)", @"1920x1080 (60Hz)",nil]; + self.hostPickerVals = [[NSArray alloc] init]; + + mDNSManager = [[MDNSManager alloc] initWithCallback:self]; + [mDNSManager searchForHosts]; +} + +- (void)updateHosts:(NSArray *)hosts { + self.hostPickerVals = hosts; + [self.HostPicker reloadAllComponents]; } - (void)didReceiveMemoryWarning diff --git a/MainFrame-iPad.storyboard b/MainFrame-iPad.storyboard index 8742821..94a881a 100644 --- a/MainFrame-iPad.storyboard +++ b/MainFrame-iPad.storyboard @@ -1,7 +1,6 @@ - @@ -17,20 +16,15 @@ - - - - - - - + + - - + + + + + + + + + - + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - + +