Skip to main content

Working with Media Playback

1. Using AVPlayer for Video Playback

Property Value Description
player AVPlayer? The player object that manages playback of a media resource
currentItem AVPlayerItem? The current media item being played
rate Float The playback rate (1.0 = normal speed)
volume Float The volume level (0.0 to 1.0)

Example: Initialize AVPlayer with a video URL

import AVFoundation

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

Example: Play video using AVPlayerLayer

import AVKit

let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = view.bounds
view.layer.addSublayer(playerLayer)

player.play()

Example: Handle playback state changes

let observer = player.addPeriodicTimeObserver(
    forInterval: CMTimeMake(value: 1, timescale: 1),
    queue: .main
) { time in
    print("Current time: \(time.seconds)")
}
Note: Ensure AVAudioSession is configured properly for audio playback.
Warning: AVPlayer does not support live streaming in all formats. Check compatibility for HLS streams.

2. Using AVPlayerViewController

Example: Basic AVPlayerViewController Setup

import AVKit
import AVFoundation

class MediaViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        guard let url = Bundle.main.url(forResource: "sample", withExtension: "mp4") else {
            return
        }
        
        let player = AVPlayer(url: url)
        let controller = AVPlayerViewController()
        controller.player = player
        
        addChild(controller)
        view.addSubview(controller.view)
        controller.didMove(toParent: self)
        
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            controller.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            controller.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            controller.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            controller.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
    }
}
Property Type Description
player AVPlayer? The player object to control media playback
showsPlaybackControls Bool Whether to display default playback controls (default: true)
videoGravity AVLayerVideoGravity How to scale video content (e.g., resizeAspect)
Note: AVPlayerViewController provides built-in controls and supports AirPlay.
Warning: Ensure the player is not nil before setting it to AVPlayerViewController.

3. Controlling Playback

Property Description Values
playbackState Current state of the media player .idle, .playing, .paused, .stopped
rate Playback rate (1.0 = normal speed) 0.0 to 4.0
currentTime Current playback position in seconds Double
duration Total duration of the media in seconds Double

Example: Controlling Playback

import AVFoundation

let player = AVPlayer(url: mediaURL)
player.play()
player.rate = 1.5
player.seek(to: CMTime(seconds: 30, preferredTimescale: 1))
Note: Use AVPlayer for media playback control in iOS Swift.

4. Observing Playback State

Property Description Notes
playbackState Current state of the media playback Read-only property indicating if media is playing, paused, or stopped
rate Playback rate of the media 1.0 = normal speed, 0.0 = paused, < 0 = reverse
currentTime Current playback position in seconds Can be used to seek to a specific time
duration Total duration of the media in seconds Read-only property, returns 0 if unknown

Example: Observing Playback State Changes

import AVFoundation

class MediaPlaybackObserver: NSObject {
    private let player = AVPlayer()
    
    func observePlaybackState() {
        // Observe playback state changes
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(playbackStateChanged),
            name: .AVPlayerItemDidPlayToEndTime,
            object: player.currentItem
        )
        
        // Observe rate changes
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(rateChanged),
            name: .AVPlayerRateDidChange,
            object: player
        )
    }
    
    @objc private func playbackStateChanged() {
        print("Playback completed")
    }
    
    @objc private func rateChanged() {
        print("Rate changed to: \(player.rate)")
    }
}
Note: Use AVPlayerItemDidPlayToEndTime to detect when playback finishes.
Warning: Always remove observers in deinit to prevent memory leaks.

5. Playing Audio with AVAudioPlayer

Property Value Description
delegate AVAudioPlayerDelegate? Object that receives audio player events
numberOfChannels Int Number of audio channels
duration TimeInterval Total duration of the audio file in seconds
currentTime TimeInterval Current playback position in seconds
volume Float Volume level (0.0 to 1.0)
rate Float Playback rate (1.0 = normal speed)
pan Float Panning position (-1.0 = left, 0.0 = center, 1.0 = right)
isPlaying Bool Indicates whether audio is currently playing

Example: Initialize and Play Audio

import AVFoundation

class AudioPlayerManager {
    var audioPlayer: AVAudioPlayer?

    func playAudio(named fileName: String) {
        guard let url = Bundle.main.url(forResource: fileName, withExtension: "mp3") else {
            print("Could not find audio file")
            return
        }

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.delegate = self
            audioPlayer?.play()
        } catch {
            print("Error initializing audio player: \(error)")
        }
    }
}

extension AudioPlayerManager: AVAudioPlayerDelegate {
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("Finished playing audio")
    }
}

Example: Set Volume and Rate

audioPlayer?.volume = 0.7
audioPlayer?.rate = 1.2 // Play at 1.2x speed
Note: Ensure audio session is configured properly before playing audio using AVAudioSession.
Warning: AVAudioPlayer does not support streaming audio from URLs directly. Use AVPlayer for streaming.

6. Using AVAudioSession for Audio Configuration

Property Description Values
category Sets the audio session category to define how audio is used .playback, .record, .playAndRecord, .ambient
mode Defines the audio mode for specific use cases .default, .spokenAudio, .videoRecording
active Activates or deactivates the audio session true, false

Example: Setting up AVAudioSession

import AVFoundation

do {
    let audioSession = AVAudioSession.sharedInstance()
    try audioSession.setCategory(.playback)
    try audioSession.setMode(.default)
    try audioSession.setActive(true)
} catch {
    print("Audio session setup failed: \(error)")
}
Note: Always call setActive(true) to activate the session before starting playback.
Warning: Changing audio session categories can interrupt other apps' audio playback.

7. Implementing Background Audio Playback

Background audio playback in iOS allows apps to continue playing audio while the app is in the background. This capability is essential for music players, podcast apps, and other audio-based applications.

Property Value Description
AVAudioSession.Category .playback Enables background audio playback. Must be set before activating the session.
AVAudioSession.Mode .default or .spokenAudio Configures the audio session mode. .spokenAudio is used for voice-based apps.
AVAudioSession.CategoryOptions .allowBluetooth, .mixWithOthers Allows mixing with other audio and Bluetooth device support.

Example: Setting up background audio session

import AVFoundation

do {
    try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.allowBluetooth, .mixWithOthers])
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print("Failed to set up audio session: \(error)")
}
Note: Ensure that your app has the necessary background modes enabled in Info.plist for audio playback to function correctly in the background.

Example: Handling audio session interruption

import AVFoundation

@objc func handleInterruption(_ notification: Notification) {
    guard let interruption = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt else { return }
    
    switch interruption {
    case AVAudioSession.InterruptionType.began.rawValue:
        // Pause playback
        player?.pause()
    case AVAudioSession.InterruptionType.ended.rawValue:
        // Resume playback if interruption was not due to an app switch
        if let options = notification.userInfo?[AVAudioSessionInterruptionOptionKey] as? UInt {
            if options & AVAudioSession.InterruptionOptions.shouldResume.rawValue != 0 {
                player?.play()
            }
        }
    default:
        break
    }
}

8. Handling Audio Interruptions

Scenario Description Action
Audio Session Category Set to .playback or .ambient Use AVAudioSession.Category.playback to allow audio to continue playing during interruptions.
Interruption Notification Listen for AVAudioSession.interruptionNotification Register observer to handle interruption events.
Interruption Type Types: .began, .ended Check AVAudioSessionInterruptionTypeKey in notification payload.

Example: Handling Audio Interruptions

import AVFoundation

class AudioPlayerManager {
    private let audioSession = AVAudioSession.sharedInstance()
    
    func setupAudioSession() {
        do {
            try audioSession.setCategory(.playback)
            try audioSession.setActive(true)
        } catch {
            print("Failed to set up audio session: \(error)")
        }
    }
    
    func handleInterruption(_ notification: Notification) {
        guard let type = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt else { return }
        
        switch type {
        case AVAudioSessionInterruptionType.began.rawValue:
            // Pause playback
            print("Audio interruption began")
        case AVAudioSessionInterruptionType.ended.rawValue:
            // Resume playback if needed
            print("Audio interruption ended")
        default:
            break
        }
    }
}
Note: When an interruption occurs (e.g., phone call), your app should pause playback and resume it when the interruption ends.

9. Using Media Player Framework

Property Value Description
AVPlayer AVPlayer(url: URL) Initializes a new AVPlayer with a media URL
AVPlayerViewController AVPlayerViewController() Creates a view controller to display media content
playbackState .playing, .paused, .stopped Current state of media playback

Example: Play Media Using AVPlayer

import AVFoundation

let url = URL(string: "https://example.com/media.mp4")!
let player = AVPlayer(url: url)
player.play()

Example: Display Media in ViewController

import AVKit

let player = AVPlayer(url: url)
let playerViewController = AVPlayerViewController()
playerViewController.player = player

present(playerViewController, animated: true) {
    player.play()
}

10. Accessing Music Library with MPMediaQuery

Property Description Example
MPMediaQuery.songs Returns a query for all songs in the user's music library let query = MPMediaQuery.songs()
MPMediaQuery.albums Returns a query for all albums in the user's music library let query = MPMediaQuery.albums()
MPMediaQuery.artists Returns a query for all artists in the user's music library let query = MPMediaQuery.artists()
MPMediaQuery.playlists Returns a query for all playlists in the user's music library let query = MPMediaQuery.playlists()

Example: Fetching Songs from Library

import MediaPlayer

let query = MPMediaQuery.songs()
query.addFilterPredicate(MPMediaPropertyPredicate(value: "Song Title", forProperty: MPMediaItemPropertyTitle))

if let items = query.items {
    for item in items {
        print(item.title ?? "Unknown Title")
    }
}
Note: You must request permission to access the user's media library using MPMediaLibrary.requestAuthorization.
Warning: Accessing the media library requires appropriate entitlements and may not work in all sandboxed environments.

11. Implementing Now Playing Info

Property Value Description
title String Title of the media item
artist String Artist or performer of the media item
albumTitle String Album title of the media item
artwork UIImage Album artwork for the media item
duration Double Total duration of the media item in seconds
playbackRate Float Current playback rate (1.0 = normal speed)

Example: Setting Up Now Playing Info

import MediaPlayer

let nowPlayingInfo = [
    MPMediaItemPropertyTitle: "Song Title",
    MPMediaItemPropertyArtist: "Artist Name",
    MPMediaItemPropertyAlbumTitle: "Album Name",
    MPMediaItemPropertyArtwork: MPMediaItemArtwork(boundsSize: CGSize(width: 100, height: 100)) { _ in
        UIImage(named: "albumArt")
    },
    MPMediaItemPropertyPlaybackDuration: 180.0,
    MPNowPlayingInfoPropertyElapsedPlaybackTime: 30.0
] as [String: Any]

MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
Note: The MPNowPlayingInfoCenter must be updated whenever the playback state changes to keep the lock screen and control center in sync.

Was this article helpful?