The keyboard extension I built uses audio files to play audio feedback when keys are pressed. At some point, the user has an ability to combine multiple audio files into a single audio file. Combining multiple audio files works in simulator but does not work on the device.
func createSound(myNotes: [String], outputFile: String) {
// CMTime struct represents a length of time that is stored as rational number
var startTime: CMTime = kCMTimeZero
// AVMutableComposition creates new composition
let composition: AVMutableComposition = AVMutableComposition()
// AVMutableCompositionTrack - A mutable track in composition that you use to insert, remove, and scale track segments
if let compositionAudioTrack: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid) {
for url in allFilesForCharacters() {
let avAsset: AVURLAsset = AVURLAsset(url: url)
let timeRange: CMTimeRange = CMTimeRangeMake(kCMTimeZero, avAsset.duration)
let audioTrack: AVAssetTrack = avAsset.tracks(withMediaType: AVMediaType.audio)[0]
try! compositionAudioTrack.insertTimeRange(timeRange, of: audioTrack, at: startTime)
startTime = CMTimeAdd(startTime, timeRange.duration)
}
}
let exportPath: String = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].path+"/"+outputFile+".m4a"
try? FileManager.default.removeItem(atPath: exportPath)
if let export: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) {
export.outputURL = URL(fileURLWithPath: exportPath)
export.outputFileType = AVFileType.m4a
export.exportAsynchronously {
if export.status == AVAssetExportSessionStatus.completed {
NSLog("All done");
if let data = try? Data(contentsOf: export.outputURL!) {
let board = UIPasteboard.general
board.setData(data, forPasteboardType: kUTTypeMPEG4Audio as String)
}
}
else {
print(export.error?.localizedDescription ?? "")
}
}
}
}