Search code examples
iosswiftavfoundationavassetavmutablecomposition

Merge multiple video assets with correct orientation swift


I am simply trying to stitch together (merge) an array of videos (with correct original orientations), and it works HOWEVER with incorrect orientation of some videos. For example with the current preferredTransform, front facing videos are inverted (i.e. if you filmed a video with your hand on the left, it will now be on the right..) while back camera videos are as they were originally.

I have tried looking at so many questions on this, but none seem to fix the issue. I just need the videos to keep their original orientation!

func merge(arrayVideos:[AVAsset], completion:@escaping (URL?, Error?) -> ()) {


          let mainComposition = AVMutableComposition()
          let compositionVideoTrack = mainComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
  compositionVideoTrack?.preferredTransform = CGAffineTransform(rotationAngle: (.pi)/2) 

          let soundtrackTrack = mainComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)

            var insertTime = CMTime.zero

          for videoAsset in arrayVideos {
            try! compositionVideoTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: .video)[0], at: insertTime)
            try! soundtrackTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: .audio)[0], at: insertTime)

            insertTime = CMTimeAdd(insertTime, videoAsset.duration)
          }

          let outputFileURL = URL(fileURLWithPath: NSTemporaryDirectory() + "merge.mp4")

          let fileManager = FileManager()
          try? fileManager.removeItem(at: outputFileURL)

          let exporter = AVAssetExportSession(asset: mainComposition, presetName: AVAssetExportPresetHighestQuality)

          exporter?.outputURL = outputFileURL
          exporter?.outputFileType = AVFileType.mp4
          exporter?.shouldOptimizeForNetworkUse = true

          exporter?.exportAsynchronously {
            if let url = exporter?.outputURL{
                completion(url, nil)
            }
            if let error = exporter?.error {
                completion(nil, error)
            }
          }
        }

Solution

  • I solved the issue!!

    Refer to my answer here:

    How to correctly orient multiple video tracks (taken on front facing cam and back facing), before merging or during?