まえがき
上記開発中アプリの機能として、SEとBGM再生が欲しかったので
色々調べて実装してみたものをまとめます。
Audio周りはこの辺りを読めば、基本的なことは理解できそう。
あ、あとで読もう。
それとiOSヒューマンインターフェイスガイドラインの項目にも、
オーディオ動作に関して記述があったから参照するとよいかも。
iOS ヒューマンインターフェイスガイドライン 音声
【確認環境】
- Xcode 7.3.1
- Swift 2.2
AudioToolbox を使う
最初は簡単そうなAudioToolboxフレームワークのSystem Sound Servicesを使ってみる。
アプリケーション内でシステムサウンドとかをSEとして使う場合にはこれで十分そう。
再生できるファイルとかにもそこそこ制約あるっぽい。
参考にさせてもらったのはこのあたりです。
準備する
フレームワークをインポートしときます。
「左上のプロジェクト名」→「Build Phases」→「Link Binary With Libraries」に
AudioToolbox.frameworkを追加しておく。もちろん使う所でimportする。
import AudioToolbox
バイブレーションさせる
いきなり音が出ないやつだけど、まずは一番お手軽なやつから実装してみた。
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
これだけ。
SystemSoundIDにkSystemSoundID_Vibrateを与えて
バイブレーションのシステムサウンドIDを作成。そのままAudioServicesPlaySystemSoundを実行。
したらブルった。
システムサウンドを再生してみる
再生できるシステムサウンドの一覧とかは以下を参考にした。
var soundId:SystemSoundID = 0
// システムサウンドへのパスを指定
if let soundUrl:NSURL = NSURL(fileURLWithPath: "/System/Library/Audio/UISounds/alarm.caf") {
// SystemsoundIDを作成して再生実行
AudioServicesCreateSystemSoundID(soundUrl, &soundId)
AudioServicesPlaySystemSound(soundId)
}
これで指定したIDのサウンドが1回再生できた。
ちなみに最初ID:1325のFanfare.cafを試したら再生されずコンソールにwarning出てた。
一部のファイルはパスが違うっぽい。1つ潜ったところ(/New)にあった。
あと以下でも再生されるけど、これでやると消音時にバイブレーションするようになった。
var soundID: SystemSoundID = 1005 # 1005はalarm.cafのSystemSoundID
AudioServicesPlaySystemSound(soundId)
気になること
再生中のサウンドはAudioServicesDisposeSystemSoundID
でsoundIDの破棄をすれば止まるのかな?
よくある「リスト選択したら1回試しに再生」される感じのものを実装したいのだけれども。
それをやるなら、AudioToolboxじゃない方がいいかな...
AVAudioPlayer を使う
自分で用意したmp3ファイルとかをBGM等で再生したい、ぐらいの要求だったら
このAVAudioPlayerを使えば大体のことはいけそう。以下参考にしました。
準備する
プロジェクト設定で最初からAVFoundationフレームワークは内包されているのか、
特に追加作業等はいらない。使うファイルでimportすればよい。
import AVFoundation
そして使用したいサウンドファイルも左ペインのファイルツリーからプロジェクトに追加しておく。
今回は"kane01.mp3"とした。(金じゃなくて鐘ですね)
AVAudioPlayerで再生してみる
今やってるアプリではUIViewController内に関数として実装していますが、
そこから最低限必要な部分だけ出すとこれだけ。
// この変数は実際のコードではUIViewControllerクラス内で宣言してる
var audioPlayer: AVAudioPlayer!
// サウンドデータの読み込み。ファイル名は"kane01"。拡張子は"mp3"
let audioPath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("kane01", ofType: "mp3")!)
// swift2系からtryでエラー処理するようなので、do〜try〜catchで対応
do {
// AVAudioPlayerを作成。もし何かの事情で作成できなかったらエラーがthrowされる
audioPlayer = try AVAudioPlayer(contentsOfURL: audioPath)
// イベントを通知したいUIViewControllerをdelegateに登録
// delegateの登録するならAVAudioPlayerDelegateプロトコルの継承が必要
audioPlayer.delegate = self
// これで再生
audioPlayer.play()
}
// playerを作成した時にエラーがthrowされたらこっち来る
catch {
print("AVAudioPlayer error")
}
再生中のサウンドを停止する場合
まあ当たり前かもですけど、普通ですね。
// playingプロパティで再生中のチェックができる
if (audioPlayer.playing) {
// サウンドの停止
audioPlayer.stop()
}
(現状の)結論
まあ簡単にできちゃいますね。これ以上にテクニカルなことをやろうとすると
もう少し調べないとダメそうですが、現状は一括でまとめたぐらいしか記事としての価値は。。。
BGM再生周りのコーディングを進めていけば、もうちょっとノウハウも出るかもなので
そしたら追記していきます。
特に各種デリゲートメソッドとか。。。