2017-05-09 1 views
11

Ich versuche, ein Video (nach der Aufnahme) einige Animationen zu machen und dann exportieren. aber vor jeder Animation hatte ich das Problem mit der Ausrichtung, die Landschaft wurde (ohne Export war es Porträt) und es ist nicht gelöst, aber jetzt habe ich ein Problem mit der Vollbild zu machen.in iPhone 6,7 plus seinen Vollbild wie immer in ipad ist es nicht.Exportieren von Video im Vollbild mit AVAssetExportSession

hier ist meine Methode:

func export(_ url : URL) { 
    let composition = AVMutableComposition() 
    let asset = AVURLAsset(url: url, options: nil) 

    let track = asset.tracks(withMediaType : AVMediaTypeVideo) 
    let videoTrack:AVAssetTrack = track[0] as AVAssetTrack 
    let timerange = CMTimeRangeMake(kCMTimeZero, asset.duration) 

    let compositionVideoTrack:AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID()) 

    do { 
     try compositionVideoTrack.insertTimeRange(timerange, of: videoTrack, at: kCMTimeZero) 
    } catch { 
     print(error) 
    } 

    let compositionAudioTrack:AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID()) 

    for audioTrack in asset.tracks(withMediaType: AVMediaTypeAudio) { 
     do { 
      try compositionAudioTrack.insertTimeRange(audioTrack.timeRange, of: audioTrack, at: kCMTimeZero) 
     } catch { 
      print(error) 
     } 

    } 

    let size = self.view.bounds.size 

    let videolayer = CALayer() 
    videolayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) 

    let parentlayer = CALayer() 
    parentlayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) 
    parentlayer.addSublayer(videolayer) 

    let layercomposition = AVMutableVideoComposition() 
    layercomposition.frameDuration = CMTimeMake(1, 30) 
    layercomposition.renderSize = self.view.bounds.size 
    layercomposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videolayer, in: parentlayer) 

    let instruction = AVMutableVideoCompositionInstruction() 

    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration) 

    let videotrack = composition.tracks(withMediaType: AVMediaTypeVideo)[0] as AVAssetTrack 
    let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videotrack) 


    let ratio = size.height/videoTrack.naturalSize.width 

    composition.naturalSize = videoTrack.naturalSize 

    layerinstruction.setTransform(videoTrack.preferredTransform.scaledBy(x: 0.645 , y: ratio).translatedBy(x: self.view.bounds.height, y: 0), at: kCMTimeZero) 

    instruction.layerInstructions = [layerinstruction] 
    layercomposition.instructions = [instruction] 

    let filePath = self.fileName() 
    let movieUrl = URL(fileURLWithPath: filePath) 

    guard let assetExport = AVAssetExportSession(asset: composition, presetName:AVAssetExportPresetHighestQuality) else {return} 
    assetExport.videoComposition = layercomposition 
    assetExport.outputFileType = AVFileTypeMPEG4 
    assetExport.outputURL = movieUrl 
    assetExport.exportAsynchronously(completionHandler: { 
     switch assetExport.status { 
     case .completed: 
      print("success") 
      let player = AVPlayer(url: movieUrl) 
      let playerViewController = AVPlayerViewController() 
      playerViewController.player = player 
      self.present(playerViewController, animated: true) { 
       playerViewController.player!.play() 
      } 
      break 
     case .cancelled: 
      print("cancelled") 
      break 
     case .exporting: 
      print("exporting") 
      break 
     case .failed: 
      print("failed: \(String(describing: assetExport.error))") 
      break 
     case .unknown: 
      print("unknown") 
      break 
     case .waiting: 
      print("waiting") 
      break 
     } 
    }) 
} 
+1

Haben Sie ein anderes Preset als 'AVAssetExportPreset' versucht? – Bluewings

+1

Ich denke, es hat etwas mit Ihrer 'layercomposition.renderSize' zu ​​tun, die Sie für die aktuelle Ansicht einstellen. Wenn Sie dies auf einem Telefon ausführen, wird das Ausgabevideo auf dem iPad kleiner. Kannst du die renderSize auf die Größe des Originalvideos einstellen? Das könnte den Trick machen. – Chris

+1

vielleicht dieser, wo die Verhältnisse von Höhe/Breite berechnet wird: lassen Ratio = size.height/videoTrack.naturalSize.width – xxtesaxx

Antwort

0

was mein Problem behoben wurde den Skalierungsfaktor zu ändern und den übersetzten Betrag. Hier ist der folgende Code:

let size = self.view.bounds.size 
    let trackTransform = videoTrack.preferredTransform 
    let xScale = size.height/videoTrack.naturalSize.width 
    let yScale = size.width/videoTrack.naturalSize.height 


    let exportTransform = videoTrack.preferredTransform.translatedBy(x: trackTransform.ty * -1 , y: 0).scaledBy(x: xScale , y: yScale) 
+0

wo hast du exportTransform? – Markinson

Verwandte Themen