xcode - currentPlaybackTime 和 NSTimer 在视频期间启动 View ,并在使用 scrubber 定位时间点时正确启动/重新启动

标签 xcode video mpmovieplayercontroller nstimer

在这里挣扎...

我正在尝试在视频时间轴的特定时间段显示 View ,并在触发下一个 View 时替换。我已经设法做到了这么多 - 我的问题是这只会以线性方式发生,如果播放头移回已经触发的 View (即该点之前的任何内容),计时器会继续,但触发器不再射击。

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

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

最佳答案

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

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

从源代码中删除静态变量position (int position = 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;
}

关于xcode - currentPlaybackTime 和 NSTimer 在视频期间启动 View ,并在使用 scrubber 定位时间点时正确启动/重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5748124/

相关文章:

ios - requestLocation 没有调用 didUpdateLocations

video - 如何解决使用ffmpeg生成复杂视频性能低的问题?

javascript - Firefox 选择 .mp4 视频而不是 .ogv

objective-c - 更改 MPMoviePlayerController 实例的视频 url 而不是分配新的

ios - 为什么从全屏返回时我的 MPMoviePlayerController 的 scalingMode 不被尊重?

ios - 保存 Parse PFInstallation 对象时缺少字段

ios 如何在从 UITableView 中的 rss 提要获取数据时显示事件指示器?

java - png 图像文件到视频(无损)

iphone - 无法同时播放 MPMoviePlayerController 和通过 AVAudioRecorder 进行录制?

ios - 我可以在 WatchKit 应用程序中从 iOS 应用程序继承用户定义的环境变量吗?