仕様
・再生ボタンを押すと永続リピートでバックグラウンドで音楽が流れる
・停止ボタンを押すとバックグラウンド音楽が止まる
・楽器の画像をタッチするとその楽器の音を出すことができる(バックグラウンド音楽に新しい音を乗せれる)
学び
画像ボタン
UIパーツを置く時にimageView
ではなくbutton
を配置しボタンの装飾として画像を上から貼ってる感じ
mp3ファイルをディレクトリにいれる
音、画像、動画のフレームワークを入れる
音、画像、動画のフレームワークを扱いやすくするためのフレームワークAVfoundation
を読み込む
import AVFoundation
順番
①楽器のファイルパス指定→②プレイヤーインスタンス作成→③楽器ボタン押された時の処理(try文とdo~catchでエラー処理も)
①ファイルパスの取得方法
ディレクトリに配置したcymbal.mp3
を取得したいとき
let cymbalPath = Bundle.main.bundleURL.appendingPathComponent("cymbal.mp3")
main→Bundle
の主なディレクトリ名称
bundleURL→Bundle
のmain
というディレクリにある保存領域の住所
.appendingPathComponent("cymbal.mp3")
→bundleURL
に指定したファイルの住所と名称
参考: https://teratail.com/questions/77240
②インスタンス作成
var cymbalPlayer = AVAudioPlayer()
③楽器ボタン押された時の処理(try文とdo~catchでエラー処理も)
@IBAction func cymbal(_ sender: Any) {
do {
cymbalPlayer = try AVAudioPlayer(contentsOf: cymbalPath, fileTypeHint: nil)
cymbalPlayer.play()
} catch {
print("エラーメッセージ")
}
}
tryからメソッドを呼び出して、エラーが起きだ場合のみcatchの中に入ってエラーメッセージ
と表示される
contentsOf
にはURLを、fileTypeHint
は補完の際に出てきたがnilなので省略可
共通処理のまとめ(リファクタリング)
同一ファイル内からのみアクセスできるアクセス修飾子fileprivate
を使う(private
は別物かつ厳しい)
fileprivate func soundPlayer(_ player: inout AVAudioPlayer, path:URL, count: Int){
do {
player = try AVAudioPlayer(contentsOf:
path, fileTypeHint: nil)
player.numberOfLoops = count
player.play()
} catch {
print("エラー発生してます")
}
}
AVAudioPlayerクラスにinout
と指定することで、引数として受け取り、最後に戻り値として変数を戻している。
つまり、return不要ということだ。
共通処理のsoundPlayer
をつかった処理
@IBAction func cymbal(_ sender: Any) {
soundPlayer(&cymbalPlayer, path:cymbal_path, count: 0)
}
&cymbalPlayer
は参照渡しというもので、参照先の場所を教えているイメージ。