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.