Подтвердить что ты не робот

AVPlayer "замораживает" приложение в начале буферизации аудиопотока

Я использую подкласс AVQueuePlayer, и когда я добавляю новый AVPlayerItem с потоковым URL, приложение зависает примерно секунду или два. Замерзая, я имею в виду, что он не реагирует на касания в пользовательском интерфейсе. Кроме того, если у меня уже есть песня, а затем добавьте еще одну в очередь, AVQueuePlayer автоматически запустит предварительную загрузку песни, пока она по-прежнему будет передавать первый. Это заставляет приложение не реагировать на касания в пользовательском интерфейсе в течение двух секунд, как при добавлении первой песни, но песня все еще воспроизводится. Таким образом, AVQueuePlayer делает что-то в основном потоке, что вызывает очевидное "замораживание".

Я использую insertItem:afterItem:, чтобы добавить мой AVPlayerItem. Я протестировал и убедился, что это был метод, который вызывал задержку. Возможно, это может быть что-то, что AVPlayerItem делает, когда оно активируется AVQueuePlayer в момент добавления его в очередь.

Необходимо указать, что я использую бета-версию Dropbox API v1 для получения URL-адреса потоковой передачи с помощью этого вызова метода:

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

Затем, когда я получаю URL-адрес потока, отправлю его на AVQueuePlayer следующим образом:

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

Итак, мой вопрос: как мне избежать этого? Должен ли я выполнять предварительную загрузку аудиопотока самостоятельно без помощи AVPlayer? Если да, то как это сделать?

Спасибо.

4b9b3361

Ответ 1

Не используйте playerItemWithURL его синхронизацию. Когда вы получите ответ с URL-адресом, попробуйте это:

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

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

Ответ 2

Ответ Gigisommo для Swift 3, включая отзывы от комментариев:

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)

        }

}