web-dev-qa-db-fra.com

Avplayer "gèle" l'application au début de la mise en mémoire tampon d'un flux audio

J'utilise une sous-classe de AVQueuePlayer et quand j'ajouterai de nouveau AVPlayerItem avec une URL de diffusion de la diffusion, l'application gèle environ une seconde ou deux. En gelant, je veux dire qu'il ne répond pas aux touches de l'interface utilisateur. En outre, si j'ai déjà une chanson qui joue, ajoutez-en une autre à la file d'attente, AVQueuePlayer commence automatiquement à précharger la chanson pendant qu'elle diffuse toujours le premier. Cela rend l'application ne répond pas aux touches de l'interface utilisateur pendant deux secondes, comme lors de l'ajout de la première chanson, mais la chanson joue toujours. Donc, cela signifie que AVQueuePlayer fait quelque chose dans le fil principal qui provoque le "gel" apparent.

J'utilise insertItem:afterItem: Pour ajouter mon AVPlayerItem. J'ai testé et je suis sûr que c'était la méthode qui causait le retard. Peut-être que cela pourrait être quelque chose que AVPlayerItem fait quand il est activé par AVQueuePlayer au moment de l'ajouter à la file d'attente.

Il faut souligner que j'utilise l'API Dropbox V1 Beta pour obtenir l'URL de diffusion en continu à l'aide de cette méthode appel:

[[self restClient] loadStreamableURLForFile:metadata.path];

Ensuite, lorsque je reçois l'URL du flux, je l'envoie à AVQueuePlayer comme suit:

[self.player insertItem:[AVPlayerItem playerItemWithURL:url] afterItem:nil];

Donc, ma question est la suivante: comment puis-je éviter cela? Dois-je faire la précharge d'un flux audio seul sans l'aide de AVPlayer? Si oui, comment puis-je faire cela?

Merci.

48
raixer

N'utilisez pas playerItemWithURL il est synchronisé. Lorsque vous recevez la réponse avec l'URL, essayez ceci:

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSArray *keys = @[@"playable"];

[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {
    [self.player insertItem:[AVPlayerItem playerItemWithAsset:asset] afterItem:nil];
}];
69
Gigisommo

Réponse de Gigisommo pour SWIFT y compris les commentaires des commentaires:

let asset = AVAsset(url: url)
let keys: [String] = ["playable"]

asset.loadValuesAsynchronously(forKeys: keys) { 

        DispatchQueue.main.async {

            let item = AVPlayerItem(asset: asset)
            self.playerCtrl.player = AVPlayer(playerItem: item)

        }

}
5
David Seek