मान लिया जाये कि हम दो वीडियो परिसंपत्तियों (AVAsset वस्तुओं) है, उन्हें खाली और मुख्य, जहां मुख्य यादृच्छिक सीमित लंबाई का एक वीडियो है कहते हैं, के 2-5 मिनट का कहना है कि करने देते हैं और खाली हमेशा होता है एक 4 दूसरा वीडियो है, हम निम्न क्रम में वीडियो मर्ज करना चाहते हैं:वीडियो के आकार को बढ़ाने के लिए AVMutableComposition का क्या कारण बन रहा है? - आईओएस, स्विफ्ट, AVFoundation
खाली - मुख्य - खाली
// Create AVMutableComposition Object.This object will hold our multiple AVMutableCompositionTrack.
let mixComposition = AVMutableComposition()
let assets = [blank, main, blank]
var totalTime : CMTime = CMTimeMake(0, 0)
var atTimeM: CMTime = CMTimeMake(0, 0)
Utils.log([blank.duration, main.duration])
// VIDEO TRACK
let videoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
for (index,asset) in assets.enumerated() {
do {
if index == 0 {
atTimeM = kCMTimeZero
} else {
atTimeM = totalTime // <-- Use the total time for all the videos seen so far.
}
try videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, asset.duration), of: asset.tracks(withMediaType: AVMediaTypeVideo)[0], at: atTimeM)
} catch let error as NSError {
Utils.log("error: \(error)")
}
totalTime = CMTimeAdd(totalTime, asset.duration)
}
// AUDIO TRACK
let audioTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
do {
try audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, main.duration), of: main.tracks(withMediaType: AVMediaTypeAudio)[0], at: blank.duration)
} catch _ {
completionHandler(nil, ErrorType(rawValue: "Unable to add audio in composition."))
return
}
let outputURL = mainVideoObject.getDirectoryURL()?.appendingPathComponent("video-with-blank.mp4")
guard let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPreset1280x720) else {
completionHandler(nil, ErrorType(rawValue: "Unable to create export session."))
return
}
let mainInstruction = AVMutableVideoCompositionInstruction()
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeAdd(blank.duration, CMTimeAdd(main.duration, blank.duration)))
// Fixing orientation
let firstLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
let firstAssetTrack = blank.tracks(withMediaType: AVMediaTypeVideo)[0]
firstLayerInstruction.setTransform(firstAssetTrack.preferredTransform, at: kCMTimeZero)
firstLayerInstruction.setOpacity(0.0, at: blank.duration)
let secondLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
let secondAssetTrack = main.tracks(withMediaType: AVMediaTypeVideo)[0]
var isSecondAssetPortrait = false
let secondTransform = secondAssetTrack.preferredTransform
if (secondTransform.a == 0 && secondTransform.b == 1.0 && secondTransform.c == -1.0 && secondTransform.d == 0) {
isSecondAssetPortrait = true
}
if (secondTransform.a == 0 && secondTransform.b == -1.0 && secondTransform.c == 1.0 && secondTransform.d == 0) {
isSecondAssetPortrait = true
}
secondLayerInstruction.setTransform(secondAssetTrack.preferredTransform, at: blank.duration)
secondLayerInstruction.setOpacity(0.0, at: CMTimeAdd(blank.duration, main.duration))
let thirdLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
let thirdAssetTrack = blank.tracks(withMediaType: AVMediaTypeVideo)[0]
thirdLayerInstruction.setTransform(thirdAssetTrack.preferredTransform, at: CMTimeAdd(blank.duration, main.duration))
mainInstruction.layerInstructions = [firstLayerInstruction, secondLayerInstruction, thirdLayerInstruction]
var naturalSize = CGSize()
if(isSecondAssetPortrait) {
naturalSize = CGSize(width: secondAssetTrack.naturalSize.height, height: secondAssetTrack.naturalSize.width)
} else {
naturalSize = secondAssetTrack.naturalSize
}
let renderWidth = naturalSize.width
let renderHeight = naturalSize.height
let mainCompositionInst = AVMutableVideoComposition()
mainCompositionInst.instructions = [mainInstruction]
mainCompositionInst.frameDuration = CMTimeMake(1, 30)
mainCompositionInst.renderSize = CGSize(width: renderWidth, height: renderHeight)
exporter.outputURL = outputURL
exporter.outputFileType = AVFileTypeMPEG4
exporter.videoComposition = mainCompositionInst
//exporter.shouldOptimizeForNetworkUse = true
exporter.exportAsynchronously {
if exporter.status == .completed {
completionHandler(AVAsset(url: outputURL!), nil)
} else {
completionHandler(nil, ErrorType(rawValue: "Unable to export video."))
if let error = exporter.error {
Utils.log("Unable to export video. \(error)")
}
}
}
Assu मिंग है कि 720 पी गुणवत्ता पर 5 मिनट के लिए मूल वीडियो रिकॉर्डर लगभग 200 एमबी स्पेस लेता है, जिसमें मुख्य वीडियो की शुरुआत और अंत में 4 एस रिक्त वीडियो को आकार में भारी रूप से बदलाव नहीं करना चाहिए, और इसे बहुत तेज़ प्रोसेसिंग करना चाहिए।
परिणाम हालांकि एक वीडियो है जो मूल वीडियो (इसलिए 400 - 500 एमबी) के आकार से 2 से 2.5x है और प्रक्रिया करने में बहुत लंबा समय लगता है।
कृपया सलाह,
धन्यवाद
तैयार किया है आप कर सकते हैं कृपया मुझे खाली वीडियो फ़ाइल जो आप के बीच में जोड़कर के लिए उपयोग किया जाता है नमूना भेजें। – MinuMaster