iOS+

AVFoundation

hot6 2024. 7. 14. 15:41

개요

이 글에서는 AVFoundation의 주요 구성 요소들을 살펴보고, 그들 간의 관계를 정리한다

그리고 AVKit은 AVFoundation을 기반으로 좀 더 고수준의 기능을 제공해 주는데, 이에 관한 내용도 마지막에 정리한다

 

AVFoundation

AVFoundation미디어 처리, 제어, 가져오기 등의 핵심 기능 제공한다

주요 클래스들은 다음과 같다

 

  • AVPlayer
  • AVAsset
  • AVPlayerItem
  • AVAudioSession
  • AVRecorder
  • AVCaptureDevice

 

AVPlayer와 AVPlayerItem, AVAssets

세 클래스의 관계는 아래 그림과 같다

 

 

 

AVAsset는 미디어 데이터를 나타내는 객체로, 비디오나 오디오 파일과 같은 미디어의 메타데이터와 트랙 정보를 포함한다

AVAsset은 실제 미디어 데이터를 직접 다루지 않지만, 미디어의 구조와 속성에 대한 정보를 제공하며, 다음과 같이 비디오나 오디오뿐 아니라 자막도 포함된다

 

AVPlayerItem은 재생할 미디어의 타이밍과 프레젠테이션 상태를 모델링하고, AVPlayer가 재생할 수 있는 에셋(asset)을 나타낸다

즉, AVAsset과 AVPlayer 사이의 중간 계층 역할을 한다

 

그리고 AVPlayer는 미디어의 재생을 관리하는 객체다

실제 코드를 보면 이렇게 설명한 관계를 더 쉽게 이해할 수 있다

 

let url = URL(string: "<https://example.com/audio.mp3>")

/// 미디어 데이터를 나타내는 AVAsset 객체
let asset = AVAsset(url: url!)  

/// 에셋을 포함하고, 재생 상태 및 정보를 관리하는 AVPlayerItem 객체
let playerItem = AVPlayerItem(asset: asset)

/// 미디어 재생을 관리하는 객체
let player = AVPlayer(playerItem: playerItem)

player.play()

 

AVAudioSession

AVAudioSession은 앱의 오디오 동작을 시스템에 알리고 오디오 하드웨어를 제어한다

이를 통해 백그라운드 재생, 녹음 권한 등을 관리할 수 있다

 

MyMemo 프로젝트에서 음성메모 기능을 구현할 때,

앱 실행하고 매번 최초 녹음하는 경우에는 녹음되지 않는 문제가 있었는데, AVAudioSession을 초기화하지 않아서 발생하는 문제였다

그래서 녹음 전에 initSession() 메서드를 수행하게 해서 문제를 해결했다

 

AVAudioRecorder

AVAudioRecorder를 사용하면 디바이스의 마이크로 오디오를 녹음할 수 있다

우선 아래와 같이 저장 경로를 지정하고, 오디오 녹음 시 관련 옵션을 딕셔너리로 넘겨줘야 한다

 

아래 코드에서는 오디오 형식, 샘플링 레이트, 채널의 수, 품질에 대한 설정을 전달했다

 

let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let audioFilename = documentsPath.appendingPathComponent("recording.m4a")

let settings = [
    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
    AVSampleRateKey: 44100,
    AVNumberOfChannelsKey: 2,
    AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]

do {
    let recorder = try AVAudioRecorder(url: audioFilename, settings: settings)
    recorder.record()
} catch {
    print("녹음 시작 실패: \\(error)")
}

AVAudioRecorder의 주요 기능 및 메서드로는 다음과 같이 존재한다

 

  • 녹음 제어
    • record()
    • stop()
    • pause()
    • resume()
  • 녹음 정보
    • isRecording
    • currentTime
    • url
    • settings

AVAudioRecorderDelegate

또한 여러 iOS 프레임워크와 마찬가지로 Delegate 메서드를 제공해 주는데, 이를 이용하여 다음과 같은 이벤트를 처리할 수 있다

 

  • audioRecorderDidFinishRecording(_:successfully:): 녹음 완료 시 호출
  • audioRecorderEncodeErrorDidOccur(_:error:): 인코딩 오류 발생 시 호출

 

AVAudioPlayer

AVAudioPlayer는 오디오 데이터를 파일 또는 버퍼에서 재생하는 객체다

물론 AVPlayer를 이용하여 재생을 구현해도 되지만, 간단한 로컬 오디오 파일 재생이라면 AVAudioPlayer로도 충분하다

 

class SimpleAudioPlayer {
    var audioPlayer: AVAudioPlayer?
    
    func playAudio() {
        guard let path = Bundle.main.path(forResource: "audiofile", ofType: "mp3") else {
            print("오디오 파일을 찾을 수 없습니다.")
            return
        }
        
        let url = URL(fileURLWithPath: path)
        
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.prepareToPlay()
            audioPlayer?.play()
        } catch {
            print("오디오 플레이어 초기화 실패: \\(error)")
        }
    }
    
    func stopAudio() {
        audioPlayer?.stop()
    }
}

let player = SimpleAudioPlayer()
player.playAudio()

 

AVCaptureDevice

AVCaptureDevice는 하드웨어 또는 가상 캡처 장치, 예를 들어 카메라나 마이크를 나타내는 클래스다

이 클래스는 미디어 데이터를 AVCaptureSession에 연결된 캡처 세션 입력에 제공한다

음성을 수행하기 위한 마이크 사용 권한 요청 및 권한 확인에 사용된다

 

이 부분과 관련된 자세한 내용은 향후 카메라 관련 기능을 정리하는 글에서 자세히 다룬다..

 

AVKit

AVKit은 AVFoundation을 기반으로 좀 더 고수준의 기능을 제공해 주는데,

VideoPlayer는 AVKit의 주요 구성 요소로, 비디오 재생을 위한 사용자 인터페이스를 제공한다

 

SwiftUI에서는 VideoPlayer 뷰를 사용하여 앱에 비디오 재생 기능을 쉽게 추가할 수 있다

 

VideoPlayer

VideoPlayer는 인자인 player에 AVPlayer를 전달하면 된다

 

import SwiftUI
import AVKit

struct ContentView: View {
    var body: some View {
        VideoPlayer(player: AVPlayer(url: URL(string: "<https://example.com/video.mp4>")!))
            .frame(height: 400)
    }
}

 

VideoPlayer뷰에는 다음과 같은 기능들이 제공되어 편리하다

  • 비디오 재생: AVPlayer를 기반으로 하며, 로컬 또는 원격 소스에서 비디오를 재생할 수 있다
  • 사용자 인터페이스 제공: 재생/일시정지 버튼, 타임라인 슬라이더, 전체 화면 버튼 등의 표준 미디어 컨트롤을 제공한다(SwiftUI에서 AVPlayer만 이용할 경우, 관련 UI들을 만들고 관련 동작코드를 직접 작성해야 한다..)

 

마무리

MyMemo 프로젝트에서 구현했던 음성 메모 기능과 관련하여 AVFoundation의 AudioRecorder 부분을 다시 복습하는 좋은 기회였다

 

AVKit은 그냥 플레이어를 만들어서 재생하는 간편한 방법을 제공해 준다

결국 기본 제공 UI가 아닌 커스텀한 플레이어를 만들려면, AVKit을 이용하기보단 AVFoundation의 요소들을 사용하고 SwiftUI로 UI를 커스텀하게 구현해야 한다

 

참고