У меня возникли проблемы с регистрацией КОГДА игрок начинает проигрывать внешние видеоролики (через Интернет) с помощью AVPlayer
. Пожалуйста, прочитайте вопрос, прежде чем предлагать решения.
Я инициализирую плеер следующим образом:
player = [[AVPlayer alloc] initWithURL:[[NSURL alloc] initWithString:@"http://example.com/video.mp4"]];
playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
[playerLayer setFrame:[videoView bounds]];
[videoView.layer addSublayer:playerLayer];
Это правильно добавляет плеер в представление. Я добавил следующие две строки кода, чтобы отслеживать, когда плеер готов, и каков статус/скорость:
[player addObserver:self forKeyPath:@"rate" options:0 context:nil];
[player addObserver:self forKeyPath:@"status" options:0 context:nil];
Эти две строки вызовут метод - (void)observeValueForKeyPath:....
, когда что-то изменится со статусом или скоростью AVPlayer
.
Пока это выглядит так:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
//To print out if it is 'rate' or 'status' that has changed:
NSLog(@"Changed: %@", keyPath);
if ([keyPath isEqualToString:@"rate"]) //If rate has changed:
{
if ([player rate] != 0) //If it started playing
{
NSLog(@"Total time: %f", CMTimeGetSeconds([[player currentItem] duration]));
// This NSLog is supposed to print out the duration of the video.
[self setControls];
// This method (setControls) is supposed to set play/pause-buttons
// as well as labels for the current and total time of the current video.
}
}
else if ([keyPath isEqualToString:@"status"]) // If the status changed
{
if(player.status == AVPlayerStatusReadyToPlay) //If "ReadyToPlay"
{
NSLog(@"ReadyToPlay");
[player play]; //Start the video
}
}
}
state
AVPlayer
почти сразу после инициализации изменяется на readyToPlay
, а затем я вызываю [player play]
. Когда это произойдет, rate
изменится на 1.00000
, что означает, что он действительно играет с такой скоростью, но видео теперь только начинает буферировать, а не воспроизводиться. Экран черный, и он занимает пару секунд, а затем начинает воспроизведение. Тем не менее, скорость указывает, что он начинает играть до того, как он это сделает. Скорость остается на уровне 1.00000
, а при начале буферизации не уменьшается до 0
, что затрудняет мне знать, когда у игрока достаточно информации, чтобы начать настройку элементов управления (метки времени IE и т.д.).
NSLog()
печать продолжительности видео выше выводит nan
(Not A Number), что заставляет меня думать, что элемент не готов к воспроизведению, однако скорость остается на уровне 1.0000
пока он не забуферизуется некоторое время, тогда он будет играть, все еще со скоростью в 1.0000
.
Однако он вызывает вызов дважды. rate
"изменяется" на 1.0000
дважды, не находясь между ними. В обоих вызовах продолжительность видео является доступной переменной.
Моя цель - как можно быстрее получить текущую и общую временную метку видео (I.E 0:00/3:52
). Это также будет использоваться для регистрации очистки ползунка (для быстрой перемотки вперед и т.д.).
Эти значения не готовы, когда игрок уведомляет меня, что он играет со скоростью 1.0000
, дважды. Если я вручную нажму "play" через секунду или так (и вызовите [player play]
), тогда он будет работать. Как я могу зарегистрироваться, когда видео готово, а не только "готово готовиться"?