2017-12-29 47 views
0

기존의 (갤러리에 저장된) 비디오를 작은 청크로 트리밍합니다. 하지만 결과 비디오 품질이 너무 저하 될 찾을 :품질을 유지하면서 비디오 다듬기

var chunkNumber = 1 
let startTime = CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(600.0)) 
let theDuration = CMTime(seconds: 10.0, preferredTimescale: CMTimeScale(600.0)) 

// the AVMutableComposition holds the track instances 
let mixCompostion = AVMutableComposition() 

// video 
let videoTrack = mixCompostion.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) 
do { 
    try videoTrack?.insertTimeRange(CMTimeRangeMake(startTime, theDuration), 
      of: (asset?.tracks(withMediaType: AVMediaType.video)[0])!, at: kCMTimeZero) 
} catch { 
    print ("failed to load the video track") 
} 

// audio 
if ((asset?.tracks(withMediaType: AVMediaType.audio).count)! > 0) { 
    let audioTrack = mixCompostion.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: 0) 
    do { 
     try audioTrack?.insertTimeRange(CMTimeRangeMake(startTime, theDuration), 
       of: (asset?.tracks(withMediaType: AVMediaType.audio)[0])!, at: kCMTimeZero) 
    } catch { 
     print ("failed to load the audio track") 
    } 
} 

// layers 
let parentLayer = CALayer() 
let videoLayer = CALayer() 
let layerFrame = CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) 
parentLayer.frame = layerFrame 
videoLayer.frame = layerFrame 
parentLayer.addSublayer(videoLayer) 

// master instruction wraps entire set of instructions 
let masterInstruction = AVMutableVideoCompositionInstruction() 
masterInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, theDuration) 
let videoLayerInstruction = videoCompositionInstructionForTrack(track: videoTrack!, asset: asset!) 

// add instructions to master, prepare composition 
masterInstruction.layerInstructions = [videoLayerInstruction] 
let mainComposition = AVMutableVideoComposition() 
mainComposition.instructions = [masterInstruction] 
mainComposition.frameDuration = CMTimeMake(1, 30) 
mainComposition.renderSize = CGSize(width: mainCompositionWidth, height: mainCompositionHeight) 
mainComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer) 

// get path 
let date = Date() 
let savePath = (documentDirectory as NSString).appendingPathComponent("\(date)-\(chunkNumber).mov") 
let url = URL(fileURLWithPath: savePath) 
chunkNumber += 1 

// create exporter 
guard let exporter = AVAssetExportSession(asset: mixCompostion, presetName: AVAssetExportPresetHighestQuality) else { return } 
exporter.outputURL = url 
exporter.outputFileType = AVFileType.mov 
exporter.shouldOptimizeForNetworkUse = true 
exporter.videoComposition = mainComposition 

// export 
exporter.exportAsynchronously(completionHandler: {() -> Void in 
    DispatchQueue.global().async { 
     self.exportDidFinish(session: exporter) 
    } 
}) 

func exportDidFinish(session: AVAssetExportSession) { 
    if session.status == AVAssetExportSessionStatus.completed { 
     PHPhotoLibrary.shared().performChanges({ 
      _ = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: session.outputURL!) 
     }, completionHandler: { (success, error) in 
      let completionString = success ? "Success." : error?.localizedDescription 
      print ("Finished updating asset: \(String(describing: completionString))") 
     }) 
    } 
    else if session.status == AVAssetExportSessionStatus.failed { 
     print ("Export failed -> Reason: \(String(describing: session.error))") 
     delegate?.exportFailed() 
    } 
} 

내가 일을 할 수있는 다른 아무것도, 동일로 비디오의 품질을 유지하기 위해 거기 또는 원래 적어도 가까운? 랩퍼 라이브러리 중 하나를 통해는 FFmpeg를 사용할 수있는 비디오 조작보다 나은 제어를 들어

답변

관련 문제