2017-12-29 50 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() 
    } 
} 

は、私は同じようなビデオの品質を維持するために、やって、または元に少なくとも近づくことができた別のものはありますか?

あなたがラッパー・ライブラリーのうちの1つを介してffmpegのを使用することができ、ビデオの操作をより良く制御するために

答えて

関連する問題