Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

watchOS 2 のオーディオ録音、再生機能を利用する

More than 5 years have passed since last update.

以前から音声からのテキスト入力機能(Dectation)として Apple Watch のマイクを利用することはできましたが、watchOS 2 より、WKInterfaceController に新たに 音声を録音してファイル出力する UI を表示するメソッドが追加されました。

func presentAudioRecordingControllerWithOutputURL(_ URL: NSURL,
                                           preset preset: WKAudioRecordingPreset,
                                  maximumDuration maximumDuration: NSTimeInterval,
                                      actionTitle actionTitle: String?,
                                       completion completion: (Bool,
                                                           NSError?) -> Void)

こんな感じの UI で録音することができます。

recorder.jpg

(公開されているWWDCセッションの動画より)

実装方法

Swift

まず、オーディオファイルを出力する先の NSURL オブジェクトを生成しておきます。

let filePaths = NSSearchPathForDirectoriesInDomains(
    NSSearchPathDirectory.DocumentDirectory,
    NSSearchPathDomainMask.UserDomainMask,
    true)
let documentDir = filePaths.first!
let filePath = documentDir + "rec.m4a"
let fileUrl = NSURL.fileURLWithPath(filePath)

ファイルの拡張子は .wav, .mp4, .m4a が指定でき、これが録音するオーディオのタイプを決定します。

presentAudioRecordingControllerWithOutputURL:preset:maximumDuration:actionTitle:completion: メソッドを次のように呼びます。

self.presentAudioRecordingControllerWithOutputURL(
    fileUrl,
    preset: WKAudioRecordingPreset.WideBandSpeech,
    maximumDuration: 5.0,
    actionTitle: "SomeTitle") { (didSave, error) -> Void in

        print("didSave:\(didSave), error:\(error)")
}

第2引数の preset は録音品質を指定するもので、上記以外に NarrowBandSpeech, HighQualityAudio を渡せます。

Objective-C

ちなみに ObjC で書くとこんな感じです。

NSArray *filePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask,YES);
NSString *path = [[filePaths firstObject] stringByAppendingPathComponent:@"rec.m4a"];
NSURL *fileUrl = [NSURL fileURLWithPath:path];
[self presentAudioRecordingControllerWithOutputURL:fileUrl
                                            preset:WKAudioRecordingPresetWideBandSpeech
                                   maximumDuration:5.0
                                       actionTitle:@"Some Title"
                                        completion:^(BOOL didSave, NSError * __nullable error) {

                                            NSLog(@"didSave:%d, error:%@", didSave, error);
                                        }];

再生

オーディオやビデオファイルを再生する UI を表示するメソッドも新たに追加されました。次のように、メディアファイルの NSURL オブジェクトを渡すだけ。

self.presentMediaPlayerControllerWithURL(
    fileURL,
    options: nil) { (didPlayToEnd, endTime, error) -> Void in

        print("didPlayToEnd:\(didPlayToEnd), endTime:\(endTime), error:\(error)")
}

前述した presentAudioRecording〜 で録音したファイルなら、そのとき渡した NSURL オブジェクトをそのままこっちのメソッドに渡すだけです。

こんな感じのUIが表示されます。

player.jpg

(一般公開されているWWDCの動画より)

WKAudioFilePlayer

WKAudioPlayer を利用すると、 Watch とペアリングされた Bluetooth オーディオヘッドセットでのオーディオファイル再生 が可能となります。

プロパティを定義しておいて、

var player: WKAudioFilePlayer!

こんな感じで、WKAudioFileAsset → WKAudioFilePlayerItem → WKAudioFilePlayer を作成します。

override func awakeWithContext(context: AnyObject?) {
    super.awakeWithContext(context)

    let filePath = NSBundle.mainBundle().pathForResource("se_tap", ofType: "m4a")!
    let fileUrl = NSURL.fileURLWithPath(filePath)
    let asset = WKAudioFileAsset(URL: fileUrl)
    let playerItem = WKAudioFilePlayerItem(asset: asset)
    player = WKAudioFilePlayer(playerItem: playerItem)
}

再生は play メソッドを呼ぶだけですが、status.ReadyToPlay になってないといけないので、こんな感じにしてみました。

@IBAction func playBtnTapped() {

    switch player.status {
    case .ReadyToPlay:
        player.play()
    case .Failed:
        label.setText("failed")
    case .Unknown:
        label.setText("unknown")
    }
}

(実際には status が .ReadyToPlay になるまでタイマーでポーリングすべき?delegateみたいなのとか、再生準備完了の通知みたいなのは見当たらなかった。WKAudioFilePlayerItem にはいくつかの関連する通知があるみたいだけど。)

ちなみに WKAudioPlayer は、ひとつのオーディオファイル再生用です。複数のオーディオファイルを再生したい場合は、WKAudioFileQueuePlayer を利用します。

参考資料(ログイン不要領域にて利用可能)

shu223
フリーランスiOSエンジニア 著書:『iOS×BLE Core Bluetooth プログラミング』『Metal入門』『実践ARKit』『Depth in Depth』『iOSアプリ開発 達人のレシピ100』他 GitHubの累計スター数24,000超
http://shu223.hatenablog.com/
engineerlife
技術力をベースに人生を謳歌する人たちのコミュニティです。
https://community.camp-fire.jp/projects/view/280040
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away