【SwiftUI】AVAudioPlayerで音(サウンド)を鳴らす方法!

【SwiftUI】AVAudioPlayerで音(サウンド)を鳴らす方法!

この記事からわかること

  • SwiftUIアプリから(サウンド)を鳴らす方法とは?
  • AVAudioPlayerクラス使い方
  • NSDataAssetクラスとは?
  • The data set "サウンドファイル名.mp3" has an unassigned child.」の解決法
  • The file "サウンドファイル名.mp3" for the image set "サウンドファイル名" does not exist.エラー解決法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

SwiftUIでアプリから音を出す方法

流れ

  1. オーディオファイル(音)の用意
  2. XcodeのAssetに追加
  3. NSDataAssetクラスでデータを指定
  4. AVAudioPlayerクラスで再生

流れとしては上記の通りです。まずは実装してみます。また今回はAVFoundationフレームワークのAVAudioPlayerクラスを使用しますが、Audio Toolboxフレームワークを使用しても音を鳴らすことが可能です。

おすすめ記事:【Swift】システムサウンドの再生方法!AudioServicesPlaySystemSoundの使い方

AVAudioPlayerの方が音量の調節など柔軟にコントローすることができます。

オーディオファイル(音)の用意

まずは鳴らしたい音データを用意します。今回は「無料効果音」(無料で効果音を提供しているサイト)の「ゲーム・ボタン音」>「button05.mp3」を使用します。

無料効果音

無料効果音

XcodeのAssetに追加

ダウンロードしたオーディオファイル(mp3)をXcodeのAssetにドラッグ&ドロップで追加します。これで前準備が完了しました。

【SwiftUI】AVAudioPlayerで音(サウンド)を鳴らす方法!'

NSDataAssetクラスでデータを指定

続いてXcode内でコードを記述し再生させていきます。まずはAVFoundationフレームワークを読み込み、NSDataAssetクラスで再生したいデータインスタンスを作っておきます。またAVAudioPlayerインスタンス格納用のプロパティも準備しておきます。AVAudioPlayerはスコープをメソッド内に閉じ込めてしまうと正しく再生されないのでインスタンスプロパティに持たせて再生完了まで破棄されないようにしておく必要があります。

import AVFoundation // 追加
class SoundPlayer {
    
    var musicPlayer: AVAudioPlayer?
    
    func play() {
        guard let musicData = NSDataAsset(name: "button05").data else { return }
        // TODO:再生
    }
}

AVAudioPlayerクラスで再生

AVAudioPlayerクラスに先ほどの音データインスタンスを渡し、playメソッドを呼び出すことで再生できます。

import AVFoundation // 追加
class SoundPlayer {
    
    var musicPlayer: AVAudioPlayer?
    
    func play() {
        guard let musicData = NSDataAsset(name: "button05").data else { return }
        do {
          musicPlayer = try AVAudioPlayer(data: musicData)
          musicPlayer.play()
        } catch {
          print("音の再生に失敗しました。")
        }
    }
}

実際にこの処理を呼び出して再生されているか確認してみてください。

NSDataAssetクラスとは?

参考文献: 公式リファレンス-NSDataAssetクラス

NSDataAssetAssetに保存されているデータを参照するためのクラスです。引数には任意のAsset名を指定することで対象のデータをNSDataAsset型で取得し、そのdataプロパティからAVAudioPlayerクラスで必要となるData型に参照できます。

let musicData = NSDataAsset(name: "button05")!.data

AVAudioPlayerクラス

参考文献: 公式リファレンス-AVAudioPlayerクラス

AVAudioPlayerオーディオデータを再生するクラスです。オーディオの再生だけでなく、音量調節やループ制御など様々な機能を提供しています。

イニシャライザにはthrowsが付与されているのでtry文の記述が必要になります。またdo-catch文を使用して適切にエラーハンドリングを行っておきます。

init(data: Data) throws

おすすめ記事:【Swift】do-catchとthrows文の使い方!エラーハンドリングのやり方

引数に対象のデータを渡しAVAudioPlayerインスタンスを生成して操作していきます。エラーが発生した場合はnilが返ります。

do {
    musicPlayer = try AVAudioPlayer(data: musicData)
    musicPlayer.play()
} catch {
    print("音の再生に失敗しました。")
}

AVAudioPlayerの操作方法

オーディオの再生や一時停止などと言った操作はメソッドとして用意されています。

// 再生
musicPlayer.play()
// 一時停止
musicPlayer.pause() 
//  停止
musicPlayer.stop()

Assetにサウンドファイル追加時に発生したエラー

効果音ラボ

効果音ラボ

最初「効果音ラボ」(無料で効果音を提供しているサイト)の音源「決定ボタンを押す2.mp3」をダウンロードしてそのままAssetに追加した際に以下のような2つのエラーが発生してしまいました。

【SwiftUI】AVAudioPlayerで音(サウンド)を鳴らす方法!

The data set "サウンドファイル名.mp3" has an unassigned child.

翻訳:データセット「サウンドファイル名.mp3」には、割り当てられていない子があります。

The file "サウンドファイル名.mp3" for the image set "サウンドファイル名" does not exist.

翻訳:画像セット「サウンドファイル名」のファイル「サウンドファイル名.mp3」が存在しません。

翻訳してみると追加したファイルが正しく認識されていないようです。

解決法

ファイル名を以下のように変更したところ正しく認識されるようになりました。全角数字も別に使用できるはずなのに原因はよくわかりませんでしたが、ダウンロードしたサウンドファイルは自分の識別しやすい任意の名前に変更しておくと良いのかもしれません。

「決定ボタンを押す2.mp3」
     ↓  
「決定ボタンを押す.mp3」

.m4aなどを再生する

.m4aなどのオーディオファイルはAssetに入れることができないため、プロジェクト内にそのまま設置します。あとはBundle.main.urlで対象ファイルのURLを取得してAVAudioPlayer(contentsOf: url)で取得すればOKです。

func playSound() {
    guard let url = Bundle.main.url(forResource: "Test", withExtension: "m4a") else {
        print("音声ファイルが見つかりません")
        return
    }
    
    do {
        player = try AVAudioPlayer(contentsOf: url)
        player?.play()
    } catch {
        print("再生エラー: \(error.localizedDescription)")
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

Search Box

Sponsor

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index