Код: Выделить всё
import Foundation
import AVFoundation
enum AudioExtractorError: Error {
case noAudio
case bufferAllocationFailed
}
@available(macOS 26.0, iOS 26.0, *)
class AudioExtractor {
init(fileURL: URL) {
self.fileURL = fileURL
}
func extractAudio(from fileURL: URL, to outputFolder: URL) async throws -> URL {
let asset = AVAsset(url: fileURL)
guard let audioTrack = try await asset.loadTracks(withMediaType: .audio).first else {
throw AudioExtractorError.noAudio
}
let reader = try AVAssetReader(asset: asset)
let outputSettings: [String: Any] = [
AVFormatIDKey: kAudioFormatLinearPCM,
AVLinearPCMIsBigEndianKey: false,
AVLinearPCMBitDepthKey: 32,
AVLinearPCMIsFloatKey: true,
AVLinearPCMIsNonInterleaved: false,
AVNumberOfChannelsKey: 2
]
let trackOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: outputSettings)
let outputProvider = reader.outputProvider(for: trackOutput)
try reader.start()
let outputURL = outputFolder
.appendingPathComponent(UUID().uuidString)
.appendingPathExtension("caf")
let outputFile = try AVAudioFile(forWriting: outputURL, settings: outputSettings)
while let sampleBuffer = try await outputProvider.next() {
guard case let CMSampleBuffer.DynamicContent.dataBuffer(blockBuffer) = sampleBuffer.content else {
continue
}
let blockSampleBuffer = CMReadySampleBuffer(dataBuffer: blockBuffer,
formatDescription: sampleBuffer.formatDescription!,
sampleProperties: sampleBuffer.sampleProperties)
guard let pcmBuffer = AVAudioPCMBuffer(pcmFormat: outputFile.processingFormat, frameCapacity: AVAudioFrameCount(sampleBuffer.sampleCount)) else {
throw AudioExtractorError.bufferAllocationFailed
}
try blockSampleBuffer.copyPCMData(fromRange: 0..
Подробнее здесь: [url]https://stackoverflow.com/questions/79843349/cmreadysamplebuffer-copypcmdata-fails-with-12731-kcmsamplebuffererror-requir[/url]