Ich mache Video von einem Array von UIImages. Ich tat das erfolgreich & alle Bilder werden auf dem Video gezeigt. Ich verwende AVAssetExportSession, um das Video zu exportieren, das auch funktioniert, außer wenn ich AVAssetExportSession videoComposition -Eigenschaft verwende, zeigt das Video nur das erste Bild an. Hier ist mein Code:AVAssetExportSession videoComposition zeigt nicht alle Frames im Video
func mergeAudioVideoFiles(videoUrl:NSURL, audioUrl:NSURL)->NSURL
{
let mixComposition : AVMutableComposition = AVMutableComposition()
var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = []
var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = []
let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
//start merge
let aVideoAsset : AVAsset = AVAsset(URL: videoUrl)
let aAudioAsset : AVAsset = AVAsset(URL: audioUrl)
mutableCompositionVideoTrack.append(mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
mutableCompositionAudioTrack.append(mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracksWithMediaType(AVMediaTypeAudio)[0]
do{
try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), ofTrack: aVideoAssetTrack, atTime: kCMTimeZero)
try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), ofTrack: aAudioAssetTrack, atTime: kCMTimeZero)
}catch{
}
print("\nslide duraition:\(CMTimeGetSeconds(aVideoAssetTrack.timeRange.duration))\n")
totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration)
let mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition(propertiesOfAsset: aVideoAsset)
mutableVideoComposition.frameDuration = aVideoAssetTrack.timeRange.duration
mutableVideoComposition.renderSize = CGSizeMake(1280,720)
//find your video on this URl
let savePathUrl : NSURL = NSURL(fileURLWithPath: documentsPath.stringByAppendingPathComponent("pandorarofinalist.mov"))
// 4. Add subtitles (we call it theme)
let insertTime = kCMTimeZero
//let endTime = aVideoAssetTrack.timeRange.duration
//let range = self.totalFrameDuration
//let themeVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition(propertiesOfAsset: aVideoAsset)
// 4.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation.
let videolayerInstruction : AVMutableVideoCompositionLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: aVideoAssetTrack)
totalVideoCompositionInstruction.layerInstructions = NSArray(array: [videolayerInstruction]) as! [AVVideoCompositionLayerInstruction]
mutableVideoComposition.instructions = NSArray(array: [totalVideoCompositionInstruction]) as! [AVVideoCompositionInstructionProtocol]
//mutableCompositionAudioTrack[0].preferredTransform
videolayerInstruction.setTransform(mutableCompositionVideoTrack[0].preferredTransform, atTime: insertTime)
//videolayerInstruction.setOpacity(0.0, atTime: endTime)
// 4.3 - Add instructions
// mutableVideoComposition.renderScale = 1.0
//themeVideoComposition.renderSize = CGSizeMake(aVideoAssetTrack.naturalSize.width, aVideoAssetTrack.naturalSize.height)
//themeVideoComposition.frameDuration = self.totalFrameDuration
// add text
let title = String("my video")
let titleLayer = CATextLayer()
titleLayer.string = title
titleLayer.frame = CGRect(x: 0, y: 0, width: aVideoAssetTrack.naturalSize.width, height: 100)
let fontName: CFStringRef = "Helvetica-Bold"
let fontSize = CGFloat(50)
titleLayer.font = CTFontCreateWithName(fontName, fontSize, nil)
titleLayer.alignmentMode = kCAAlignmentCenter
titleLayer.foregroundColor = UIColor.orangeColor().CGColor
let backgroundLayer = CALayer()
backgroundLayer.frame = CGRect(x: 0, y: 0, width: aVideoAssetTrack.naturalSize.width, height: aVideoAssetTrack.naturalSize.height)
backgroundLayer.masksToBounds = true
backgroundLayer.addSublayer(titleLayer)
// 2. set parent layer and video layer
let parentLayer = CALayer()
let videoLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: aVideoAssetTrack.naturalSize.width, height: aVideoAssetTrack.naturalSize.height)
videoLayer.frame = CGRect(x: 0, y: 0, width: aVideoAssetTrack.naturalSize.width, height: aVideoAssetTrack.naturalSize.height)
parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(backgroundLayer)
//backgroundLayer.opacity = 1.0
// 3. make animation
mutableVideoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)
// Remove the file if it already exists (merger does not overwrite)
do{
let fileManager = NSFileManager.defaultManager()
try fileManager.removeItemAtURL(savePathUrl)
}catch{
}
let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
assetExport.outputFileType = AVFileTypeMPEG4
assetExport.outputURL = savePathUrl
assetExport.shouldOptimizeForNetworkUse = true
assetExport.videoComposition = mutableVideoComposition
assetExport.exportAsynchronouslyWithCompletionHandler {() -> Void in
switch assetExport.status {
case AVAssetExportSessionStatus.Completed:
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(savePathUrl)
}) { success, error in
if !success {
print("Error saving video: \(error)")
}
}
//Uncomment this if u want to store your video in asset
//let assetsLib = ALAssetsLibrary()
//assetsLib.writeVideoAtPathToSavedPhotosAlbum(savePathUrl, completionBlock: nil)
print("success")
case AVAssetExportSessionStatus.Failed:
print("failed \(assetExport.error)")
case AVAssetExportSessionStatus.Cancelled:
print("cancelled \(assetExport.error)")
default:
print("complete")
}
}
return savePathUrl
}
Das Problem ist, dass Zeile assetExport.videoComposition = mutableVideoComposition Wenn ich diese Zeile der Ausgabe Video auslassen ist gut so. Aber wenn ich diese Zeile hinzufüge, zeigt das Ausgabevideo nur das erste Bild, das ich für das Video hinzugefügt habe. Ich muss videoComposition einstellen, weil ich Titeltext dem Video hinzufüge, das ich als CALayer hinzugefügt habe. Ich verwende swift 2.2 für mein Projekt. Irgendwelche Hilfe bitte? Danke im Voraus.
Haben Sie eine Lösung gefunden? – Sam
Dies ist ein Fehler mit AVVideoCompositionCoreAnimationTool Bitte überprüfen Sie diesen Beitrag und alle damit verbundenen Beiträge http://StackOverflow.com/search?Tab=Newest&q=Swift%20AVAssetWriter – Sam
Allerdings habe ich es nicht geschafft, eine Lösung zu implementieren – Sam