😺

Audiomasterロードマップ ~収録編~

2022/05/06に公開

この記事は?

AudioMasterロードマップの再生編です。
AudioMasterというライブラリを作成するまでにやることをまとめているものです。

https://zenn.dev/entaku/articles/725253883f1699

AVAudioRecorder

AVAudioRecorderは録音するためのクラスです

主に下記の4つの機能を利用できます

  • システムのアクティブな入力デバイスからの音声を録音する
  • 指定した期間、またはユーザーが録音を停止するまで録音します
  • 録音を一時停止して再開します
  • 記録レベルの計測データにアクセスする

またiOSやtvOSで利用する場合はaudio sessionのcategoryを record または PlayAndRecord を設定する必要があります

Use an audio recorder to:

- Record audio from the system’s active input device
- Record for a specified duration or until the user stops recording
- Pause and resume a recording
- Access recording-level metering data

To record audio in iOS or tvOS, configure your audio session to use the `[record](https://developer.apple.com/documentation/avfaudio/avaudiosession/category/1616451-record)` or `[playAndRecord](https://developer.apple.com/documentation/avfaudio/avaudiosession/category/1616568-playandrecord)` category.

https://developer.apple.com/documentation/avfaudio/avaudiorecorder

AudioMasterへ録音の機能をつける

それでは実際にAudioMasterへ録音機能をつけてみましょう

録音機能としてつけたのは下記の3つです。

  • 録音開始機能 recordStart
  • 録音停止機能 recordStop
  • 録音ファイル取得機能 lastRecordAudioFile

また、音声ファイルの保存先を定義するためにgetAudioFileUrlというメソッドを追加しました。


public mutating func recordStart() -> Void {
    let session = AVAudioSession.sharedInstance()

    do {
        try session.setCategory(.record, mode: .default)
        try session.setActive(true)

        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC), // m4a形式で保存
            AVSampleRateKey: 44100, // サンプルレート。音楽業界などで一般的に利用されている44100で固定
            AVNumberOfChannelsKey: 2, // 音声経路はステレオを考え2に設定
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue // 品質はhighを設定。Maxでもいい気がする。
        ]

        audioRecorder = try AVAudioRecorder(url: getAudioFileUrl(), settings: settings)
        audioFileUrl = getAudioFileUrl()
    } catch let error {
        print(error)
    }
    audioRecorder.record()
}

public func recordStop() -> Void {
    audioRecorder.stop()
}

public func lastRecordAudioFile() -> URL? {
    audioFileUrl
}

private func getAudioFileUrl() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let docsDirect = paths[0]
    let audioUrl = docsDirect.appendingPathComponent("recording\(DateFormatter.yyyyMMddHHmmss.string(from: Date())).m4a")

    return audioUrl
}

また下記のようにテストコードを書いて録音処理が正常にできていることを確認しています

// 10秒間録音し、その結果を再生する
  func testRecordStart() throws {
      audioMaster.recordStart()
      let expectation = XCTestExpectation(description: "Your expectation")
      DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in
          self?.audioMaster.recordStop()
          expectation.fulfill()
      }
      wait(for: [expectation], timeout: 20)
      guard let url = audioMaster.lastRecordAudioFile() else { return }

      audioMaster = AudioMaster(url: url)
      audioMaster.play()
      XCTAssertTrue(audioMaster.isPlayng())
  }

https://github.com/entaku0818/AudioMaster/blob/master/Sources/AudioMaster/AudioMaster.swift

Discussion