2015-12-10 16 views
10

का उपयोग कर मैं सामने का सामना करना पड़ कैमरे के साथ एक वीडियो रिकॉर्ड किया गया है और उत्पादन नजर आता है एक वीडियो फ्लिप कैसे ...AVFoundation

मैं वीडियो है, लेकिन कोई किस्मत फ्लिप करने AVMutablecomposition और layerinstructions का उपयोग कर की कोशिश की है।

गुगलिंग और खोज स्टैक ओवरफ़्लो निष्फल रहा है, इसलिए मैं यह कैसे करना है, यह एक सरल, सीधा आगे उदाहरण है जो कई लोगों को लाभ पहुंचाएगा।

+0

बदलना आप AVCaptureConnection उपयोग कर रहे हैं रिकॉर्ड करने के लिए मिलता है, मैं इस समस्या को ठीक करता हूँ वहाँ, का उपयोग करते हुए वीडियो अभिविन्यास की स्थापना द्वारा 'setVideoOrientation' – Lefteris

उत्तर

13

थेरेस क्या आप वीडियो रिकॉर्ड करने का उपयोग कर रहे पर कोई संकेत नहीं है, बीमार मान AVCaptureSession + AVCaptureVideoDataOutput

lazy var videoFileOutput: AVCaptureVideoDataOutput = AVCaptureVideoDataOutput() 
let v = videoFileOutput.connectionWithMediaType(AVMediaTypeVideo) 
v.videoOrientation = .Portrait 
v.videoMirrored = true 
7

आप -[AVMutableVideoCompositionLayerInstruction setTransform:atTime:]

CGAffineTransform transform = CGAffineTransformMakeTranslation(self.config.videoSize, 0); 
transform = CGAffineTransformScale(transform, -1.0, 1.0); 
[videoCompositionLayerInstruction setTransform:transform atTime:videoTime]; 

// then append video tracks 
// [compositionTrack insertTimeRange:timeRange ofTrack:track atTime:atTime error:&error]; 

// apply instructions 
videoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration); 
videoCompositionInstruction.layerInstructions = @[videoCompositionLayerInstruction]; 

videoComposition = [AVMutableVideoComposition videoComposition]; 
videoComposition.renderSize = CGSizeMake(self.config.videoSize, self.config.videoSize); 
videoComposition.frameDuration = CMTimeMake(1, self.config.videoFrameRate); 
videoComposition.instructions = @[videoCompositionInstruction]; 

https://github.com/ElfSundae/AVDemo/tree/ef2ca437d0d8dcb3dd41c5a272c8754a29d8a936/AVSimpleEditoriOS

निर्यात रचना का उपयोग कर सकते हैं:

AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:presetName]; 
exportSession.outputFileType = AVFileTypeMPEG4; 
exportSession.outputURL = outputURL; 
exportSession.shouldOptimizeForNetworkUse = YES; 
// videoComposition contains transform instructions for video tracks 
exportSession.videoComposition = videoComposition; 
// audioMix contains background music for audio tracks 
exportSession.audioMix = audioMix; 

[exportSession exportAsynchronouslyWithCompletionHandler:^{ 
    AVAssetExportSessionStatus status = exportSession.status; 
    if (status != AVAssetExportSessionStatusCompleted) { 
     // exportSession.error 
    } else { 
     // exportSession.outputURL 
    } 
}]; 
+0

अपने उदाहरण के लिए धन्यवाद - और आप इस रचना को एक वीडियो में कैसे निर्यात करेंगे? – PinkFloydRocks

+0

@PinkFloydRocks मैं AVAssetExportSession का उपयोग करता हूं, उत्तर अपडेट किया गया है। –

+0

CGAffineTransformMakeTranslation (self.config.videoSize, 0); । इसे एक CGFloat मान की आवश्यकता है, CGGize मान नहीं। यह नहीं पता कि आपको यह कोड कैसे काम करने और इसे पोस्ट करने के लिए मिला है। –

0

के बाद आप अपने उत्पादन अपने वीडियो

func mirrorVideo(inputURL: URL, completion: @escaping (_ outputURL : URL?) ->()) 
{ 
    let videoAsset: AVAsset = AVAsset(url: inputURL) 
    let clipVideoTrack = videoAsset.tracks(withMediaType: AVMediaType.video).first! as AVAssetTrack 

    let composition = AVMutableComposition() 
    composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: CMPersistentTrackID()) 

    let videoComposition = AVMutableVideoComposition() 
    videoComposition.renderSize = CGSize(width: clipVideoTrack.naturalSize.height, height: clipVideoTrack.naturalSize.width) 
    videoComposition.frameDuration = CMTimeMake(1, 30) 

    let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack) 

    let instruction = AVMutableVideoCompositionInstruction() 
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30)) 
    var transform:CGAffineTransform = CGAffineTransform(scaleX: -1.0, y: 1.0) 
    transform = transform.translatedBy(x: -clipVideoTrack.naturalSize.width, y: 0.0) 
    transform = transform.rotated(by: CGFloat(Double.pi/2)) 
    transform = transform.translatedBy(x: 0.0, y: -clipVideoTrack.naturalSize.width) 

    transformer.setTransform(transform, at: kCMTimeZero) 

    instruction.layerInstructions = [transformer] 
    videoComposition.instructions = [instruction] 

    // Export 

    let exportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPreset640x480)! 
    let fileName = UniqueIDGenerator.generate().appending(".mp4") 
    let filePath = documentsURL.appendingPathComponent(fileName) 
    let croppedOutputFileUrl = filePath 
    exportSession.outputURL = croppedOutputFileUrl 
    exportSession.outputFileType = AVFileType.mp4 
    exportSession.videoComposition = videoComposition 
    exportSession.exportAsynchronously { 
     if exportSession.status == .completed { 
      DispatchQueue.main.async(execute: { 
       completion(croppedOutputFileUrl) 
      }) 
      return 
     } else if exportSession.status == .failed { 
      print("Export failed - \(String(describing: exportSession.error))") 
     } 

     completion(nil) 
     return 
    } 
} 
संबंधित मुद्दे