У меня есть AVPlayer, который воспроизводит видеопоток HLS. В моем пользовательском интерфейсе имеется ряд кнопок, по одной для каждой «главы» в видео (. Кнопки помечены как «1», «2», «3» ). Приложение загружает некоторые метаданные -с сервера, которые содержат список сокращений глав -в пунктах, обозначенных в секундах. Например, одно видео имеет продолжительность 12 минут -список нарезок глав -в точках: 0, 58, 71, 230, 530 и т. д. и т. д.
Когда пользователь нажимает одну из «кнопок главы», код обработчика кнопки делает следующее:
[self.avPlayer pause];
[self.avPlayer seekToTime: CMTimeMakeWithSeconds(seekTime, 600)
toleranceBefore: kCMTimeZero
toleranceAfter: kCMTimeZero
completionHandler: ^(BOOL finished)
{
[self.avPlayer play];
}];
Где «seekTime» — это локальная переменная, которая содержит разрез -в точке (, как описано выше ).
Проблема в том, что видео не всегда начинается с нужной точки. Иногда это так. Но иногда это где-то от десятых долей секунды до 2 секунд ДО запрошенного seekTime. Он НИКОГДА не начинается после запрошенного seekTime.
Вот немного статистики по кодированию видео:
Энкодер :ручного тормозаCLI Кодек :h.264 Частота кадров :24 (на самом деле, 23,976 -такая же, как было снято )Битрейт видео :несколько битрейтов (64/150/300/500/800/1200 )Битрейт аудио :128k Ключевые кадры :23,976 (1 в секунду)
Конечно, я использую инструмент Apple mediafilesegmenter и variantplaylistcreator для создания плейлиста.
Файлы обслуживаются из корзины Amazon Cloud/S3.
Одна область, в которой я до сих пор не уверен, это CMTimeMakeWithSeconds -. Я пробовал несколько вариантов, основанных на разных статьях/документах, которые я читал. Например, в приведенном выше отрывке я использую:
CMTimeMakeWithSeconds (seekTime,600)
Я также пробовал:
CMTimeMakeWithSeconds (seekTime, 1)
Я не могу сказать, что правильно, хотя ОБЕ, похоже, дают одинаковые противоречивые результаты!
Я также пробовал:
CMTimeMakeWithSeconds (seekTime, 23,967)
В некоторых статьях утверждается, что это работает как числитель/знаменатель, поэтому n/1 должно быть правильным, где n — количество секунд (, как в CMTimeMakeWithseconds (n, 1 )). Но код изначально был создан другим программистом (, которого сейчас нет ), и он использовал число 600 для предпочтительного TimeScale (, т.е. CMTimeMakeWithseconds (n, 600 )).
Может ли кто-нибудь предложить какие-либо подсказки относительно того, что я делаю неправильно, или даже возможна ли та точность, которую я пытаюсь достичь?
А на случай, если у кого-то возникнет соблазн предложить «альтернативные» решения, мы уже рассматриваем возможность разбивать видео на отдельные потоки, по одному на главу, но не верим, что это даст нам такую же производительность в том плане, что смена глав займет больше времени так как новый AVPlayerItem должен быть создан и загружен и т. д., и т. д., и т. д. Итак, если вы считаете, что это единственное решение, которое будет работать (, и мы ожидаем, что это приведет к желаемому результату -, т.е.. каждая глава БУДЕТ начинаться именно там, где мы хотим )не стесняйтесь говорить об этом.
Заранее спасибо!