【问题标题】:How to cache audio to local when playing audio with avplayer使用avplayer播放音频时如何将音频缓存到本地
【发布时间】:2015-11-04 09:45:19
【问题描述】:

我使用 AVPlayer 在线播放音频,并希望在 avplayer 加载完流后将音频的数据/流保存到本地。

我实现如下:

    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
}

当url为http/https时,不调用resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource.... -, 自定义url时(eg.:' test'),它调用 resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource...

谁知道原因,resourceLoader不支持http/https吗?

【问题讨论】:

    标签: ios swift avplayer avasset avurlasset


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这个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 是用于处理正在接收的数据的自定义对象(在链接中有详细说明)。

      【讨论】:

        【解决方案3】:

        在这里你可以找到full Swift solution 基于原生 AVPlayerItem 和自定义加载器。

        【讨论】:

        • 1.这并没有真正回答他的问题,他在问为什么 AVAssetResourceLoader 在 http/https 中不起作用。 2.当您提出自己编写的库作为解决方案时,您应该披露您是该库的作者的事实......
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-16
        • 2019-08-20
        • 1970-01-01
        • 1970-01-01
        • 2011-11-21
        • 2022-01-10
        相关资源
        最近更新 更多