2017-12-29 46 views
0

Ich trimme ein vorhandenes (in der Galerie gespeichertes) Video in kleinere Stücke; aber ich finde die resultierende Videoqualität zu abgebaut werden:Trimmen eines Videos bei gleichbleibender Qualität

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() 
    } 
} 

Gibt es etwas anders, ich könnte, tun die Qualität des Videos als gleich zu halten oder zumindest näher an das Original?

Antwort

0

Für eine bessere Kontrolle über die Videomanipulation Sie ffmpeg über einen der Wrapper-Bibliotheken verwenden könnte - siehe diese Links zum Beispiel:

Ich habe nicht ein gebrauchter die iOS, aber ich habe das gleiche auf Android gemacht und es funktioniert gut, mit der üblichen Einschränkung, dass die Videoverarbeitung auf mobilen Geräten langsam ist.

Verwandte Themen