currentPlaybackTime & NSTimer to launch views during a video and be correctly launched/relaunched when time point positioned with the scrubber
Struggling here...
I am trying to have views displayed during specific periods in a videos timeline, being replaced when the next view is triggered. This much I have managed to do - my problem is that this only happens in a linear fashion and if the playhead is moved back to a view that has already been triggered (ie anything prior to that point) the timer continues on, but the triggers are no longer firing.
Any help will be greatly appreciated! Here's the code...
- (void)viewDidLoad {
[super viewDidLoad];
keyframeTimes = [[NSMutableArray alloc] init];
shoutOutTexts = [[NSArray
arrayWithObjects:@"This is a test\nLabel at 2 secs ",
@"This is a test\nLabel at 325 secs",
nil] retain];
shoutOutTimes = [[NSArray
arrayWithObjects:[[NSNumber alloc] initWithInt: 2],
[[NSNumber alloc] initWithInt: 325],
nil] retain];
self.player = [[MPMoviePlayerController alloc] init];
self.player.contentURL = [self movieURL];
// END:viewDidLoad1
self.player.view.frame = self.viewForMovie.bounds;
self.player.view.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[self.viewForMovie addSubview:player.view];
开发者_如何学Go [self.player play];
// START_HIGHLIGHT
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
// END_HIGHLIGHT
// START:viewDidLoad1
[self.view addSubview:self.myScrollView];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(movieDurationAvailable:)
name:MPMovieDurationAvailableNotification
object:nil];
}
// END:viewDidLoad
// END:viewDidLoad1
// START:movieURL
-(NSURL *)movieURL
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath =
[bundle
pathForResource:@"BigBuckBunny_640x360"
ofType:@"m4v"];
if (moviePath) {
return [NSURL fileURLWithPath:moviePath];
} else {
return nil;
}
}
// END:movieURL
int position = 0;
- (void)timerAction:(NSTimer*)theTimer {
NSLog(@"hi");
int count = [shoutOutTimes count];
NSLog(@"count is at %d", count);
if (position < count) {
NSNumber *timeObj = [shoutOutTimes objectAtIndex:position];
int time = [timeObj intValue];
NSLog(@"time is at %d", time);
if (self.player.currentPlaybackTime >= time) {
CommentView *cview = [[CommentView alloc]
initWithText:[shoutOutTexts objectAtIndex:position]];
[self.player.view addSubview:cview];
position++;
[NSTimer scheduledTimerWithTimeInterval:4.0f target:self selector:@selector(removeView:) userInfo:cview repeats:NO];
}
}
}
- (void)removeView:(NSTimer*)theTimer {
UIView *view = [theTimer userInfo];
[view removeFromSuperview];
}
Here's the log calls Till...
Here's the log calls...
2011-04-23 11:53:44.370 MoviePlayer[17129:207] last check was at 7.76279
2011-04-23 11:53:44.371 MoviePlayer[17129:207] current playback time is 8.76292
2011-04-23 11:53:44.371 MoviePlayer[17129:207] shouting: This is a test
Label at 2 secs
2011-04-23 11:53:45.368 MoviePlayer[17129:207] position is at 2
2011-04-23 11:53:45.369 MoviePlayer[17129:207] shout scheduled for 8
2011-04-23 11:53:45.370 MoviePlayer[17129:207] last check was at 8.76451
2011-04-23 11:53:45.371 MoviePlayer[17129:207] current playback time is 9.76299
That happens because position
is a static variable and you are always raising it but never lowering it.
You will need to change the logic within the timer function a little - maybe like this;
Remove the static variable position
from your source (int position = 0;
)
- (NSInteger)positionFromPlaybackTime:(NSTimeInterval)playbackTime
{
NSInteger position = 0;
for (NSNumber *startsAt in shoutOutTimes)
{
if (playbackTime > [startsAt floatValue])
{
++position;
}
}
return position;
}
Add a static variable (actually an instance variable would be cleaner but hey, we are just trying to get it to work at this moment):
NSTimeInterval lastCheckAt = -1.0;
Then change your timer method to this:
- (void)timerAction:(NSTimer*)theTimer
{
int count = [shoutOutTimes count];
NSInteger position = [self positionFromPlaybackTime:self.player.currentPlaybackTime];
NSLog(@"position is at %d", position);
if (position > 0)
{
--position;
}
if (position < count)
{
NSNumber *timeObj = [shoutOutTimes objectAtIndex:position];
int time = [timeObj intValue];
NSLog(@"shout scheduled for %d", time);
NSLog(@"last check was at %g", lastCheckAt);
NSLog(@"current playback time is %g", self.player.currentPlaybackTime);
if (lastCheckAt < time && self.player.currentPlaybackTime >= time)
{
NSString *shoutString = [shoutOutTexts objectAtIndex:position];
NSLog(@"shouting: %@", shoutString);
CommentView *cview = [[CommentView alloc] initWithText:shoutString];
[self.player.view addSubview:cview];
[NSTimer scheduledTimerWithTimeInterval:4.0f target:self selector:@selector(removeView:) userInfo:cview repeats:NO];
}
}
lastCheckAt = self.player.currentPlaybackTime;
}
精彩评论