Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> iOS

Cách phát âm thanh và video trong iOS (AVFoundation)

Phát audio/video là nhu cầu cơ bản hầu hết app. iOS cung cấp AVFoundation framework mạnh mẽ.

Framework & Setup

Project → Target → Build Phases → Link Binary With Libraries → Thêm AVFoundation.framework.

Cách phát âm thanh và video trong iOS (AVFoundation)

Phát Audio (AVAudioPlayer)

Bước 1: Thêm file audio vào project

Kéo file .mp3, .m4a, .wav... vào project (Copy items if needed).

Bước 2: Code


import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    var audioPlayer: AVAudioPlayer?
    
    @IBAction func playButton(_ sender: Any) {
        guard let url = Bundle.main.url(forResource: "sample", withExtension: "mp3") else {
            print("Không tìm thấy file audio")
            return
        }
        
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.prepareToPlay()
            audioPlayer?.play()
            print("Đang phát audio...")
        } catch {
            print("Lỗi phát audio: \(error)")
        }
    }
    
    @IBAction func stop(_ sender: Any) {
        audioPlayer?.stop()
        audioPlayer = nil // Release memory
    }
    
    @IBAction func pause(_ sender: Any) {
        audioPlayer?.pause()
    }
}

Phát Video (AVPlayer + AVPlayerLayer)

Bước 1: Thêm file video (.mp4, .mov) vào project

Bước 2: Code


import AVFoundation

class ViewController: UIViewController {
    
    var player: AVPlayer?
    var playerLayer: AVPlayerLayer?
    
    @IBAction func videoButton(_ sender: Any) {
        guard let path = Bundle.main.path(forResource: "one", ofType: "mp4") else {
            print("Không tìm thấy video")
            return
        }
        
        let videoURL = URL(fileURLWithPath: path)
        player = AVPlayer(url: videoURL)
        
        playerLayer = AVPlayerLayer(player: player)
        playerLayer?.frame = view.bounds
        playerLayer?.videoGravity = .resizeAspect // Giữ tỷ lệ
        
        if let layer = playerLayer {
            view.layer.addSublayer(layer)
        }
        
        player?.play()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        playerLayer?.frame = view.bounds // Cập nhật frame khi rotate
    }
}

Mã hoàn chỉnh


import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    var audioPlayer: AVAudioPlayer?
    var player: AVPlayer?
    var playerLayer: AVPlayerLayer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func stop(_ sender: Any) {
        audioPlayer?.stop()
        audioPlayer = nil
    }
    
    @IBAction func playButton(_ sender: Any) {
        guard let url = Bundle.main.url(forResource: "sample", withExtension: "mp3") else { return }
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.play()
        } catch { print("Audio error: \(error)") }
    }
    
    @IBAction func videoButton(_ sender: Any) {
        guard let path = Bundle.main.path(forResource: "one", ofType: "mp4") else { return }
        let videoURL = URL(fileURLWithPath: path)
        player = AVPlayer(url: videoURL)
        playerLayer = AVPlayerLayer(player: player)
        playerLayer?.frame = view.bounds
        playerLayer?.videoGravity = .resizeAspect
        if let layer = playerLayer { view.layer.addSublayer(layer) }
        player?.play()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        playerLayer?.frame = view.bounds
    }
    
    deinit {
        player?.pause()
        player = nil
        audioPlayer?.stop()
    }
}

Các tính năng nâng cao

1. Audio Session (Background audio, ducking...)


do {
    try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
    try AVAudioSession.sharedInstance().setActive(true)
} catch { print("Audio session error: \(error)") }

2. Remote URL Streaming


// Audio streaming
let url = URL(string: "https://example.com/audio.mp3")!
audioPlayer = try AVAudioPlayer(contentsOf: url) // Chỉ file local
// Streaming dùng AVPlayer
player = AVPlayer(url: url)

// Video streaming
player = AVPlayer(url: URL(string: "https://example.com/video.mp4")!)

3. PiP (Picture in Picture) - iOS 14+


if AVPictureInPictureController.isPictureInPictureSupported() {
    let pipController = AVPictureInPictureController(playerLayer: playerLayer!)
    pipController.delegate = self
    pipController.startPictureInPicture()
}

4. Thư viện cao cấp

  • AVPlayerViewController: Built-in UI controls (play/pause, slider, fullscreen, airplay)
  • VideoPlayer (SwiftUI): VideoPlayer(player: player)
  • Player (GitHub: piemonte/Player) - Wrapper đẹp, dễ dùng
  • Kingfisher + AVPlayer cho caching

Lưu ý

  • Audio file trong Bundle: dùng AVAudioPlayer (local, offline, hỗ trợ loop, rate, volume)
  • Streaming/Remote/Video: dùng AVPlayer
  • Luôn handle error (file missing, corrupt, format không hỗ trợ)
  • Memory: Release player khi không dùng (deinit, viewWillDisappear)
  • Background audio: Cần Capability "Audio, AirPlay, and Picture in Picture" + Audio Session config