Как динамически изменять скорость воспроизведения видео в iOS?

Прекрасный пример того, что я пытаюсь достичь, можно увидеть в приложении Flow ● Slow and Fast Motion.

Можно изменить скорость воспроизведения видео с помощью перетаскивания точек на кривой вверх или вниз. В этом состоянии видео также может быть сохранено.

Я ищу способ динамически ускорить/понизить видео, так что скорость воспроизведения может быть изменена во время воспроизведения видео.

Описание видео

введите описание изображения здесь

ЧТО Я ПОЛУЧИЛ

  • Воспроизведение rate свойства AVPlayer. Но оно работает только с несколькими значениями для воспроизведения Rate (0.50, 0.67, 0.80, 1.0, 1.25, 1.50 и 2.0), и нельзя сохранить видео
  • Свойство scaleTimeRange(..) AVMutableComposition. Но это не работает, если вы хотите рамп видео для постепенного уменьшения медленного/быстрого движения.

  • Показывать кадры видео на экране с помощью CAEAGLLayer и CADisplayLink. Но мои многочисленные попытки попытаться добиться медленного/быстрого движения с этим не увенчались успехом.

Все это заняло у меня месяцы, и я начинаю сомневаться, смогу ли я это сделать.

Таким образом, любое предложение было бы чрезвычайно ценным.

Ответ 1

В IOS объект MPNowPlayingInfoCenter содержит словарь nowPlayingInfo, содержимое которого описывает воспроизводимый элемент. Рекомендуется начать воспроизведение в режиме "currentplaybackrate", а затем установить скорость. Смотрите thread на форуме разработчиков.

Возможно, у вас может получиться что-то вроде this (но это javascript), где скорость воспроизведения видео ускоряется 4.

  document.querySelector('video').playbackRate = 4.0;
  document.querySelector('video').play();
video{width:400px;
   height:auto;}
<video controls preload="true" autoplay>
      <source src="http://www.rachelgallen.com/nature.mp4" type="video/mp4" > 
</video>

Ответ 2

Итак, я не уверен, что полностью понимаю, в каком случае вы собираетесь, но я думаю,

func setRate(_ rate: Float, 
      time itemTime: CMTime, 
      atHostTime hostClockTime: CMTime) 

[Источник документации Apple]

Это то, что вы ищете. Хотя это может быть не совсем то, что вам нужно, я также не уверен, где в документах есть именно то, что вы ищете, но с помощью вышеописанного метода вы можете сделать следующее для сохранения видео с переменной скоростью:

1) Используйте приведенный выше метод для воспроизведения видео на протяжении всего (при условии, что он не слишком длинный, в противном случае это будет невозможно вычислить/время ожидания на некоторых устройствах) с желаемыми тарифами каждую секунду. Design UI, чтобы настроить эту скорость в секунду.

2) под капотом вы можете фактически воспроизвести видео с этой скоростью "по кадре" и захватить нужные вам кадры (в правой части #, которая даст вам желаемую скорость) и voila - сохранение правильного номера (при пропуске/дублировании по мере необходимости для увеличения/уменьшения желаемой скорости на основе пользовательского интерфейса "picker" ) вы выполнили то, что хотите

Чтобы быть ясным, речь идет о видеовыходе @60FPS имеет 60 кадров в секунду. Вы могли бы буквально "вырезать и вставлять" кадры вместе с исходным видео в "целевое" видео на основе любых значений шаговых параметров пользовательского интерфейса, которые вы получаете от своего пользователя (в примере с скриншотом вопрос содержит, в качестве моей основы) и забрать что много кадров. AKA, если пользователь говорит, что секунды 2-10 из их 20-секундного видео должны быть в 2 раза, установите только 30 кадров для каждой из этих секунд (если снято на 60 FPS) чередующихся кадров. Выход на 60FPS выглядит как 2X-скорость (так как теперь есть 30 кадров в секунду на оригинальном видео, что составляет 0,5 секунды при 60 FPS). Точно так же любое значение может быть соответствующим образом учтено в:

  • (желаемый согласованный FPS) = (исходное видео FPS) = (целевое видео FPS) (т.е. 60 или 90)
  • (rate) = (скорость от пользовательских интерфейсов пользовательского интерфейса/графического интерфейса для выбора скорости @каждый временной интервал) (например, 1X/2x/0,25X)
  • (желаемый согласованный FPS) * (скорость) = (# кадров, сохраненных в видео назначения)
  • (целевые видеокадры) = (исходное видео) * (желаемый согласованный FPS) ~, модулированный ~ (за пользовательскую временную интервал)

Точные механизмы для ^^ могут быть фактически встроены в AVPlayer, и я не нашел деталей, но это само по себе должно стать хорошим началом для вас в этом направлении.