Предпочтительная форма AVAssetTrack иногда кажется неправильной. Как это можно исправить?

#ios #avfoundation #avassetexportsession

#iOS #avfoundation #avassetexportsession

Вопрос:

Я использую AVAssetExportSession для экспорта видео в приложении iOS. Для рендеринга видео в их правильной ориентации я использую AVAssetTrack s preferredTransform . Для некоторых исходных видеороликов это свойство, похоже, имеет неправильное значение, и в результате видео выглядит смещенным или полностью черным. Как я могу это исправить?

Ответ №1:

Это preferredTransform a CGAffineTransform . Свойства a , b , c , d являются конкатенациями матриц отражения и поворота, а свойства tx и ty описывают перевод. Во всех случаях, которые я наблюдал с неправильным preferredTransform , часть отражения / поворота оказалась правильной, и только часть перевода содержала неправильные значения. Надежное исправление, по-видимому, заключается в проверке a , b , c , d (всего восемь случаев, каждый из которых соответствует случаю в UIImageOrientation ) и обновлении tx и ty соответственно:

 extension AVAssetTrack {
  var fixedPreferredTransform: CGAffineTransform {
    var t = preferredTransform
    switch(t.a, t.b, t.c, t.d) {
    case (1, 0, 0, 1):
      t.tx = 0
      t.ty = 0
    case (1, 0, 0, -1):
      t.tx = 0
      t.ty = naturalSize.height
    case (-1, 0, 0, 1):
      t.tx = naturalSize.width
      t.ty = 0
    case (-1, 0, 0, -1):
      t.tx = naturalSize.width
      t.ty = naturalSize.height
    case (0, -1, 1, 0):
      t.tx = 0
      t.ty = naturalSize.width
    case (0, 1, -1, 0):
      t.tx = naturalSize.height
      t.ty = 0
    case (0, 1, 1, 0):
      t.tx = 0
      t.ty = 0
    case (0, -1, -1, 0):
      t.tx = naturalSize.height
      t.ty = naturalSize.width
    default:
      break
    }
    return t
  }
}
  

Комментарии:

1. Я вижу подобную проблему, но, похоже, она появилась недавно с iOS 14. До этого, preferredTransform казалось, работала корректно в течение многих лет. Мы выяснили, как создается неправильный перевод для дорожки активов? Я хотел бы сообщить об ошибке в Apple, но у меня нет воспроизводимого тестового примера.

2. Мне удалось воспроизвести это на iOS 14 следующим образом: Запишите видео в портретной ориентации с помощью приложения камеры. Затем обрезайте видеокадр до меньшего прямоугольника с помощью приложения «Фотографии». Результирующее видео показывает неправильную предпочтительную форму. Я не понимаю технических деталей, поэтому я не знаю, действительно ли это ошибка в приложении «Фото» или в AVFoundation (является preferredTransform частью видеофайла или он создан на AVFoundation основе других атрибутов видео?). Я отправил ошибку FB8762584, которая была помечена как «Идентифицировано потенциальное исправление».

3. Отличный тестовый пример @Theo. Спасибо. Мы смогли воспроизвести проблему с помощью этих шагов. С точки зрения preferredTransform извлечения и вычисления, это хороший вопрос. Я не уверен. Как бы то ни было, когда наш код iOS сталкивается с видео, сделанным с устройств Android, мы обнаружили, что некоторые из необходимых переводов в preferredTransform могут быть равны нулю и должны быть исправлены аналогичным образом.

Ответ №2:

В итоге я сделал что-то немного более надежное, я думаю, я аннулировал преобразование в зависимости от того, где оно закончится:

 auto naturalFrame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
auto preferredFrame = CGRectApplyAffineTransform(naturalFrame, preferredTransform);
preferredTransform.tx -= preferredFrame.origin.x;
preferredTransform.ty -= preferredFrame.origin.y;
  

Обратите внимание, что вы не можете просто применить преобразование (0, 0) , поскольку CGRect.origin учитывает такие вещи, как переворачивание.