开发者

currentPlaybackTime & NSTimer to launch views during a video and be correctly launched/relaunched when time point positioned with the scrubber

开发者 https://www.devze.com 2023-02-28 03:15 出处:网络
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 tha

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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消