Фиксирование ориентации при сшивании (слиянии) видео с использованием AVMutableComposition

TLDR – ВИДЕТЬ РЕДАКТИРОВАТЬ

Я создаю тестовое приложение в Swift, где я хочу сшить несколько видео вместе из каталога документов приложений, используя AVMutableComposition .

У меня был успех в этом, до некоторой степени, все мои видео сшиты вместе, и все показывает правильный портрет и пейзаж.

Моя проблема, однако, в том, что все видеоролики отображаются в ориентации последнего видео в компиляции.

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

Это не тот результат, который я ищу, я хочу ожидаемую функциональность, т. Е. Если видеоролик является ландшафтом, он показывает масштабирование в портретном режиме, но если телефон повернут, я хочу, чтобы ландшафтное видео заполняло экран (как это было бы при простом просмотре пейзажное видео на фотографиях) и то же самое для портрета, чтобы при просмотре на портрете он был полноэкранным, а когда он повернут сбоку, видео масштабируется до размера ландшафта (как при просмотре портретного видео на фотографиях).

В общем, желаемый результат, который я хочу, заключается в том, что при просмотре компиляции с пейзажными и портретными видеороликами я могу просмотреть всю компиляцию с моим телефоном на боку, а пейзажные видеоролики – полноэкранный и портретный масштаб, или при просмотре одного и того же видео в портретные видеоролики – полный экран, а пейзажные видео масштабируются по размеру.

Со всеми ответами я обнаружил, что это не так, и все они, казалось, имели очень неожиданное поведение при импорте видео с фотографий, чтобы добавить к компиляции, и такое же случайное поведение при добавлении видеороликов, снятых с фронтальной камерой (до с моими текущими видеороликами реализации, импортированными из библиотеки, и видеоролики «selfie» появляются с правильным размером без этих проблем).

Я ищу способ повернуть / масштабировать эти видео, чтобы они всегда показывались в правильной ориентации и масштабах, в зависимости от того, каким образом пользователь держит свой телефон.

EDIT : Теперь я знаю, что я не могу иметь ориентацию пейзажа и портрета в одном видео, поэтому ожидаемый результат, который я ищу, – это иметь окончательное видео в альбомной ориентации. я выяснил, как сделать все ориентации и масштабы, чтобы получить все одинаково, но мой вывод – портретное видео, если кто-то может помочь мне изменить это, поэтому мой результат – это пейзаж, который будет оценен.

Ниже приведена моя функция для получения инструкции для каждого видео:

 func videoTransformForTrack(asset: AVAsset) -> CGAffineTransform { var return_value:CGAffineTransform? let assetTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0] let transform = assetTrack.preferredTransform let assetInfo = orientationFromTransform(transform) var scaleToFitRatio = UIScreen.mainScreen().bounds.width / assetTrack.naturalSize.width if assetInfo.isPortrait { scaleToFitRatio = UIScreen.mainScreen().bounds.width / assetTrack.naturalSize.height let scaleFactor = CGAffineTransformMakeScale(scaleToFitRatio, scaleToFitRatio) return_value = CGAffineTransformConcat(assetTrack.preferredTransform, scaleFactor) } else { let scaleFactor = CGAffineTransformMakeScale(scaleToFitRatio, scaleToFitRatio) var concat = CGAffineTransformConcat(CGAffineTransformConcat(assetTrack.preferredTransform, scaleFactor), CGAffineTransformMakeTranslation(0, UIScreen.mainScreen().bounds.width / 2)) if assetInfo.orientation == .Down { let fixUpsideDown = CGAffineTransformMakeRotation(CGFloat(M_PI)) let windowBounds = UIScreen.mainScreen().bounds let yFix = assetTrack.naturalSize.height + windowBounds.height let centerFix = CGAffineTransformMakeTranslation(assetTrack.naturalSize.width, yFix) concat = CGAffineTransformConcat(CGAffineTransformConcat(fixUpsideDown, centerFix), scaleFactor) } return_value = concat } return return_value! } 

И экспортер:

  // Create AVMutableComposition to contain all AVMutableComposition tracks let mix_composition = AVMutableComposition() var total_time = kCMTimeZero // Loop over videos and create tracks, keep incrementing total duration let video_track = mix_composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID()) var instruction = AVMutableVideoCompositionLayerInstruction(assetTrack: video_track) for video in videos { let shortened_duration = CMTimeSubtract(video.duration, CMTimeMake(1,10)); let videoAssetTrack = video.tracksWithMediaType(AVMediaTypeVideo)[0] do { try video_track.insertTimeRange(CMTimeRangeMake(kCMTimeZero, shortened_duration), ofTrack: videoAssetTrack , atTime: total_time) video_track.preferredTransform = videoAssetTrack.preferredTransform } catch _ { } instruction.setTransform(videoTransformForTrack(video), atTime: total_time) // Add video duration to total time total_time = CMTimeAdd(total_time, shortened_duration) } // Create main instrcution for video composition let main_instruction = AVMutableVideoCompositionInstruction() main_instruction.timeRange = CMTimeRangeMake(kCMTimeZero, total_time) main_instruction.layerInstructions = [instruction] main_composition.instructions = [main_instruction] main_composition.frameDuration = CMTimeMake(1, 30) main_composition.renderSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height) let exporter = AVAssetExportSession(asset: mix_composition, presetName: AVAssetExportPreset640x480) exporter!.outputURL = final_url exporter!.outputFileType = AVFileTypeMPEG4 exporter!.shouldOptimizeForNetworkUse = true exporter!.videoComposition = main_composition // 6 - Perform the Export exporter!.exportAsynchronouslyWithCompletionHandler() { // Assign return values based on success of export dispatch_async(dispatch_get_main_queue(), { () -> Void in self.exportDidFinish(exporter!) }) } 

Извините за длинное объяснение, я просто хотел удостовериться, что я был очень ясен с тем, что я просил, потому что другие ответы не сработали для меня.

Я не уверен, что ваша orientationFromTransform() даст вам правильную ориентацию.

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

 extension AVAsset { func videoOrientation() -> (orientation: UIInterfaceOrientation, device: AVCaptureDevicePosition) { var orientation: UIInterfaceOrientation = .Unknown var device: AVCaptureDevicePosition = .Unspecified let tracks :[AVAssetTrack] = self.tracksWithMediaType(AVMediaTypeVideo) if let videoTrack = tracks.first { let t = videoTrack.preferredTransform if (ta == 0 && tb == 1.0 && td == 0) { orientation = .Portrait if tc == 1.0 { device = .Front } else if tc == -1.0 { device = .Back } } else if (ta == 0 && tb == -1.0 && td == 0) { orientation = .PortraitUpsideDown if tc == -1.0 { device = .Front } else if tc == 1.0 { device = .Back } } else if (ta == 1.0 && tb == 0 && tc == 0) { orientation = .LandscapeRight if td == -1.0 { device = .Front } else if td == 1.0 { device = .Back } } else if (ta == -1.0 && tb == 0 && tc == 0) { orientation = .LandscapeLeft if td == 1.0 { device = .Front } else if td == -1.0 { device = .Back } } } return (orientation, device) } } 
  • Загрузите большие видео в Facebook с помощью iOS SDK
  • Размеры видео HTML5 в Safari IOS
  • Как вставить видео Youtube в мое приложение?
  • Видео Youtube не воспроизводится в ландшафтном режиме в iOS 8
  • Как перевернуть видео с помощью AVFoundation
  • отображение видео, добавление поля UIText и сохранение его на альбоме iphone
  • iOS: обрезать видео странную зеленую линию слева и внизу в видео
  • как повысить производительность поиска при использовании avplayer
  • PhoneGap iOS не может воспроизводить видео с помощью HTML 5
  • NSArray UIImages для видео ошибки имеет искажение в выходе
  • Воспроизвести видео из URL в WatchOS 2
  • Давайте будем гением компьютера.