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

5
Theo 1 Окт 2020 в 21:49

2 ответа

Лучший ответ

preferredTransform - это 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
  }
}
3
Theo 1 Окт 2020 в 18:49

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

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 учитывает такие вещи, как переворачивание.

0
Barak Yoresh 24 Фев 2021 в 19:04