Here\'s the code:
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
Usually green lines appear after video cropping, problem is in video renderSize width, it should be multiply of 16.
Here some links about this: apple 1 apple 2
This did the magic for me (iOS9, Swift 3, iPhone 6):
Based on: https://www.raywenderlich.com/94404/play-record-merge-videos-ios-swift
Changing mainComposition.renderSize to:
mainComposition.renderSize = CGSize(width: self.mainCompositionWidth, height: self.mainCompositionHeight)
where mainCompositionWidth, mainCompositionHeight are CGFloats and are calculated like this:
self.mainCompositionWidth = UIScreen.mainScreen().bounds.width
self.mainCompositionHeight = UIScreen.mainScreen().bounds.height
while (self.mainCompositionWidth%16>0) { // find the right resolution that can be divided by 16
self.mainCompositionWidth = self.mainCompositionWidth + 1.0
}
while (self.mainCompositionHeight%16>0) { // find the right resolution that can be divided by 16
self.mainCompositionHeight = self.mainCompositionHeight + 1.0
}
Also modifying scaleFitRatio in the videoCompositionInstructionForTrack function to:
scaleToFitRatio = self.mainCompositionWidth / assetTrack.naturalSize.height
This made the bottom green line disappear and the video fills the screen.
Turns out that if AVMutableVideoComposition's render size width isn't an even number, you get the mysterious green borders. Good times.
a much nicer solution to get the multiple of 16 would be this approach:
floor(width / 16) * 16
or
ceil(width / 16) * 16
depending on your preference of having a smaller or bigger width
In order to get the proper resolution try something like this... increment it until the nearest number that can be divided by 16:
computedVideoSize=self.view.frame.size.width;
while (computedVideoSize%16>0) { // find the right resolution that can be divided by 16
computedVideoSize++;
}