Как кешировать аудио на локальный при воспроизведении аудио с avplayer

Я играю аудио онлайн с 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-адрес настраивается (например ,.

Кто знает причину, не поддерживает ли resourceLoader http/https?

3 ответа

Когда игрок не знает, как загрузить файл, он вызывает resourceLoader(resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource... метод. Так как он знает, как загрузить 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];

Реализация методов делегата будет выглядеть примерно так:

- (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 являются пользовательскими объектами для обработки полученных данных (подробности в ссылке).

Здесь вы можете найти полное решение Swift на основе нативного AVPlayerItem с пользовательским загрузчиком.

Другие вопросы по тегам