iOS: изменение размера / обрезка записанного видео - PullRequest
3 голосов
/ 15 февраля 2011

Каков наилучший способ изменить размер видео, записанного пользователем на iphone?

В настоящее время у меня есть возможность получать видеоданные двумя способами:

1) Получить URL-адрес файлас UIImagePickerController после того, как видео было записано

2) Получить кадры видео по мере его отправки с помощью AVCaptureSession

. Для 1) Мне нужно что-то, что может читать.Переместить файлы h.264 и выложить отдельные кадры.Есть ли такая вещь?

Для 2) Я думал о получении UIImage для каждого кадра, изменении размера изображения и затем перекомпиляции видео с чем-то вроде AVAssetWriter.Но это похоже на очень интенсивную операцию, и мне интересно, есть ли лучший способ решения этой проблемы.

Является ли общая идея изменения размера видео для изменения размера каждого отдельного кадра, а затем перекомпилировать видео?Или есть способ напрямую изменить размер всего видео?

Мне просто нужно, чтобы пользователь записал видео, а затем изменил размер этого видео до 320x320, никакого необычного редактирования.

Спасибо залюбая помощь, которую вы можете предоставить.

Редактировать: Возможно, слово «изменить размер» - неправильное слово.Мне действительно просто нужно обрезать видео, чтобы оно было от 480x360 до 320x320.Кроме того, это обрезка не должна происходить в режиме реального времени, я могу сделать это, когда видео было записано.

Ответы [ 4 ]

3 голосов
/ 11 января 2013

В случае, если кто-то столкнется с этим, я обнаружил, что вы можете сделать это с AVFoundation, если вы используете AVMutableVideoComposition, а также AVMutableComposition.Затем вы устанавливаете renderSize для композиции видео, и это повлияет на выходной размер видео.Затем вы используете AVMutableVideoCompositionLayerInstruction для размещения видео, где вы хотите его.Есть хорошая статья здесь о начале работы со всеми этими классами, и его пример проекта в конце закомментировал код для его экспорта.

3 голосов
/ 17 февраля 2014

Идеальный способ - использовать AVAssetReader для чтения видеофайла и AVAssetWriter для повторной записи этого видеофайла в новый видеофайл. Вы можете установить выходной набор для ввода записи:

NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
                                  AVVideoCodecH264, AVVideoCodecKey,
                                  [NSNumber numberWithInt: 480], AVVideoWidthKey,
                                  [NSNumber numberWithInt: 480], AVVideoHeightKey,
                                      AVVideoScalingModeResizeAspectFill,AVVideoScalingModeKey,
                                  nil];
        NSLog(@"%@",[assetVideoTrack mediaType]);
assetWriterVideoInput = [AVAssetWriterInput assetWriterInputWithMediaType: [assetVideoTrack mediaType]
                                                                   outputSettings:settings];
        [assetWriter addInput:assetWriterVideoInput];

Вы ищете документацию для разработчиков Apple, чтобы найти строку руководства о AVAssetReader

2 голосов
/ 15 февраля 2011

Альтернатива 2 не будет работать в режиме реального времени.

Для альтернативы 1 используйте AVAssetExportSession, инициализированный с одной из желаемых предустановок - например, AVAssetExportPreset640x480.

Поэкспериментируйте с AVAssetExportPresetLowQuality, AVAssetExportPresetMediumQuality, AVAssetExportPresetHighestQuality для дополнительных разрешений.

Обратите внимание, что видеофайлы обычно имеют соотношение сторон 16: 9 (или 4: 3), поэтому 320x320недопустимый вариант.Нет веских причин для изменения размера, кроме поддерживаемых разрешений, если только вы не планируете распространять их на другие телефоны, и в этом случае доступно транскодирование на стороне сервера.

0 голосов
/ 09 сентября 2016

Вам необходимо принять во внимание ориентацию видео. Вот решение Swift 2. Это и обрезает, и масштабирует видео

extension AVAsset {

  private var g_naturalSize: CGSize {
    return tracksWithMediaType(AVMediaTypeVideo).first?.naturalSize ?? .zero
  }

  var g_correctSize: CGSize {
    return g_isPortrait ? CGSize(width: g_naturalSize.height, height: g_naturalSize.width) : g_naturalSize
  }

  var g_isPortrait: Bool {
    let portraits: [UIInterfaceOrientation] = [.Portrait, .PortraitUpsideDown]
    return portraits.contains(g_orientation)

  // Same as UIImageOrientation
  var g_orientation: UIInterfaceOrientation {
    guard let transform = tracksWithMediaType(AVMediaTypeVideo).first?.preferredTransform else {
      return .Portrait
    }

    switch (transform.tx, transform.ty) {
    case (0, 0):
      return .LandscapeRight
    case (g_naturalSize.width, g_naturalSize.height):
      return .LandscapeLeft
    case (0, g_naturalSize.width):
      return .PortraitUpsideDown
    default:
      return .Portrait
    }
  }
}

Вот как получить преобразование

func transform(avAsset: AVAsset, scaleFactor: CGFloat) -> CGAffineTransform {
    let offset: CGPoint
    let angle: Double

    switch avAsset.g_orientation {
    case .LandscapeLeft:
      offset = CGPoint(x: avAsset.g_correctSize.width, y: avAsset.g_correctSize.height)
      angle = M_PI
    case .LandscapeRight:
      offset = CGPoint.zero
      angle = 0
    case .PortraitUpsideDown:
      offset = CGPoint(x: 0, y: avAsset.g_correctSize.height)
      angle = -M_PI_2
    default:
      offset = CGPoint(x: avAsset.g_correctSize.width, y: 0)
      angle = M_PI_2
    }

    let scale = CGAffineTransformMakeScale(scaleFactor, scaleFactor)
    let translation = CGAffineTransformTranslate(scale, offset.x, offset.y)
    let rotation = CGAffineTransformRotate(translation, CGFloat(angle))

    return rotation
  }

А как это использовать в инструкции к слою

let layer = AVMutableVideoCompositionLayerInstruction(assetTrack: track)
layer.setTransform(transform(avAsset, scaleFactor: 0.8), atTime: kCMTimeZero)

1010 * Ссылки *

...