2012-02-04 1 views
6

У меня возникла проблема синхронизации внешнего контента в CALayer с AVPlayer с высокой точностью.Кадровая синхронизация с AVPlayer

Моя первая мысль заключалась в том, чтобы выстроить массив кадров (равный количеству кадров в видео) в пределах CAKeyframeAnimation и синхронизировать с AVSynchronizedLayer. Однако при переходе по кадру показывается, что AVPlayer и Core Animation перерисовываются на разных циклах, так как между ними перед их синхронизацией происходит небольшая (но заметная) задержка.

Короткая обработка и отображение через Core Video, есть способ точно синхронизировать с AVPlayer на уровне кадра?

обновление: 5 февраля 2012

До сих пор лучший способ я нашел, чтобы сделать это предварительно вынести через AVAssetExportSession в сочетании с AVVideoCompositionCoreAnimationTool и CAKeyFrameAnimation.

Я все еще очень заинтересован в том, чтобы узнать, как это сделать в реальном времени.

ответ

3

Что вы подразумеваете под «высокой точностью»?

Хотя документы заявляют, что AVAssetReader не предназначен для использования в реальном времени, на практике у меня не было проблем с чтением видео в режиме реального времени, используя его (cf https://stackoverflow.com/a/4216161/42961). Возвращенные кадры поставляются с «меткой представления», которую вы можете получить с помощью CMSampleBufferGetPresentationTimeStamp.

Вы хотите, чтобы одна часть проекта была «мастером» хронометриста здесь. Предполагая, что анимация CALayer быстро вычисляется и не включает в себя потенциально блокирующие вещи, такие как доступ к диску, я бы использовал это как главный источник времени. Когда вам нужно сделать содержание (например, в селекторе draw на вашем UIView подкласса), вы должны прочитать currentTime из CALayer анимации, при необходимости проходить через видеокадры AVAssetReader «s с помощью copyNextSampleBuffer, пока CMSampleBufferGetPresentationTimeStamp возвращается> = currentTime, нарисовать рамку, и затем нарисуйте содержимое анимации CALayer сверху.

1

Если ваш плеер использует AVURLAsset, вы загрузили его с установленным точной меткой времени? То есть что-то вроде:

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; 
AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:aUrl options:options];