0

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

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

假设我们有以下内容:

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

1. 应该怎么做?同时丢失连接时 avPlayerItem 的实例会发生什么情况?是否有一些协议可以实现以确定初始化是否成功?

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

4

2 回答 2

1

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

应该做什么?

1)在后台线程上执行所有依赖互联网连接的代码。您不想阻塞 UI。

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

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

AVAsset下载后,我会使用临时 URL初始化一个。AVAsset有一些像这样的好属性playable将帮助您检查文件下载是否正常。(NSURLConnectionDelegate还有一个通知下载是否出错的方法。)

如果你已经走到了这一步,那么你可以创建一个AVPlayerItem带着AVAsset你走的路。如果您没有挂在下载的内容上,请记住在某个时候擦除临时文件夹的内容。

请记住,您想在主线程上播放文件,但所有其他加载和检查可能最好在后台线程上完成;你肯定想NSURLConnection从后台线程中使用。

于 2015-09-16T22:55:47.153 回答
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;
}

这不仅确保了对缓存的全局访问,而且还确保了缓存的一个实例,这在缓存 AVPlayerItems 时尤其重要,因为它们的大小可能很大。

要在 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
于 2016-10-22T11:54:59.717 回答