我希望以 44100 Hz 录制的音频以 16000 采样率下采样,但代码不起作用,在 React Native 应用程序中使用 swift 本机代码
@objc func startRecording() {
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playAndRecord, mode: .default, options: [])
try session.setActive(true)
let fileName = "recording.wav"
let cacheDirectory = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
let filePath = cacheDirectory.appending("/\(fileName)")
audioFileURL = URL(fileURLWithPath: filePath)
let settings: [String: Any] = [
AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey: 44100.0,
AVNumberOfChannelsKey: 1,
AVLinearPCMBitDepthKey: 16,
AVLinearPCMIsFloatKey: false,
AVLinearPCMIsBigEndianKey: false,
]
audioRecorder = try AVAudioRecorder(url: audioFileURL!, settings: settings)
audioRecorder?.record()
//callback([NSNull()])
} catch {
//callback(["Failed to start recording"])
}
}
// @objc func stopRecording(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock)
@objc func stopRecording()
{
if let recorder = audioRecorder, recorder.isRecording {
recorder.stop()
let cacheDirectory = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
let sourceFilePath = cacheDirectory.appending("/recording.wav") // The path of the recorded audio file at 44100 sample rate
let destinationFilePath = cacheDirectory.appending("/downsampled_recording.wav") // The path where you want to save the downsampled audio file
print(destinationFilePath)
downsampleAudio(from: sourceFilePath, to: destinationFilePath)
//callback([NSNull()])
} else {
//callback(["No active recording"])
}
}
func downsampleAudio(from sourcePath: String, to destinationPath: String) {
let sourceURL = URL(fileURLWithPath: sourcePath)
let destinationURL = URL(fileURLWithPath: destinationPath)
let sourceAsset = AVURLAsset(url: sourceURL)
let audioSettings: [String: Any] = [
AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey: 16000,
AVNumberOfChannelsKey: 1,
AVLinearPCMBitDepthKey: 16,
AVLinearPCMIsFloatKey: false,
AVLinearPCMIsBigEndianKey: false,
AVLinearPCMIsNonInterleaved: false,
]
do {
let audioAssetReader = try AVAssetReader(asset: sourceAsset)
let audioAssetTrack = sourceAsset.tracks(withMediaType: .audio).first!
let audioAssetOutput = AVAssetReaderTrackOutput(track: audioAssetTrack, outputSettings: nil)
audioAssetReader.add(audioAssetOutput)
let audioAssetWriter = try AVAssetWriter(outputURL: destinationURL, fileType: .wav)
let audioAssetInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioSettings)
audioAssetWriter.add(audioAssetInput)
audioAssetWriter.startWriting()
audioAssetReader.startReading()
audioAssetWriter.startSession(atSourceTime: .zero)
let mediaInputQueue = DispatchQueue(label: "mediaInputQueue")
audioAssetInput.requestMediaDataWhenReady(on: mediaInputQueue) {
while audioAssetInput.isReadyForMoreMediaData {
if let sampleBuffer = audioAssetOutput.copyNextSampleBuffer() {
audioAssetInput.append(sampleBuffer)
} else {
audioAssetInput.markAsFinished()
audioAssetWriter.finishWriting {
if audioAssetWriter.status == .completed {
print("Audio downsampling completed.")
} else {
print("Error while downsampling audio: \(audioAssetWriter.error?.localizedDescription ?? "Unknown error")")
}
}
break
}
}
}
} catch {
print("Error while preparing audio for downsampling: \(error.localizedDescription)")
}
}
我对iOS开发一无所知,但该项目需要原生模块和16000采样率的音频,因此任何人都可以帮助解决这个问题。
当前应用程序崩溃,输出如下:
由于未捕获的异常而终止应用程序 'NSInternalInconsistencyException',原因:'*** -[AVAssetReaderTrackOutput copyNextSampleBuffer] 在将此输出添加到实例之前无法复制下一个样本缓冲区 AVAssetReader (使用 -addOutput:) 并调用 -startReading 资产阅读器'
我尝试了各种功能,但都不起作用,附加了录制音频的整个文件:文件链接
预期结果是音频可以被覆盖为录制时保存的 44100Hz 文件,或者返回音频下采样缓冲区以反应本机端。