Playback: Start playback and seek in the background
Perform playback start and seeking operations in the background, instead of on the main thread, which should help prevent them from stalling the user interface. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
d4196a5595
commit
f54dd1c7b1
3 changed files with 45 additions and 6 deletions
|
@ -23,6 +23,35 @@
|
|||
|
||||
extern BOOL kAppControllerShuttingDown;
|
||||
|
||||
@implementation NSObject (NxAdditions)
|
||||
|
||||
-(void)performSelectorInBackground:(SEL)selector withObjects:(id)object, ...
|
||||
{
|
||||
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
|
||||
|
||||
// Setup the invocation
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
invocation.target = self;
|
||||
invocation.selector = selector;
|
||||
|
||||
// Associate the arguments
|
||||
va_list objects;
|
||||
va_start(objects, object);
|
||||
unsigned int objectCounter = 2;
|
||||
for (id obj = object; obj != nil; obj = va_arg(objects, id))
|
||||
{
|
||||
[invocation setArgument:&obj atIndex:objectCounter++];
|
||||
}
|
||||
va_end(objects);
|
||||
|
||||
// Make sure to invoke on a background queue
|
||||
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithInvocation:invocation];
|
||||
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
|
||||
[backgroundQueue addOperation:operation];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlaybackController
|
||||
|
||||
#define DEFAULT_SEEK 5
|
||||
|
@ -241,7 +270,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
|||
|
||||
double seekTime = pe.seekable ? [offset doubleValue] : 0.0;
|
||||
|
||||
[audioPlayer play:pe.url withUserInfo:pe withRGInfo:makeRGInfo(pe) startPaused:paused andSeekTo:seekTime];
|
||||
[audioPlayer performSelectorInBackground:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(seekTime), nil];
|
||||
}
|
||||
|
||||
- (IBAction)next:(id)sender {
|
||||
|
@ -272,7 +301,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
|||
- (IBAction)seek:(id)sender {
|
||||
double time = [sender doubleValue];
|
||||
|
||||
[audioPlayer seekToTime:time];
|
||||
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(time)];
|
||||
|
||||
lastPosition = -10;
|
||||
|
||||
|
@ -289,7 +318,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
|||
|
||||
lastPosition = -10;
|
||||
|
||||
[audioPlayer seekToTime:time];
|
||||
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(time)];
|
||||
|
||||
[self setPosition:time];
|
||||
|
||||
|
@ -321,7 +350,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
|||
[self next:self];
|
||||
} else {
|
||||
lastPosition = -10;
|
||||
[audioPlayer seekToTime:seekTo];
|
||||
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(seekTo)];
|
||||
[self setPosition:seekTo];
|
||||
}
|
||||
}
|
||||
|
@ -338,7 +367,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
|||
|
||||
lastPosition = -10;
|
||||
|
||||
[audioPlayer seekToTime:seekTo];
|
||||
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(seekTo)];
|
||||
[self setPosition:seekTo];
|
||||
}
|
||||
|
||||
|
@ -704,7 +733,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
|||
PlaylistEntry *pe = [playlistController currentEntry];
|
||||
BOOL paused = playbackStatus == CogStatusPaused;
|
||||
[[FIRCrashlytics crashlytics] logWithFormat:@"Restarting playback of track: %@", pe.url];
|
||||
[player play:pe.url withUserInfo:pe withRGInfo:makeRGInfo(pe) startPaused:paused andSeekTo:pe.seekable ? pe.currentPosition : 0.0];
|
||||
[player performSelectorInBackground:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(pe.seekable ? pe.currentPosition : 0.0), nil];
|
||||
}
|
||||
|
||||
- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo {
|
||||
|
|
|
@ -61,12 +61,14 @@
|
|||
- (void)play:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi;
|
||||
- (void)play:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(BOOL)paused;
|
||||
- (void)play:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(BOOL)paused andSeekTo:(double)time;
|
||||
- (void)playBG:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(NSNumber *)paused andSeekTo:(NSNumber *)time;
|
||||
|
||||
- (void)stop;
|
||||
- (void)pause;
|
||||
- (void)resume;
|
||||
|
||||
- (void)seekToTime:(double)time;
|
||||
- (void)seekToTimeBG:(NSNumber *)time;
|
||||
- (void)setVolume:(double)v;
|
||||
- (double)volume;
|
||||
- (double)volumeUp:(double)amount;
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
[self play:url withUserInfo:userInfo withRGInfo:rgi startPaused:paused andSeekTo:0.0];
|
||||
}
|
||||
|
||||
- (void)playBG:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(NSNumber *)paused andSeekTo:(NSNumber *)time {
|
||||
[self play:url withUserInfo:userInfo withRGInfo:rgi startPaused:[paused boolValue] andSeekTo:[time doubleValue]];
|
||||
}
|
||||
|
||||
- (void)play:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(BOOL)paused andSeekTo:(double)time {
|
||||
ALog(@"Opening file for playback: %@ at seek offset %f%@", url, time, (paused) ? @", starting paused" : @"");
|
||||
|
||||
|
@ -165,6 +169,10 @@
|
|||
[self setPlaybackStatus:CogStatusPlaying waitUntilDone:YES];
|
||||
}
|
||||
|
||||
- (void)seekToTimeBG:(NSNumber *)time {
|
||||
[self seekToTime:[time doubleValue]];
|
||||
}
|
||||
|
||||
- (void)seekToTime:(double)time {
|
||||
if(endOfInputReached) {
|
||||
// This is a dirty hack in case the playback has finished with the track
|
||||
|
|
Loading…
Reference in a new issue