以前から音声からのテキスト入力機能(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 で録音することができます。
(公開されている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が表示されます。
(一般公開されている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 を利用します。
##参考資料(ログイン不要領域にて利用可能)