当前播放时间 & NSTimer 在视频期间启动视图,并在使用洗涤器定位时间点时正确启动/重新启动

发布于 2024-11-03 07:47:14 字数 3322 浏览 0 评论 0原文

在这里苦苦挣扎...

我试图在视频时间线的特定时间段内显示视图,并在触发下一个视图时被替换。我已经做到了这么多 - 我的问题是,这仅以线性方式发生,如果播放头移回已触发的视图(即该点之前的任何内容),计时器将继续运行,但触发器会触发不再开火。

任何帮助将不胜感激!这是代码...

- (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];
    [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];
}

这是日志调用直到...

这是日志调用...

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

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];
    [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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长亭外,古道边 2024-11-10 07:47:15

发生这种情况是因为 position 是一个静态变量,您总是提高它但从不降低它。

您需要稍微更改计时器函数内的逻辑 - 也许像这样;

从源中删除静态变量 position (intposition = 0;)

- (NSInteger)positionFromPlaybackTime:(NSTimeInterval)playbackTime
{
  NSInteger position = 0;
  for (NSNumber *startsAt in shoutOutTimes)
  {
    if (playbackTime > [startsAt floatValue])
    {
      ++position;
    }
  }
  return position;
}

添加一个静态变量(实际上实例变量会更干净,但是嘿,我们只是想获取它此时可以工作):

NSTimeInterval lastCheckAt = -1.0;

然后将您的计时器方法更改为:

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文