5

我使用 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吗?

4

3 回答 3

3

When player doesn't know how to load a file, it calls resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource... method. So since it knows how to load URL, it wont call this method, so you have to pass custom URL.

于 2016-02-05T14:31:09.077 回答
2

这个示例项目和教程似乎详细说明了您正在寻找的内容。

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

于 2016-03-31T08:13:57.687 回答
0

在这里,您可以找到基于本机 AVPlayerItem 和自定义加载器的完整 Swift 解决方案。

于 2016-07-11T23:10:59.143 回答