【Swift4】効果音のクラスを作ってみた。【AVAudioPlayer】

ずーーっと以前にSwiftで音を出すのはやってみた。
【Swift3】【AVAudioPlayer】音を出してみる。 | iPhoneアプリ備忘録

最近、ちょっとまた効果音を出したくて勉強し直してみた。
効果音を出すにはAudioServicesPlaySystemSoundを使う方法もあって、連打できたりするのは良いのですが、
iPhone側の音量で調節ができないという欠点もあり、AVAudioPlayerを使って連打も出来るようにクラスを作ってみた。

ちなみにクラスとか作るの初めてなのでなんか間違ってても生暖かく見守るか、優しく教えてもらえるとありがたいです。(-人-)

さて、参考にしたのはこちらのサイト。
ARC環境下でAVAudioPlayerを使い柔軟かつシンプルにサウンドを再生する方法

これをSwiftで書いてみたいと思います。

まず、AVAudioPlayerを使うにはAVFoundation.frameworkが必要です。
TARGET>Generalで追加しておきます。

音声ファイルも用意してプロジェクトナビゲータに放り込んでおく。
とりあえずファイル名は「hit.mp3」とする。

んでは、SEManagerというNSObjectのクラスを作ります。

import UIKit
import AVFoundation
class SEManager: NSObject , AVAudioPlayerDelegate{

    //シングルとして使う
    static let sharedInstance = SEManager()
    var soundArray = NSMutableArray()
    
    override init() {
        super.init()
    }
    
    func playSound(soundName : String) throws {
        //サウンドファイルのパスを作ります。
        let soundPath :String = (Bundle.main.path(forAuxiliaryExecutable:soundName)! as NSString) as String
        let URLOfSound : NSURL = NSURL(fileURLWithPath: soundPath as String)
        
        do {
            //AVAudioPlayerのインスタンスを作成
            let player :AVAudioPlayer = try AVAudioPlayer(contentsOf:URLOfSound as URL)
            //配列に収納
            soundArray.insert (player, at: 0)
            //デリゲートを設定
            player.delegate = self
            //音を鳴らします。
            player.play()
            
        } catch {
            print("サウンドエラー",error)
        }
        
    }
    
    //音が鳴り終わったら呼ばれるデリゲート
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        //鳴り終わったインスタンスを削除
        soundArray.remove(player)
        print("サウンド残り",soundArray.count)
    }
    
}

これで音を鳴らすクラスが出来た。
インスタンスを配列に入れて削除する辺り、実はよく分かってない。/(^o^)\
do とか、try とか、throwsとかも理解していない。
動いてるから良しとしてほしい。(^_^;)

んで、音を鳴らして!っていう側。
ボタンアクションでSEManagerを呼び出します。

import UIKit
class playSoundViewController: UIViewController {

    //SEManager用インスタンス作成
    var seManager:SEManager!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        //SEManager用インスタンスを保持
        seManager = SEManager.sharedInstance
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func hitButton(_ sender: Any)  {
        do{
        try seManager.playSound(soundName: "hit.mp3")
            
        } catch {
            print(error)
        }
    }
}

SEManagerに投げる音声ファイルでいろいろと音が鳴らせるので汎用性は高いように思います。
あ、インスタンスとか、オブジェクトとかよく理解できてませんので、なんかおかしい所あるかもしれません。
動いてるから良しとして(以下ry

ま、そんな感じで自分用の備忘録です。
うじゃうじゃ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です