如何在使用avplayer播放音频时将音频缓存到本地

问题描述:

我使用AVPlayer在线播放音频,并且希望在avplayer完成加载流时将音频数据/音频流保存到本地。如何在使用avplayer播放音频时将音频缓存到本地

我implementt它为以下几点:

let fileUrl = NSURL(string: strUrl)! 
    let asset = AVURLAsset(URL: fileUrl) 
    asset.resourceLoader.setDelegate(self, queue:dispatch_queue_create("AVARLDelegateDemo loader", nil)) 
    self.pendingRequests = [AVAssetResourceLoadingRequest]() 

    asset.loadValuesAsynchronouslyForKeys(["playable"]){ 
     dispatch_async(dispatch_get_main_queue()){ 
      self.prepareToPlayAsset(asset, requestedKeys: ["playable"]) 
     } 
    } 


    func resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool { 
    ....... 
    return false 
} 

当网址为HTTP/HTTPS,它不调用资源加载(资源加载:AVAssetResourceLoader,shouldWaitForLoadingOfRequestedResource ... - ,当URL是定制(eg.:'test'),它调用资源加载(资源加载:AVAssetResourceLoader,shouldWaitForLoadingOfRequestedResource ...

谁知道其中的原因,难道没有资源加载支持http/https?

当播放器不知道如何加载文件时,它调用resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource...方法。因为它知道如何加载URL,所以不会调用这个方法,所以你必须传递自定义URL。

这个sample project and tutorial似乎是你要找的细节。

上面的链接设置自定义URL方案并设置AVAssetResourceLoaderDelegate以在加载时处理资源。这被初始化为:

NSURL *url = [NSURL URLWithString:@"customscheme://host/audio.mp3"]; 
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; 
[asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()]; 

AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; 
[self addObserversForPlayerItem:item]; 

self.player = [AVPlayer playerWithPlayerItem:playerItem]; 
[self addObserversForPlayer]; 

的委托方法的实施将随后类似于以下内容:

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest*)loadingRequest{ 

    NSURL *resourceURL = [loadingRequest.request URL]; 

    if([resourceURL.scheme isEqualToString:@"customscheme"]){ 
     LSFilePlayerResourceLoader *loader = [self resourceLoaderForRequest:loadingRequest]; 

     if(loader==nil){ 
      loader = [[LSFilePlayerResourceLoader alloc] initWithResourceURL:resourceURL session:self.session]; 
      loader.delegate = self; 
      [self.resourceLoaders setObject:loader forKey:[self keyForResourceLoaderWithURL:resourceURL]]; 
     } 

     [loader addRequest:loadingRequest]; 

     return YES; 
    } 
    return NO; 
} 

- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest{ 

    LSFilePlayerResourceLoader *loader = [self resourceLoaderForRequest:loadingRequest]; 

    [loader removeRequest:loadingRequest]; 
} 

凡LSFilePlayerResourceLoader和LSFilePlayerResourceLoader是处理接收到的数据自定义对象(在详细链接)。

在这里你可以找到full Swift solution基于本地AVPlayerItem与自定义加载程序。

+1

1.这并没有真正回答他的问题,他询问为什么AVAssetResourceLoader不能在http/https中工作。 2.当你提出你自己写的图书馆作为解决方案时,你应该透露你是这个图书馆的作者的事实...... –