[Xcode/Swift] AVFoundationを知る

AVFoundationは、Appleが提供するフレームワークで、オーディオやビデオの操作、処理、編集、再生が可能です。このフレームワークを使用すると、アプリケーションでマルチメディアコンテンツを操作するための高度な機能にアクセスできます。この記事では、AVFoundationの基本概念から、実際のコーディング例までを詳しく解説します。

AVFoundationとは

AVFoundationは、iOS、macOS、tvOS、watchOS向けのマルチメディアフレームワークです。以下のような多岐にわたるマルチメディア機能を提供します。

  • オーディオとビデオの再生
  • メディアの録音とキャプチャ
  • メディアの編集と合成
  • ライブストリーミング
  • メタデータの操作

AVFoundationを使用すると、単純なメディア再生から高度なメディア処理まで、幅広い操作が可能です。

AVFoundationの基本構造

AVFoundationは、いくつかの主要なクラスに分かれています。

  • AVPlayer: オーディオおよびビデオの再生を管理するクラス。
  • AVPlayerItem: 再生するメディアの情報を提供するオブジェクト。
  • AVAsset: メディアデータの構造とタイミング情報を提供。
  • AVCaptureSession: カメラやマイクからの入力を管理。
  • AVAudioRecorder: オーディオの録音を管理。
  • AVAudioPlayer: オーディオファイルの再生を管理。

オーディオ再生の実装

オーディオファイルを再生する最も簡単な方法は、AVAudioPlayerを使用することです。AVAudioPlayerは、ローカルファイルからのオーディオ再生を簡単に実装できます。

import SwiftUI
import AVFoundation

struct AudioPlayerView: View {
    @StateObject private var audioPlayer = AudioPlayer()

    var body: some View {
        VStack {
            Button(action: {
                audioPlayer.playSound()
            }) {
                Text("Play Sound")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }
        }
    }
}

final class AudioPlayer: ObservableObject {
    var player: AVAudioPlayer?

    func playSound() {
        guard let url = Bundle.main.url(forResource: "sound", withExtension: "mp3") else { return }
        do {
            player = try AVAudioPlayer(contentsOf: url)
            player?.play()
        } catch {
            print("Error playing sound: \(error.localizedDescription)")
        }
    }
}

解説

  • AVAudioPlayerを使用して、ローカルのオーディオファイルを再生します。
  • prepareToPlay()メソッドで、オーディオ再生の準備を行います。

ビデオ再生の実装

AVPlayerを使ったビデオ再生の例を実装します。

import SwiftUI
import AVKit

struct VideoPlayerView: View {
    private let player = AVPlayer(url: Bundle.main.url(forResource: "video", withExtension: "mp4")!)

    var body: some View {
        VStack {
            VideoPlayer(player: player)
                .onAppear {
                    player.play()
                }
        }
    }
}

解説

  • VideoPlayerは、SwiftUIに統合されたビデオ再生ビューで、AVPlayerと連携します。
  • onAppearを使って、ビューが表示されると同時にビデオを再生します。

オーディオ録音の実装

AVAudioRecorderを使って、オーディオを録音します。

import SwiftUI
import AVFoundation

struct AudioRecorderView: View {
    @StateObject private var audioRecorder = AudioRecorder()

    var body: some View {
        VStack {
            Button(audioRecorder.isRecording ? "Stop Recording" : "Start Recording") {
                if audioRecorder.isRecording {
                    audioRecorder.stopRecording()
                } else {
                    audioRecorder.startRecording()
                }
            }
            .padding()
            .background(audioRecorder.isRecording ? Color.red : Color.green)
            .foregroundColor(.white)
            .cornerRadius(8)
        }
    }
}

final class AudioRecorder: ObservableObject {
    var recorder: AVAudioRecorder?
    @Published var isRecording = false

    func startRecording() {
        let fileURL = getDocumentsDirectory().appendingPathComponent("recording.m4a")
        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 12000,
            AVNumberOfChannelsKey: 1,
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
        ]

        do {
            recorder = try AVAudioRecorder(url: fileURL, settings: settings)
            recorder?.record()
            isRecording = true
        } catch {
            print("Failed to record: \(error.localizedDescription)")
        }
    }

    func stopRecording() {
        recorder?.stop()
        isRecording = false
    }

    private func getDocumentsDirectory() -> URL {
        FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    }
}

カメラの使用とビデオキャプチャ

カメラを使用してビデオキャプチャを行うには、AVCaptureSessionを使用します。これにより、カメラ入力を管理し、リアルタイムで映像をキャプチャできます。

import SwiftUI
import AVFoundation

struct CameraView: View {
    @StateObject private var cameraModel = CameraModel()

    var body: some View {
        CameraPreviewView(session: cameraModel.session)
            .onAppear {
                cameraModel.startSession()
            }
            .onDisappear {
                cameraModel.stopSession()
            }
    }
}

final class CameraModel: ObservableObject {
    let session = AVCaptureSession()

    init() {
        setupSession()
    }

    private func setupSession() {
        session.beginConfiguration()

        guard let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
            print("No video device found")
            return
        }

        do {
            let videoInput = try AVCaptureDeviceInput(device: videoDevice)
            if session.canAddInput(videoInput) {
                session.addInput(videoInput)
            }
        } catch {
            print("Error setting up video input: \(error.localizedDescription)")
        }

        session.commitConfiguration()
    }

    func startSession() {
        if !session.isRunning {
            session.startRunning()
        }
    }

    func stopSession() {
        if session.isRunning {
            session.stopRunning()
        }
    }
}

struct CameraPreviewView: UIViewRepresentable {
    let session: AVCaptureSession

    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        let previewLayer = AVCaptureVideoPreviewLayer(session: session)
        previewLayer.frame = UIScreen.main.bounds
        previewLayer.videoGravity = .resizeAspectFill
        view.layer.addSublayer(previewLayer)
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}

解説

  • CameraModelクラスは、AVCaptureSessionの設定と管理を行います。
  • CameraPreviewViewは、UIViewRepresentableを使用して、カメラ映像をSwiftUIビュー内に表示します。

まとめ

AVFoundationを使うことで、SwiftUIでも強力なマルチメディア機能を実現できます。オーディオやビデオの再生、録音、カメラキャプチャを簡単に実装できるので、リッチなメディア体験を提供するアプリケーションの開発が可能です。この記事を参考に、AVFoundationを活用してください。