Last active
March 29, 2024 08:31
-
-
Save HomidWay/e848dc8962f97f40fb65eeb5c0697a01 to your computer and use it in GitHub Desktop.
Swift | AVPlayer, load and play multiple audio files with one player
This file contains hidden or 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
//Pass urls to files you want to play in one compossition, | |
//works with any file recognised as AVAsset and containing audio tracks, | |
//!!only first track in file will be played!! | |
func loadFiles(filesURL: [URL]) async throws -> AVPlayer{ | |
//Initialize Mutable composition | |
let composition: AVMutableComposition = .init() | |
for file in filesURL{ | |
//Add new Composition track for new file | |
guard let compositionAudioTrack: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: .audio, | |
preferredTrackID: CMPersistentTrackID()) else{ | |
throw NSError(domain: "Can't create audio track composition", code: 100) | |
} | |
//Create asset with url to file | |
let asset = AVAsset(url: file) | |
//Load audio tracks from file | |
let track = try await asset.loadTracks(withMediaType: .audio) | |
guard !track.isEmpty else{ | |
throw NSError(domain: "File \"\(file.lastPathComponent)\" doesn't contain audio tracks ", code: 100) | |
} | |
// create audio track | |
guard let audio = track.first else{ | |
throw NSError(domain: "Can't extract audio track from tracks extracted from \(file.lastPathComponent)", code: 100) | |
} | |
// create time range | |
let timeRange: CMTimeRange = .init(start: CMTimeMake(value: 0, timescale: 600), | |
duration: try await audio.load(.timeRange).duration){ | |
// Set position you want track to be inserted at in "at" parameter(seconds) | |
try compositionAudioTrack.insertTimeRange(timeRange, | |
of: audio, | |
at: CMTime(value: 0, timescale: 600)) | |
} | |
} | |
//Create PlayerItem to host prepared compositon | |
let playerItem: AVPlayerItem = .init(asset: composition) | |
//Create player with playerItem | |
let player: AVPlayer = .init(playerItem: playerItem) | |
//Return configuredPlayer | |
return player | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Not perfect, I'll add AudioMix bit later to configure volume, pan etc. later