AVURLAsset для долгого звука на ipod

давний читатель, впервые спрашивающий ...

Я делаю музыкальное приложение, которое использует AVAssetReader для чтения mp3-данных из библиотеки itunes. Мне нужна точная синхронизация, поэтому, когда я создаю AVURLAsset, я использую «AVURLAssetPreferPreciseDurationAndTimingKey» для извлечения данных синхронизации. Это накладные расходы (и у меня нет проблем, когда я им не пользуюсь, но он мне нужен!)

Все отлично работает на iphone (4) и ipad (1). Я бы хотел, чтобы он работал на моем iPod Touch (2-го поколения). Но это не так: если звуковой файл слишком длинный (> ~ 7 минут), AVAssetReader не может начать чтение и выдает ошибку (ошибка AVFoundationErrorDomain -11800.)

Похоже, я упираюсь в стену с точки зрения ресурсов сканера iPod Touch. Есть идеи, что происходит, или как управлять накладными расходами на создание AVURLAsset, чтобы он мог обрабатывать длинные файлы? (Я пробовал запускать это с помощью инструментов повышения производительности, и я не вижу значительного всплеска памяти).

Спасибо, Дэн


person danI    schedule 19.05.2011    source источник


Ответы (1)


Может ты тоже начинаешь читать, сынок? Насколько я понимаю, для mp3 нужно будет пройти через весь файл, чтобы обеспечить точное время. Итак, попробуйте отложить чтение. Вы также можете попробовать зарегистрироваться в качестве наблюдателя для некоторых свойств AVAsset. iOS 4.3 имеет свойство «читабельность». Я никогда не пробовал, но предполагаю, что изначально он был установлен на NO, а как только AVAsset завершил загрузку, он был установлен на YES.

РЕДАКТИРОВАТЬ: На самом деле, только что заглянул в документы. Вы должны использовать для этого протокол AVAsynchronousKeyValueLoading, и Apple предоставляет пример.

NSURL *url = <#A URL that identifies an audiovisual asset such as a movie file#>;
AVURLAsset *anAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSArray *keys = [NSArray arrayWithObject:@"duration"];

[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {

    NSError *error = nil;
    AVKeyValueStatus durationStatus = [asset statusOfValueForKey:@"duration" error:&error];
    switch (durationStatus) {
        case AVKeyValueStatusLoaded:
            [self updateUserInterfaceForDuration];
            break;
        case AVKeyValueStatusFailed:
            [self reportError:error forAsset:asset];
            break;
        case AVKeyValueStatusCancelled:
            // Do whatever is appropriate for cancelation.
            break;
   }
}];

Если «продолжительность» не поможет, попробуйте «читабельный» (но, как я уже упоминал ранее, для «читабельного» требуется 4.3). Возможно, это решит вашу проблему.

person Alex Chugunov    schedule 19.05.2011
comment
Привет, Алекс, спасибо! Я использовал протокол loadValuesAsynchronouslyForKeys, но я использовал ключ треков вместо продолжительности. Похоже, что его выполнение по продолжительности действительно переключает работу по поиску накладных расходов на асинхронный поток, а не на [AVAssetReader startReading]. Здорово! - person danI; 19.05.2011