Created
August 25, 2024 22:28
-
-
Save pardeike/02c3f07be5546ecf60a6519b3a148beb to your computer and use it in GitHub Desktop.
Stretching audio in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// from https://nonstrict.eu/blog/2023/stretching-an-audio-file-using-swift/ | |
import Foundation | |
import AVFoundation | |
func scaleAudio(inputURL: URL, toDuration targetDuration: CMTime, outputURL: URL) async throws { | |
// Load info from the input audio file | |
let inputAudioAsset = AVAsset(url: inputURL) | |
let inputAudioDuration = await inputAudioAsset.load(.duration) | |
let inputAudioTimeRange = CMTimeRange(start: .zero, duration: inputAudioDuration) | |
let inputAudioTracks = await inputAudioAsset.loadTracks(withMediaType: .audio) | |
guard let inputAudioTrack = inputAudioTracks.first else { | |
fatalError("No audio track in input file.") | |
} | |
// Create a composition with the current audio added to it on a track | |
let composition = AVMutableComposition() | |
guard let audioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) else { | |
fatalError("Failed to add mutable audio track.") | |
} | |
try audioTrack.insertTimeRange(inputAudioTimeRange, of: inputAudioTrack, at: .zero) | |
// Scale the whole composition to the target duration, this stretches the audio | |
composition.scaleTimeRange(inputAudioTimeRange, toDuration: targetDuration) | |
// Setup an export session that will write the composition to the given ouput URL | |
let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) | |
exportSession?.outputURL = outputURL | |
exportSession?.outputFileType = .m4a | |
// Do the actual export and check for completion | |
await exportSession?.export() | |
guard exportSession?.status == .completed else { | |
fatalError("Export failed, check `exportSession.error` for details.") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment