Orientation video après la fusion audio et video

J'essayais de merge un son et une video, mais quand j'enregistre la video dans ma bibliothèque, c'est la sauvegarde. Je suivais un tutoriel pour cela, mais je n'ai trouvé aucune réponse appropriée.

mais proble est la video en mode non portrait.

Alors, comment puis-je get une video avec le portrait dans ma bibliothèque ici ce que je tente

func mergeFilesWithUrl(videoUrl:NSURL, audioUrl:NSURL) { let mixComposition : AVMutableComposition = AVMutableComposition() var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = [] var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = [] let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction() //start merge let aVideoAsset : AVAsset = AVAsset(url: videoUrl as URL) let aAudioAsset : AVAsset = AVAsset(url: audioUrl as URL) mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)) mutableCompositionAudioTrack.append( mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)) let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0] do{ try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: kCMTimeZero) //In my case my audio file is longer then video file so i took videoAsset duration //instead of audioAsset duration try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero) try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), ofTrack: aAudioAssetTrack, atTime: kCMTimeZero) }catch{ } totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration ) let mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition() mutableVideoComposition.frameDuration = CMTimeMake(1, 30) mutableVideoComposition.renderSize = CGSize(width: 1280, height: 720) //find your video on this URl let savePathUrl : NSURL = NSURL(fileURLWithPath: NSHomeDirectory() + "/Documents/newVideo.mp4") let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)! assetExport.outputFileType = AVFileTypeMPEG4 assetExport.outputURL = savePathUrl as URL assetExport.shouldOptimizeForNetworkUse = true assetExport.exportAsynchronously { () -> Void in switch assetExport.status { case AVAssetExportSessionStatus.completed: //here i Store into asset library let assetsLib = ALAssetsLibrary() assetsLib.writeVideoAtPath(toSavedPhotosAlbum: savePathUrl as URL!, completionBlock: nil) print("success") case AVAssetExportSessionStatus.failed: print("failed \(Ssortingng(describing: assetExport.error))") case AVAssetExportSessionStatus.cancelled: print("cancelled \(Ssortingng(describing: assetExport.error))") default: print("complete") } } } 

Vous avez deux façons de résoudre ce problème.

PREMIÈRE MÉTHODE SANS UTILISER AVMutableVideoComposition

 let mainComposition = AVMutableComposition() let videoTrack = mainComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) let videoAssetTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first! try? videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: videoAssetTrack, at: kCMTimeZero) videoTrack.preferredTransform = videoAssetTrack.preferredTransform // THIS LINE IS IMPORTANT let audioTrack = mainComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) let audioAssetTrack = audioAsset.tracks(withMediaType: AVMediaTypeAudio).first! try? audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioAsset.duration), of: audioAssetTrack, at: kCMTimeZero) let exportSession = AVAssetExportSession(asset: mainComposition, presetName: AVAssetExportPresetHighestQuality) exportSession?.outputURL = outputURL exportSession?.outputFileType = AVFileTypeQuickTimeMovie exportSession?.shouldOptimizeForNetworkUse = true exportSession?.exportAsynchronously { } 

DEUXIÈME MÉTHODE AVEC AVMutableVideoComposition

 let mainComposition = AVMutableComposition() let videoTrack = mainComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) let videoAssetTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first! try? videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: videoAssetTrack, at: kCMTimeZero) let audioTrack = mainComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) let audioAssetTrack = audioAsset.tracks(withMediaType: AVMediaTypeAudio).first! try? audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioAsset.duration), of: audioAssetTrack, at: kCMTimeZero) let videoCompositionLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack) videoCompositionLayerInstruction.setTransform(videoAssetTrack.preferredTransform, at: kCMTimeZero) let videoCompositionInstuction = AVMutableVideoCompositionInstruction() videoCompositionInstuction.timeRange = CMTimeRangeMake(kCMTimeZero, mainComposition.duration) videoCompositionInstuction.layerInstructions = [ videoCompositionLayerInstruction ] var renderSize = videoAssetTrack.naturalSize renderSize = renderSize.applying(videoAssetTrack.preferredTransform) renderSize = CGSize(width: fabs(renderSize.width), height: fabs(renderSize.height)) let videoComposition = AVMutableVideoComposition() videoComposition.renderSize = renderSize videoComposition.frameDuration = CMTimeMake(1, 30) videoComposition.instructions = [ videoCompositionInstuction ] let exportSession = AVAssetExportSession(asset: mainComposition, presetName: AVAssetExportPresetHighestQuality) exportSession?.videoComposition = videoComposition exportSession?.outputURL = outputURL exportSession?.outputFileType = AVFileTypeQuickTimeMovie exportSession?.shouldOptimizeForNetworkUse = false exportSession?.exportAsynchronously { }