AVPlayerViewController è un controller di lettore video integrato nell'ecosistema Apple, progettato per la riproduzione di contenuti multimediali su iOS e tvOS. Fornisce un'interfaccia a schermo intero con controlli, supporto per i sottotitoli e AirPlay senza la necessità di scrivere un'interfaccia utente personalizzata. Secondo la Documentazione Apple Developer, 2026, AVPlayerViewController si integra in poche righe di codice e supporta HLS, MP4 e la maggior parte dei formati multimediali.
Punti chiave
AVPlayerViewController è un componente del framework AVKit che fornisce un'interfaccia pronta per riprodurre video nelle applicazioni Apple. Solleva lo sviluppatore dalla necessità di creare un lettore personalizzato da zero, offrendo controlli standard: riproduzione/pausa, avanzamento, regolazione del volume e modalità schermo intero.
A differenza di AVPlayerLayer di basso livello, che richiede la costruzione manuale dell'interfaccia utente, AVPlayerViewController gestisce completamente il ciclo di vita del lettore. Il controller gestisce automaticamente la rotazione dello schermo, si adatta all'area sicura sugli iPhone con notch e supporta il multitasking su iPad.
Secondo la Documentazione Apple (2026), AVPlayerViewController è compatibile con AVPlayer e AVQueuePlayer, consentendo di riprodurre sia file singoli che playlist. Sono supportati URL da archiviazione locale, flussi di rete HLS e contenuti FairPlay crittografati.
Il componente è apparso in iOS 8 insieme ad AVKit come sostituto del deprecato MPMoviePlayerController. In iOS 11 è stato aggiunto il supporto per Picture in Picture e la visualizzazione dei sottotitoli. In iOS 14, il controller ha ricevuto una barra di trasporto personalizzabile tramite AVPlayerViewControllerDelegate. A partire da iOS 16, è stato introdotto il supporto per la sostituzione dinamica dei file multimediali senza ricreare il lettore.
L'AVPlayerViewController moderno è ottimizzato per i display ProMotion — la frequenza dei fotogrammi video si sincronizza automaticamente con la frequenza di aggiornamento dello schermo. Su tvOS, il componente si adatta all'interfaccia di focus del Siri Remote e su macOS alla modalità finestra del QuickTime Player.
Al centro del controller si trova l'abbinamento di AVPlayer e AVPlayerItem. AVPlayer è l'oggetto di riproduzione che gestisce la timeline, la velocità e lo stato. AVPlayerItem è un wrapper attorno a un file multimediale specifico, contenente metadati, tracce e informazioni di caricamento.
Quando viene inizializzato, AVPlayerViewController riceve un riferimento ad AVPlayer e crea automaticamente un AVPlayerLayer per visualizzare il video. Il controller si abbina alle notifiche KVO di AVPlayer sui cambiamenti di stato come readyToPlay, errori di caricamento e completamento della riproduzione.
I controlli (barra di trasporto) vengono visualizzati toccando lo schermo. In iOS 15+, supportano la personalizzazione tramite AVPlayerViewControllerCustomizationDelegate, consentendo di nascondere o sostituire i pulsanti standard.
Dopo aver creato il controller e assegnato AVPlayer, viene chiamato il metodo viewDidLoad, che inizia a preparare il flusso video. Quando AVPlayerItem passa allo stato AVPlayerItemStatusReadyToPlay, il lettore è pronto per visualizzare i fotogrammi. Quando viene chiamato il metodo play(), inizia la decodifica del flusso video tramite Video Toolbox.
Quando si lascia lo schermo, il controller mette automaticamente in pausa la riproduzione e rilascia le risorse del decodificatore. In iOS 13+, per mantenere la riproduzione quando l'app viene minimizzata, è necessario configurare le Modalità di background e la Sessione audio. Secondo WWDC 2024, si consiglia di utilizzare AVPlayerPlaybackCoordinator per la sincronizzazione con il centro multimediale iOS.
Il componente fornisce un ricco set di funzionalità pronte all'uso, rendendolo interessante per la maggior parte dei progetti. Di seguito sono elencate le capacità principali che non richiedono codice aggiuntivo.
La barra di trasporto è la parte inferiore dell'interfaccia che contiene i pulsanti di controllo principali. Per impostazione predefinita, la barra si nasconde dopo 3 secondi di inattività dell'utente e appare al tocco. In iOS 16+, il delegato può essere utilizzato per controllare la visibilità dei singoli elementi.
In modalità debug, la barra di trasporto può essere forzata a mostrarsi utilizzando la proprietà AVPlayerViewController.requiresLinearPlayback, che impedisce anche la messa in pausa del video. Utile per interruzioni pubblicitarie e contenuti educativi.
L'integrazione di base del controller non richiede più di 10 righe di codice. Innanzitutto, crea un'istanza di AVPlayer con l'URL del file multimediale, quindi passala ad AVPlayerViewController e visualizza il controller sullo schermo.
import AVKit
let player = AVPlayer(url: URL(string: "https://example.com/video.mp4")!)
let playerVC = AVPlayerViewController()
playerVC.player = player
present(playerVC, animated: true) {
player.play()
}
Dopo aver chiamato present, il controller viene visualizzato a schermo intero. Il video inizia a caricarsi dalla rete e, una volta che il buffer raggiunge la soglia readyToPlay, la riproduzione inizia automaticamente dopo la chiamata a play().
let asset = AVAsset(url: videoURL)
let item = AVPlayerItem(asset: asset)
let metadata = AVMutableMetadataItem()
metadata.key = AVMetadataKey.commonKeyTitle
metadata.value = "Il Mio Video"
item.addMetadata(metadata)
let player = AVPlayer(playerItem: item)
let playerVC = AVPlayerViewController()
playerVC.player = player
L'uso di AVPlayerItem ti dà il controllo su metadati, timecode, selezione delle tracce audio e sottotitoli. Tramite AVPlayerItem, puoi anche monitorare l'avanzamento del caricamento, il buffering e gli errori di rete utilizzando KVO sulla proprietà status.
A partire da iOS 11, gli sviluppatori possono personalizzare la barra di trasporto tramite il protocollo AVPlayerViewControllerDelegate. Il metodo playerViewController(_:willBeginFullScreenPresentationWithAnimationCoordinator:) viene chiamato prima di entrare in modalità schermo intero e consente di preparare l'interfaccia utente.
Per nascondere i singoli pulsanti, usa la proprietà AVPlayerViewController.showsPlaybackControls. Se impostata su false, la barra di trasporto scompare completamente, lasciando solo il flusso video. Utile per elementi sovrapposti personalizzati.
class CustomPlayerViewController: UIViewController {
private let playerVC = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
playerVC.delegate = self
playerVC.showsPlaybackControls = true
playerVC.entersFullScreenWhenPlaybackBegins = true
}
}
extension CustomPlayerViewController: AVPlayerViewControllerDelegate {
func playerViewController(
_ playerViewController: AVPlayerViewController,
willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator
) {
// Aggiungi pulsante overlay
}
func playerViewController(
_ playerViewController: AVPlayerViewController,
didUpdate legibleMediaSelection: AVMediaSelectionGroup
) {
print("Nuova lingua sottotitoli selezionata")
}
}
Il delegato consente di intercettare gli eventi di cambio sottotitoli, l'entrata e l'uscita dalla modalità schermo intero, nonché l'avvio e la fine di Picture in Picture. Alla WWDC 2024, Apple ha raccomandato di utilizzare il delegato per l'analisi — registrare ogni transizione entro 100 ms.
AVPlayerViewController visualizza automaticamente tutti i sottotitoli e le tracce audio disponibili se sono incorporati nel file multimediale o specificati nel manifesto HLS. Gli utenti possono cambiarli tramite il menu che appare toccando l'icona dei sottotitoli nella barra di trasporto.
Per i flussi HLS, il manifesto M3U8 contiene un elenco di varianti linguistiche disponibili. AVPlayer carica i segmenti di sottotitoli WebVTT corrispondenti e li passa ad AVPlayerLayer per il rendering. iOS 16+ ha introdotto il supporto per lo stile dei sottotitoli tramite AVTextStyleRule.
func selectAudioTrack(languageCode: String) {
guard let group = player.currentItem?
.asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.audible)
else { return }
for option in group.options {
if option.extendedLanguageTag?.hasPrefix(languageCode) == true {
player.currentItem?.select(option, in: group)
}
}
}
Il metodo selectAudioTrack cerca tra le opzioni audio del gruppo audible la variante il cui extendedLanguageTag corrisponde al codice lingua desiderato. Ciò consente di implementare la funzione “Audio originale” nelle app con contenuti multilingue.
La modalità Picture in Picture (PiP) consente di visualizzare il video in una finestra fluttuante sopra altre app. Su iPad, questa funzione è disponibile da iOS 9, su iPhone da iOS 14. AVPlayerViewController aggiunge automaticamente un pulsante PiP alla barra di trasporto quando si è abbonati a UIBackgroundModes.
Per attivare PiP, aggiungi la chiave UIBackgroundModes con i valori audio e airplay a Info.plist. Successivamente, appare un pulsante PiP nel controller che, quando toccato, riduce il video in una finestra fluttuante di 192x108 punti.
Gli eventi PiP vengono gestiti tramite il delegato: playerViewController(_:willStartPictureInPictureFromFullScreen:) e playerViewController(_:didStopPictureInPicture:). Secondo Apple HIG, la dimensione minima della finestra PiP dovrebbe essere di almeno 120x68 punti per mantenere la leggibilità del contenuto.
Domande frequenti
No, i video YouTube richiedono l'uso di una vista web WKWebView o della libreria YouTube iOS Helper, poiché YouTube utilizza il proprio sistema DRM. AVPlayerViewController è progettato per flussi multimediali diretti tramite URL.
Imposta la proprietà showsPlaybackControls su false. Successivamente, lo schermo rimane vuoto — solo il flusso video. Per ripristinare i pulsanti personalizzati, aggiungi una sovrapposizione tramite addSubview sopra il controller.
Sì, il controller supporta completamente HLS Live. La barra di trasporto mostra un indicatore In diretta invece di un cursore di avanzamento. La latenza dipende dalla configurazione HLS — minimo 6 secondi con impostazioni di bassa latenza.
Abbonati a KVO sulla proprietà AVPlayerItem.status. In caso di errore, lo stato passa a .failed. Ottieni i dettagli tramite la proprietà error di AVPlayerItem e mostra un avviso all'utente spiegando il problema — spesso è un problema di rete o un URL non valido.
Sì, usa AVAsset con un AVAssetResourceLoader personalizzato per fornire dati dalla RAM. Implementa AVAssetResourceLoaderDelegate e restituisci byte da un buffer invece di leggere dal disco.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche