我正在使用“initWithUrl:”方法初始化AVPlayerItem。
问题是初始化中断时(例如连接丢失)
假设我们有以下内容:
self.avPlayerItem = [[AVPlayerItem alloc] initWithUrl:url];
1。 应该做什么?当连接丢失时,avPlayerItem的实例会发生什么? 是否有一些协议要实现,以确定初始化是否成功?
2。 我注意到的是,一旦初始化被中断,那么avPlayerItem的下一次“成功”初始化根本没有轨道(它们在之前没有中断的情况下存在) 要从源用户再次使用轨道初始化avPlayerItem,需要再次关闭并打开应用程序。
答案 0 :(得分:1)
在处理依赖于互联网连接的代码时,你必须确保在出现问题时会出现故障,因为在某些时候会出现故障。
应该做什么?
1)在后台线程上执行所有依赖互联网连接的代码。你不想阻止用户界面。
2)如果可能,请在使用前验证下载的文件。
有不同的方法可以解决这个问题,但我认为我会使用NSURLConnection
或类似的API将文件下载到临时文件夹中。在背景线上。
下载后,我会使用临时URL初始化AVAsset
。 AVAsset
有一些不错的属性,例如playable
,可以帮助您检查文件下载是否正常。 (NSURLConnectionDelegate
还有一个方法可以通知下载是否有错误。)
如果您已经做到这一点,那么您可以使用AVPlayerItem
创建AVAsset
,然后离开。如果您没有挂在下载的内容上,请记得在某些时候擦除临时文件夹的内容。
请记住,您希望在主线程上播放文件,但所有其他加载和检查可能最好在后台线程上完成;你肯定想在后台主题中使用NSURLConnection
。
答案 1 :(得分:0)
首先将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;
}
这不仅可以确保缓存的全局访问,还可以确保缓存的一个实例,这在缓存AVPlayerItem时尤其重要,因为它们的大小可能很大。
要在AppDelegate中创建全局可访问的缓存,请分别将这些缓存添加到标头和实现文件中:
+ (AppDelegate *)sharedAppDelegate;
...和
+ (AppDelegate *)sharedAppDelegate
{
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
要引用其他类文件中的缓存,请导入AppDelegate头文件,并根据需要创建AppDelegate的sharedApplication方法的快捷方式:
#import "AppDelegate.h"
#define AppDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])
Insodoing,缓存可以由......引用:
AppDelegate.thumbnailCache
...而不是:
AppDelegate.sharedAppDelegate.thumbnailCache