SwiftUI | 音声ファイルを再生する方法

音声・動画

SwiftUIで音声ファイルを再生する方法を説明する。

結論

  1. 音声ファイルのURLを取得する。音声ファイルのURLの取得方法は、音声ファイルがApp同梱のものか、ユーザーが保存したものか、Web上のものかで異なる。
  2. 1を引数にAVAudioPlayerのインスタンスを生成する。
  3. 2に対してplay( )を実行する。

具体例

ボタンをタップすると音声ファイルが再生されるAppを作成する。

App同梱の音声ファイルを再生する場合

iOSファイルシステムのディレクトリ構成は以下のようになっている。App同梱のデータはBundle Containerに保存されている。

出典 https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html

音声ファイルをAppに同梱する方法は2つあり、再生するためのコードも異なる。

方法1

XcodeでTARGETS -> Build Phases -> Copy Bundle Resources を開き音声ファイルをドラッグ&ドロップする。

Copy items if needed、Create groupsをチェックしてfinish。

この音声ファイルを再生するには以下のコードを記述する。

  1. App同梱の音声ファイルのURLを取得する。
  2. 1を引数にAVAudioPlayerのインスタンスを生成する。
  3. 2に対してplay( )を実行する。
import SwiftUI
import AVFoundation

struct ContentView: View {
    var body: some View {
        let ファイルURL = Bundle.main.url(forResource: "test",
                                         withExtension: "mp3")!   // ? 1
        let プレイヤー = try! AVAudioPlayer(contentsOf: ファイルURL)  // ? 2
        Button("ボタンをタップ") {
            プレイヤー.play()                                        // ? 3
        }
        .buttonStyle(.borderedProminent)
    }
}

方法2

Assets.xcassetsに音声ファイルをドラッグ&ドロップする。

この音声ファイルを再生するには以下のコードを記述する。

import SwiftUI
import AVFoundation

struct ContentView: View {
    var body: some View {
        let プレイヤー = try! AVAudioPlayer(data: NSDataAsset(name:"test")!.data)

        Button("ボタンをタップ") {
            プレイヤー.play()
        }
        .buttonStyle(.borderedProminent)
    }
}

ユーザーが保存した音声ファイルを再生する場合

iOSファイルシステムのディレクトリ構成において、ユーザーが保存したファイルはData Container内のDocumentsディレクトリに保存される。

出典 https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html

Documentsディレクトリに保存された音声ファイルを再生するには、前述のコードからファイルURLを取得する部分をDocumentsディレクトリに変更すればよい。

  1. DocumentsディレクトリのURLを取得する。
  2. 1の後ろに動画ファイル名を追加する。
import SwiftUI
import AVFoundation

struct ContentView: View {
    var body: some View {
        let ファイルディレクトリ = FileManager.default.urls(for: .documentDirectory,
                                                      in: .userDomainMask)[0]  // ? 1
        let ファイルURL = ファイルディレクトリ.appendingPathComponent("/test.mp3")  // ? 2
        let プレイヤー = try! AVAudioPlayer(contentsOf: ファイルURL)
        Button("ボタンをタップ") {
            プレイヤー.play()
        }
        .buttonStyle(.borderedProminent)
    }
}

テストのためにDocumentsディレクトリにファイルを保存したい場合は、例えばApp同梱のファイルを保存しておき、それをDocumentsディレクトリにコピーすればよい。以下はコードの一例である。このAppを起動すればDocumentsディレクトリにファイルが保存される。iPhoneからAppを削除しない限り保存したファイルは残り続けるので、1回実行したらこのコードは消してもよい。

import SwiftUI

struct ContentView: View {
    var body: some View {
        Spacer()
            .onAppear{
                let ファイルディレクトリ = FileManager.default.urls(for: .documentDirectory,
                                                            in: .userDomainMask)[0]
                let コピー先 = ファイルディレクトリ.appendingPathComponent("test.mp3")
                let コピー元 = Bundle.main.url(forResource: "test", withExtension: "mp3")!
                do {
                    try FileManager.default.copyItem(at: コピー元, to: コピー先)
                } catch {
                    print("error")
                }
            }
    }
}

Web上の音声ファイルを再生する場合

Web上の音声ファイルをAVAudioPlayerで再生する方法はわからなかった。AVPlayerで再生する方法は以下の通りである。AVPlayerはカスタマイズ(例えばループ再生させるなど)できる幅が狭そうなので、AVPlayerで音声ファイルを再生するというのはあまり良い方法ではないかもしれない。

import SwiftUI
import AVKit

struct ContentView: View {
    var body: some View {
        let ファイルURL = URL(string: "https://なんとかかんとか/test.mp3")!
        let avPlayer = AVPlayer(url: ファイルURL)
        VideoPlayer(player: avPlayer)
    }
}

まとめ

SwiftUIで音声ファイルを再生する方法を説明した。

コメント

タイトルとURLをコピーしました