Skip to content

Commit

Permalink
Starting queue controller implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
indragiek committed Oct 23, 2015
1 parent 007caa7 commit 7ad0215
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 32 deletions.
5 changes: 0 additions & 5 deletions Audio Players/SMKAVQueuePlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@
- (void)pause;
- (void)play;

// Seeking (SMKPlayer @optional)
- (void)seekToPlaybackTime:(NSTimeInterval)time;
- (void)seekBackward;
- (void)seekForward;

// Preloading (SMKPlayer @optional)
@property (nonatomic, strong, readonly) id<SMKTrack> preloadedTrack;
- (void)preloadTrack:(id<SMKTrack>)track completionHandler:(void(^)(NSError *error))handler;
Expand Down
3 changes: 2 additions & 1 deletion Audio Players/SMKAVQueuePlayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ - (void)preloadTrack:(id<SMKTrack>)track completionHandler:(void (^)(NSError *))

- (void)skipToPreloadedTrack
{
[self.audioPlayer advanceToNextItem];
if ([self.audioPlayer.items count] == 2)
[self.audioPlayer advanceToNextItem];
}

#if !TARGET_OS_IPHONE
Expand Down
5 changes: 0 additions & 5 deletions Audio Players/SMKMPMusicPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,4 @@

- (void)pause;
- (void)play;

// Seeking (SMKPlayer @optional)
- (void)seekToPlaybackTime:(NSTimeInterval)time;
- (void)seekBackward;
- (void)seekForward;
@end
7 changes: 1 addition & 6 deletions Audio Players/SMKSFBAudioPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,8 @@
@property (nonatomic, assign, readonly) BOOL playing;
@property (nonatomic, strong, readonly) id<SMKTrack> currentTrack;

// Seeking (SMKPlayer @optional)
@property (nonatomic, strong, readonly) id<SMKTrack> preloadedTrack;
- (void)seekToPlaybackTime:(NSTimeInterval)time;
- (void)seekBackward;
- (void)seekForward;

// Preloading (SMKPlayer @optional)
@property (nonatomic, strong, readonly) id<SMKTrack> preloadedTrack;
- (void)preloadTrack:(id<SMKTrack>)track completionHandler:(void(^)(NSError *error))handler;
- (id<SMKTrack>)preloadedTrack;
- (void)skipToPreloadedTrack;
Expand Down
5 changes: 0 additions & 5 deletions Audio Players/SMKSpotifyPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@

- (id)initWithPlaybackSession:(SPSession *)aSession;

// Seeking (SMKPlayer @optional)
- (void)seekToPlaybackTime:(NSTimeInterval)time;
- (void)seekBackward;
- (void)seekForward;

// Preloading (SMKPlayer @optional)
@property (nonatomic, strong, readonly) id<SMKTrack> preloadedTrack;
- (void)preloadTrack:(id<SMKTrack>)track completionHandler:(void(^)(NSError *error))handler;
Expand Down
7 changes: 4 additions & 3 deletions Master API/SMKQueueController.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ typedef NSUInteger SMKQueueControllerRepeatMode;

@property (nonatomic, retain, readonly) NSArray *tracks;
- (id)initWithTracks:(NSArray *)tracks;
+ (instancetype)queueControllerWithItems:(NSArray *)tracks;
+ (instancetype)queueControllerWithTracks:(NSArray *)tracks;

- (void)insertTrack:(id<SMKTrack>)track afterTrack:(id<SMKTrack>)track;
- (void)insertTrack:(id<SMKTrack>)newTrack afterTrack:(id<SMKTrack>)track;
- (void)removeAllTracks;
- (void)removeTrack:(id<SMKTrack>)track;

Expand All @@ -34,9 +34,10 @@ typedef NSUInteger SMKQueueControllerRepeatMode;
@property (nonatomic, strong, readonly) id<SMKPlayer> currentPlayer;
@property (nonatomic, strong, readonly) id<SMKTrack> currentTrack;
@property (nonatomic, assign, readonly) NSUInteger indexOfCurrentTrack;
@property (nonatomic, assign, readonly) BOOL playing;
@property (nonatomic, assign) BOOL shuffle;
@property (nonatomic, assign) SMKQueueControllerRepeatMode repeatMode;
#if TARGET_OS_IPHONE
#if !TARGET_OS_IPHONE
@property (nonatomic, assign) float volume;
#endif

Expand Down
226 changes: 226 additions & 0 deletions Master API/SMKQueueController.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,232 @@

#import "SMKQueueController.h"

@interface SMKQueueItem : NSObject
@property (nonatomic, retain) id<SMKTrack> track;
@end

@interface SMKQueueController ()
@property (nonatomic, strong) NSMutableArray *items;
@property (nonatomic, strong, readwrite) id<SMKPlayer> currentPlayer;
@end

@implementation SMKQueueController

- (id)init
{
if ((self = [super init])) {
self.items = [NSMutableArray array];
}
return self;
}

- (id)initWithTracks:(NSArray *)tracks
{
if ((self = [super init])) {
NSArray *items = [self _queueItemsForTracks:tracks];
self.items = [NSMutableArray arrayWithArray:items];
}
return self;
}

+ (instancetype)queueControllerWithTracks:(NSArray *)tracks
{
return [[self alloc] initWithTracks:tracks];
}

#pragma mark - Queue

- (void)insertTrack:(id<SMKTrack>)newTrack afterTrack:(id<SMKTrack>)track
{
if (!track) {
[self.items addObjectsFromArray:[self _queueItemsForTracks:@[newTrack]]];
} else {
NSUInteger index = [self _indexOfTrack:track];
if (index != NSNotFound)
[self insertObject:newTrack inItemsAtIndex:index+1];
}
}

- (void)removeAllTracks
{
[self pause:nil];
self.items = [NSMutableArray array];
}

- (void)removeTrack:(id<SMKTrack>)track
{
NSUInteger index = [self _indexOfTrack:track];
if (index == NSNotFound)
return;
if ([track isEqual:self.currentTrack]) {
[self next:nil];
}
[self removeObjectFromItemsAtIndex:index];
}

#pragma mark - Accessors

- (NSUInteger)indexOfCurrentTrack
{
return [self.items indexOfObject:self.currentTrack];
}

+ (NSSet *)keyPathsForValuesAffectingIndexOfCurrentTrack
{
return [NSSet setWithObject:@"currentTrack"];
}

- (NSTimeInterval)playbackTime
{
return [self.currentPlayer playbackTime];
}

- (void)seekToPlaybackTime:(NSTimeInterval)playbackTime
{
[self.currentPlayer seekToPlaybackTime:playbackTime];
}

+ (NSSet *)keyPathsForValuesAffectingPlaybackTime
{
return [NSSet setWithObject:@"currentPlayer.playbackTime"];
}

- (BOOL)playing
{
return [self.currentPlayer playing];
}

+ (NSSet *)keyPathsForValuesAffectingPlaying
{
return [NSSet setWithObject:@"currentPlayer.playing"];
}

- (NSArray *)tracks
{
return [self.items valueForKey:@"track"];
}

+ (NSSet *)keyPathsForValuesAffectingTracks
{
return [NSSet setWithObject:@"items"];
}

- (id<SMKTrack>)currentTrack
{
return [self.currentPlayer currentTrack];
}

+ (NSSet *)keyPathsForValuesAffectingCurrentTrack
{
return [NSSet setWithObject:@"currentPlayer.currentTrack"];
}

#pragma mark - Array Accessors

- (NSUInteger)countOfItems
{
return [self.items count];
}

- (id)objectInItemsIndex:(NSUInteger)index
{
return [self.items objectAtIndex:index];
}

- (void)insertObject:(id)obj inItemsAtIndex:(NSUInteger)index
{
[self.items insertObject:obj atIndex:index];
}

- (void)removeObjectFromItemsAtIndex:(NSUInteger)index
{
[self.items removeObjectAtIndex:index];
}

- (void)replaceObjectInItemsAtIndex:(NSUInteger)index withObject:(id)obj
{
[self.items replaceObjectAtIndex:index withObject:obj];
}

#pragma mark - Playback

- (IBAction)play:(id)sender
{
if (!self.currentPlayer && [self.items count]) {
[self _beginPlayingItemAtIndex:0];
}
[self.currentPlayer play];
}

- (IBAction)pause:(id)sender
{
[self.currentPlayer pause];
}

- (IBAction)playPause:(id)sender
{
[self playing] ? [self pause:nil] : [self play:nil];
}

- (IBAction)next:(id)sender
{

}

- (IBAction)previous:(id)sender
{

}

- (IBAction)seekForward:(id)sender
{

}

- (IBAction)seekBackward:(id)sender
{

}

#pragma mark - Private

- (NSArray *)_queueItemsForTracks:(NSArray *)tracks
{
NSMutableArray *items = [NSMutableArray arrayWithCapacity:[tracks count]];
[tracks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
SMKQueueItem *item = [SMKQueueItem new];
item.track = obj;
[items addObject:item];
}];
return items;
}

- (NSUInteger)_indexOfTrack:(id<SMKTrack>)track
{
__block NSUInteger index = NSNotFound;
[self.items enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([[obj track] isEqual:track]) {
index = idx;
*stop = YES;
}
}];
return index;
}

- (void)_beginPlayingItemAtIndex:(NSUInteger)index
{
id<SMKTrack> track = [[self.items objectAtIndex:index] track];
self.currentPlayer = [[track playerClass] new];
__weak SMKQueueController *weakSelf = self;
[self.currentPlayer playTrack:track completionHandler:^(NSError *error) {
if (error) {
SMKQueueController *strongSelf = weakSelf;
SMKGenericErrorLog([NSString stringWithFormat:@"Error playing track %@", track], error);
[strongSelf removeObjectFromItemsAtIndex:index];
strongSelf.currentPlayer = nil;
if (index < [self.items count])
[self _beginPlayingItemAtIndex:index];
}
}];
}
@end
14 changes: 7 additions & 7 deletions Protocols/SMKPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,6 @@
*/
- (NSTimeInterval)playbackTime;

@optional

/**
@return The player volume from 0.0 to 1.0
*/
@property (nonatomic, assign) float volume;

/**
The seek time interval for the -seekBackward and -seekForward methods.
*/
Expand All @@ -88,6 +81,13 @@
*/
- (void)seekForward;

@optional

/**
@return The player volume from 0.0 to 1.0
*/
@property (nonatomic, assign) float volume;

/**
Preload the specified track (if the player supports preloading)
@param handler Completion handler called with an NSError if preloading failed and nil if successful.
Expand Down
Binary file not shown.

0 comments on commit 7ad0215

Please sign in to comment.