クリアメモリ

プログラミングやモーショングラフィックス、便利なアプリケーションなど雑多に記録するブログ

【Swift】AVAudioPlayerで音が鳴るOSXアプリを作る

f:id:clrmemory:20170422184535p:plain 

今回はCocoa Programmingで、ボタンを押したら音がなるOSXアプリを作成してみようと思います。複数用意した音源ファイルの中からユーザーが選択した音がなるようにしてみました。

音源については各自用意しておいてください。

 

 

はじめに

 

今回完成するアプリケーションは以下のようになっています。

 

 

この画像にあるように、ユーザーが鳴らす音を選択してから「Play Audio」ボタンをクリックすることで選択した音源が再生される仕組みです。

また、こちらのアプリはCocoa ProgrammingでSwiftで作成し、Xcodeからストーリーボードを使っています。別の言語やアプリケーションではうまくいかないので注意してください。

 

実際の動作はこちらから確認してみてください。

 

 

ではまずストーリーボードで、オブジェクトの設置と音源ファイルの作成をしていきましょう。音源ファイルは各自用意しておいてください。

 

ストーリーボードを作成

 

今回のストーリーボードで使用したオブジェクトは「ラベル」「ラジオボタン」「カスタムボックス」「再生ボタン」です。

以下の画像を参考にして、オブジェクトをそれぞれ配置してみてください。

 

 

ラジオボタンの「state」は最初の1つ目以外は「off」にしておいてください。これは、どれか1つのオーディオファイルだけを選択できるようにするためです。

オブジェクトの設置が完了したら、先にViewControllerとセグエで接続してしまいましょう。

 

今回は

ラジオボタン -> Outlet ,  Action

再生ボタン    -> Action

で接続しています。

 

class ViewController: NSViewController {

    @IBOutlet weak var phoneButton: NSButton!
    @IBOutlet weak var waterButton: NSButton!
    @IBOutlet weak var explosionButton: NSButton!
    @IBOutlet weak var bellButton: NSButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        setAudio()
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBAction func phoneButton(_ sender: Any) { }

    @IBAction func waterButton(_ sender: Any) { }

    @IBAction func explosionButton(_ sender: Any) { }

    @IBAction func bellButton(_ sender: Any) { }

    @IBAction func playAudio(_ sender: Any) { }
}

 

とりあえずこのような感じで接続しておいてください。

続いて、音源ファイルをプロジェクトの中に作成しましょう。今回は4つの音源ファイルを用意しました。

 

ちなみに、これらのアクション接続は「ひとまとめ」にすることもできます。コードを簡潔に書けるので確認してみると良いかもしれません。

 

https://clrmemory.com/swift/cocoa-package-ibaction/

 

オーディオファイルを設置

 

https://clrmemory.com/unity/bgm-koukaonn-lab/

 

こちらでも紹介されている「効果音ラボ」様などで効果音を用意するか、すでに自分で所持している音源をXcodeのプロジェクト内にドラッグしてみてください。

 

 

このようなウィンドウが表示されますので「Copy Items if needed」にチェックを入れ、「Create groups」を選択してください。

このようにすることで、元の音源ファイルに変更を加えても、プロジェクト内のオーディオファイルは変更しないようにできます。

 

同様にすべてのオーディオファイルを設置すると以下のようになると思います。

 

 

プロジェクト名やオーディオファイル名に違いはあるものの、大体このような感じで配置できましたでしょうか。

ではオーディオの設置が完了したので、実際にコードから音源ファイルを再生させてみましょう。

 

音源ファイルを作成

 

Swiftで音源ファイルを再生する場合、必要な工程が以下になります。

 

1.オーディオプレーヤーを用意

2.パスを設定

3.拡張子を設定

4.オーディオプレーヤーに音源を追加

5.再生

 

これらと、ボタンの状態を記述することで、選択した音源だけを再生させます。

では、実際のコードを確認してください。今回はこのようなコードになりました。

 

import Cocoa
import AVFoundation

class ViewController: NSViewController {

    var audioName: String = "Phone"
    let audioPath = NSURL()
    var audioPlayer: AVAudioPlayer?

    @IBOutlet weak var phoneButton: NSButton!
    @IBOutlet weak var waterButton: NSButton!
    @IBOutlet weak var explosionButton: NSButton!
    @IBOutlet weak var bellButton: NSButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        setAudio()
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBAction func phoneButton(_ sender: Any) {
        resetList(sender as! NSButton)
    }

    @IBAction func waterButton(_ sender: Any) {
        resetList(sender as! NSButton)
    }
    @IBAction func explosionButton(_ sender: Any) {
        resetList(sender as! NSButton)
    }
    @IBAction func bellButton(_ sender: Any) {
        resetList(sender as! NSButton)
    }

    func resetList(_ sender: NSButton){

        phoneButton.state = 0
        waterButton.state = 0
        explosionButton.state = 0
        bellButton.state = 0

        sender.state = 1

        audioName = sender.title
        setAudio()
    }

    func setAudio(){

        let setURL = Bundle.main.url(forResource: audioName,withExtension: "mp3")

        if let selectURL = setURL{
            do{
                audioPlayer = try AVAudioPlayer(contentsOf: selectURL, fileTypeHint: nil)
            }catch{
                print("ERROR")
            }
        }
    }
    @IBAction func playAudio(_ sender: Any) {
        audioPlayer?.play()
    }
}

 

まず、冒頭に「import AVFoundation」の記述がある点に注意してください。

このようなフレームワークを追加する記述がされていないと、オーディオを鳴らすことはできません。

 

記述できたらViewControllerクラス内に、再生するオーディオの名前パスオーディオプレーヤーをあらかじめ作成しておきましょう。オーディオの名の初期状態は、1つ目のPhoneという音源を鳴らしたいので、ここですでに設定しておきました。

 

では、重要な点を順に解説していきます。

resetList( )

 

ラジオボタンがクリックされた時の処理を記述します。

この中では、ボタンの状態をoffにした後で、クリックされたボタンだけをonに変更しています。このようにすることで、4つの音源からクリックした音源のボタンだけにチェックを入れることができました。

 

その後で、ボタンのタイトルをaudioNameに格納します。

このaudioNameはsetAudio( )のなかで、パスを指定するときに使いました。

 

setAudio( )

 

ここでは、オーディオプレーヤーに音源ファイルを追加しています。

まず、setURLにパスを設定する必要があるのですが、forResourceで音源の名前、withExtensionで拡張子を指定してください。今回はラジオボタンのタイトルで受け取っています。

 

続いてAVAudioPlayerでオーディオプレイヤーのcontentsOf: selectURLで先ほど設定したURLにある音源ファイルを追加しているのですが、この記述は「try catch文」で記述する必要があります。このようにしないとエラーが発生するので注意してください。

 

playAudio( )

 

最後に音源を.play( )で再生しました。

 

まとめ

 

今回紹介したように、Xcodeでは用意した音源ファイルを簡単に再生することができます。同じようにして、音源を追加できる機能を実装して、ユーザーが自由にオーディオを選択できるようにしてみても良いかもしれませんね。

 

ぜひ試してみてください。

ではまた。