#xcode #video #mpmovieplayercontroller #nstimer
#xcode #Видео #mpmovieplayercontroller #nstimer
Вопрос:
Здесь возникают проблемы…
Я пытаюсь отобразить просмотры в определенные периоды на временной шкале видео, которые будут заменены при запуске следующего просмотра. Это многое, что мне удалось сделать — моя проблема в том, что это происходит только линейным способом, и если начало воспроизведения перемещается обратно к просмотру, который уже был запущен (т. Е. Что-либо до этого момента), таймер продолжает работать, но триггеры больше не срабатывают.
Любая помощь будет высоко оценена! Вот код…
- (void)viewDidLoad {
[super viewDidLoad];
keyframeTimes = [[NSMutableArray alloc] init];
shoutOutTexts = [[NSArray
arrayWithObjects:@"This is a testnLabel at 2 secs ",
@"This is a testnLabel 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];
}
Вот журнал вызовов Till…
Вот журнал вызовов…
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
Ответ №1:
Это происходит потому, что 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 amp;amp; 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;
}
Комментарии:
1. Обратите внимание; это крайне неоптимизировано и на самом деле предназначено в основном для внесения в ваш код как можно меньших изменений по мере необходимости. Я бы вообще посоветовал не перебирать массив в рамках метода, запускаемого по таймеру, если этот массив потенциально может быть довольно большим. Однако для вашего примера это должно быть нормально.
2. Спасибо за это! Серьезно ценю ваше время! Судя по журналу, таймер работает нормально. К сожалению, выкрики теперь не отображаются. У меня была скрипка, но, похоже, я не могу в этом разобраться — Есть мысли?
3. Я не вижу, как изменился бы фактический код отображения. Я добавил немного протоколирования (выкрик: % @), чтобы приблизиться к решению проблемы. Видим ли мы это в журналах? Ой, еще одна вещь. В знак вашей признательности, как только проблема будет решена, вы можете повысить мой ответ и пометить его как принятый (стрелка вверх, галочка рядом с моим ответом).
4. Конечно, я это сделаю — меньшее, что я могу сделать! Я также отправлю вам промо-код для приложения, которое я обновляю, если вы хотите… Кроме того, вы можете захотеть проверить свой веб-сайт — Safari выдает серьезное предупреждение о «вредоносности» после того, как я нажал на ссылку на него — просто подумал, что дам вам знать…
5. Возможно, уместно — если первый выкрик длится 2 секунды, ни в одной из точек ничего не отображается. Если первая выкладка длится 0 секунд, первая работает нормально, но ни одна из следующих не работает. Показалось достаточно интересным, чтобы упомянуть. Указанный выше журнал обновлен..