2017-05-09 2 views
11

비디오 (녹음 후)에 일부 애니메이션을 실행하고 내보내려고합니다. 하지만 애니메이션 전에는 풍경이 된 방향에 문제가있었습니다 (세로 방향으로 내보내기없이) 해결되었지만 이제는 전체 화면을 만드는 데 문제가 있습니다. 아이폰 6,7과 전체 화면 방법 ipad 그렇지 않습니다. 내 문제는 스케일 팩터 번역 된 금액을 변경 한 고정 된 어떤AVAssetExportSession을 사용하여 전체 화면으로 비디오 내보내기

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

'AVAssetExportPreset' 이외의 다른 사전 설정을 시도 했습니까? – Bluewings

+1

나는 그것이 당신의'layercomposition.renderSize'와 관련이 있다고 생각하고 있습니다. 당신이 현재보기를 위해 그것을 설정하고 있습니다. 그래서 이것을 전화로 실행한다면, 출력 비디오는 iPad에서 더 작아 질 것입니다. renderSize를 원본 비디오의 크기로 설정할 수 있습니까? 그 트릭을 할 수도 있습니다. – Chris

+1

어쩌면이 비율이 높이/너비로 계산되는 비율입니다. let ratio = size.height/videoTrack.naturalSize.width – xxtesaxx

답변

0

:

여기 내 방법입니다. 여기에 코드가 있습니다 :

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

의 계산과 함께 했습니까? exportTransform을 어디에 연결 했습니까? – Markinson

관련 문제