iOS React Native 中的音频采样率从 44100 降采样到 16000

问题描述 投票:0回答:0

我希望以 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 文件,或者返回音频下采样缓冲区以反应本机端。

ios swift react-native audio avfoundation
© www.soinside.com 2019 - 2024. All rights reserved.