Сначала сохраните объект AVPlayerItem в объекте NSPurgeableData и играйте с ним; хранить объект данных в объекте NSCache, чтобы автоматически вытеснять объект из памяти после его воспроизведения или когда соединение отбрасывается, а прежний элемент AVPlayerItem заменяется новым (все эти вещи, которые вы должны делать в любом случае, независимо от того, конкретную проблему, которую вы описываете).Вот код, чтобы вы начали:
void (^cachePlayerItem)(AVPlayerItem *, NSCache *, NSString *) = ^(AVPlayerItem *playerItem, NSCache *cache, NSString *key) {
NSURL *fileURL = [(AVURLAsset *)playerItem.asset URL];
NSPurgeableData *data = [NSPurgeableData dataWithContentsOfURL:fileURL];
[data beginContentAccess];
[cache setObject:data forKey:key];
[data endContentAccess];
[data discardContentIfPossible];
};
Поместите этот блок в любом месте в файле реализации, определив его в файле заголовка с:
typedef void (^cachePlayerItemBlock)(AVPlayerItem *, NSCache *, NSString *);
Называйте это в методе с:
cachePlayerItem(playerItem, playerItems, phAsset.localIdentifier);
Принимая во внимание, что playerItem является элементом AVPlayerItem, playerItems является кешем NSCache и, в зависимости от того, какой вид актива, из которого вы приобретаете AVPlayerItem, уникальным для него идентификатором (или, в приведенном выше примере, связанный с ним актив).
Кстати, я создал свои кэши в AppDelegate соответственно:
- (NSCache *)thumbnailCache {
__block NSCache *t = self->_thumbnailCache;
if (!t) {
t = [[NSCache alloc] init];
[t setName:@"Thumbnail Cache"];
[t setEvictsObjectsWithDiscardedContent:TRUE];
[t setCountLimit:self.assetsFetchResults.count];
self->_thumbnailCache = t;
}
return t;
}
Это обеспечивает не только глобальный доступ, но и один экземпляр, кэш, что особенно важно, когда кэширование AVPlayerItems как они могут быть большого размера.
Для создания глобально доступного кэша в AppDelegate, добавить их в ваш заголовок и реализации файлов, соответственно:
+ (AppDelegate *)sharedAppDelegate;
... и:
+ (AppDelegate *)sharedAppDelegate
{
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
Для ссылки на кэш в другом классе файлы, импортировать заголовочный файл AppDelegate и, при желании, создать ярлык для метода sharedApplication приложения AppDelegate:
#import "AppDelegate.h"
#define AppDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])
Insodoing, кэш может ссылаться ...:
AppDelegate.thumbnailCache
... вместо:
AppDelegate.sharedAppDelegate.thumbnailCache
спасибо за большой ответ. Я использую GCD для загрузки файла. 'dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{...' Я попытался использовать '[AVURLAsset initWithUrl: options:]', и я попытался инициализировать AVPlayerItem этим ресурсом. Элемент инициализирован, но по-прежнему не имеет треков. Вероятно, я не очищаю экземпляр должным образом, но я вижу в коде, что все наблюдатели удалены, и avplayeritem (также avplayer.currentitem и т. Д.) Установлены на нуль, когда что-то пойдет не так.) – travdu
'AVAsset' имеет свойство' track' так что вы можете получить информацию о предыстории. Поэтому, если вы ожидаете 2 трека, и вы получите 1, вы знаете, что что-то пошло не так. Я ожидаю, что в процессе инициализации произошла ошибка, и поэтому у вас есть проблемы. Либо это, либо вы загрузили поврежденный файл. –
Я ожидаю один трек, и я получаю 0. Файл в порядке, потому что, когда я запускаю приложение и пытаюсь снова получить тот же файл, все работает нормально. У меня проблема только в том случае, если initWithUrl прерван с потерей соединения. Затем каждый раз после прерывания я получаю 0 треков, даже когда вы присоединяетесь к другим файлам. Как я говорю. Когда соединение не теряется во время init, все работает отлично, а также при обращении к другим файлам позже. – travdu