I have several audio clips that I recorded with an AVAudioRecorder over a video. Using a AVMutableComposition I want to merge the audio assets with the video at the times the audio was recorded. For eg, the video is 1 minute long, I recorded 3 audio clips at 5-10secs, 20-25secs, and 30-35secs. The audio clips should be merged with the video at those specific time frames. When the final video plays the audio would play over the video at those time frames.
model:
class AudioModel {
var audioUrl: URL?
var startTime: Double?
var endTime: Double?
}
mix:
let mixComposition = AVMutableComposition()
guard let videoCompositionTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else { return }
guard let audioFromVideoCompositionTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else { return }
guard let audioModelCompositionTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else { return }
let videoAsset = AVURLAsset(url: videoURL)
guard let videoTrack = videoAsset.tracks(withMediaType: .video).first else { return }
for audioModel in audioModels {
let audioAsset = AVURLAsset(url: audioModel.url!)
let startTime = CMTime(seconds: audioModel.startTime!, preferredTimescale: 1000)
do {
try videoCompositionTrack.insertTimeRange(CMTimeRangeMake(start: .zero, duration: videoAsset.duration), of: videoTrack, at: .zero)
if let audioTrackFromAudioModel = audioAsset.tracks(withMediaType: .audio).first {
try audioModelCompositionTrack.insertTimeRange(CMTimeRangeMake(start: startTime, duration: audioAsset.duration),
of: audioTrackFromAudioModel, at: .zero)
}
if let audioFromVideoTrack = videoAsset.tracks(withMediaType: .audio).first {
try audioFromVideoCompositionTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration),
of: audioFromVideoTrack, at: .zero)
}
} catch {
}
}
let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
// ... I know what to do from here