如何重新启动AVPlayerItem?

时间:2015-09-16 17:15:53

标签: ios objective-c avplayeritem

我正在使用“initWithUrl:”方法初始化AVPlayerItem。

问题是初始化中断时(例如连接丢失)

假设我们有以下内容:

self.avPlayerItem = [[AVPlayerItem alloc] initWithUrl:url];

1。 应该做什么?当连接丢失时,avPlayerItem的实例会发生什么? 是否有一些协议要实现,以确定初始化是否成功?

2。 我注意到的是,一旦初始化被中断,那么avPlayerItem的下一次“成功”初始化根本没有轨道(它们在之前没有中断的情况下存在) 要从源用户再次使用轨道初始化avPlayerItem,需要再次关闭并打开应用程序。

2 个答案:

答案 0 :(得分:1)

在处理依赖于互联网连接的代码时,你必须确保在出现问题时会出现故障,因为在某些时候会出现故障。

  

应该做什么?

1)在后台线程上执行所有依赖互联网连接的代码。你不想阻止用户界面。

2)如果可能,请在使用前验证下载的文件。

有不同的方法可以解决这个问题,但我认为我会使用NSURLConnection或类似的API将文件下载到临时文件夹中。在背景线上。

下载后,我会使用临时URL初始化AVAssetAVAsset有一些不错的属性,例如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