我尝试将音频导出为 .band 文件,但 GarageBand 表示文件已损坏或格式不正确
func copyAudioFileToDocuments(ringtone: Ringtone?) async throws -> URL? {
guard let ringtone, let documentsURL = ringtone.url else { return nil }
let asset = AVURLAsset(url: documentsURL)
let exportAudioMix = AVMutableAudioMix()
guard let track = try await asset.load(.tracks).last else { return nil }
let start = ringtone.info.startTime
let length = ringtone.info.endTime - ringtone.info.startTime
let exportTimeRange = CMTimeRange(start: .init(seconds: start, preferredTimescale: 1),
duration: .init(seconds: length, preferredTimescale: 1))
let destinationURL = Constants.cachesDirectory.appendingPathComponent(ringtone.id.replacingOccurrences(of: ringtone.info.title.ext.rawValue, with: "band"))
try await exportAudio(from: track, mix: exportAudioMix, exportTimeRange: exportTimeRange, to: destinationURL)
return destinationURL
}
------------------->
func exportAudio(from track: AVAssetTrack, mix: AVAudioMix? = nil, exportTimeRange: CMTimeRange? = nil, to destinationURL: URL) async throws {
let composition = AVMutableComposition()
let compositionAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
let duration = try await track.asset?.load(.duration)
try compositionAudioTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: duration ?? .init()), of: track, at: .zero)
let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)
if let exportTimeRange { exportSession?.timeRange = exportTimeRange }
exportSession?.outputURL = destinationURL
exportSession?.audioMix = mix
exportSession?.outputFileType = AVFileType.aiff
if FileManager.default.fileExists(atPath: destinationURL.path) {
try FileManager.default.removeItem(at: destinationURL)
}
try await exportSession?.exportAsync()
}
我尝试使用 .mp3 扩展名,一切正常,但使用 .band 则无法正常工作。
.band 文件实际上并不是声音文件。它根本不是一个文件。它是(正如您在评论中已经被告知的那样)一个包,即伪装成文件的文件夹;该文件夹内是整个 GarageBand 项目。如何正确构建文件夹的内容取决于you; AVAssetExportSession 不会神奇地为您制作一个。