Как кешировать аудио на локальный при воспроизведении аудио с 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 с пользовательским загрузчиком.