Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用avplayer播放音频时如何将音频缓存到本地_Ios_Swift_Avplayer_Avasset_Avurlasset - Fatal编程技术网

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

Ios 使用avplayer播放音频时如何将音频缓存到本地,ios,swift,avplayer,avasset,avurlasset,Ios,Swift,Avplayer,Avasset,Avurlasset,我使用AVPlayer在线播放音频,并希望在AVPlayer完成加载流时将音频数据/流保存到本地 我的实施方式如下: let fileUrl = NSURL(string: strUrl)! let asset = AVURLAsset(URL: fileUrl) asset.resourceLoader.setDelegate(self, queue:dispatch_queue_create("AVARLDelegateDemo loader", nil))

我使用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
}
- (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];
}
当url为http/https时,它不会调用resourceLoader(resourceLoader:AVAssetResourceLoader,ShouldWaitForLoadingFrequestedResource…-),当url为自定义(例如:“测试”)时,它会调用resourceLoader(resourceLoader:AVAssetResourceLoader,ShouldWaitForLoadingFrequestedResource…


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

当播放器不知道如何加载文件时,它会调用
resourceLoader(resourceLoader:AVAssetResourceLoader,应该等待LoadingFrequestedResource…
方法。因为它知道如何加载URL,所以它不会调用此方法,所以您必须传递自定义URL。

这似乎详细说明了您要查找的内容

上面的链接详细介绍了如何设置自定义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];
然后,委托方法的实现将类似于以下内容:

    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
}
- (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是用于处理所接收数据的自定义对象(详细信息请参见链接).

在这里,您可以找到基于本机AVPlayerItem的自定义加载程序。

1.这并不能真正回答他的问题,他问的是为什么AVAssetResourceLoader不能在http/https中工作。2.当您提出自己的书面库作为解决方案时,您应该披露您是上述库的作者这一事实。。。