Czy jest możliwe wysyłanie nagłówków z żądaniem http do pliku audio podczas korzystania z AVPlayera? Muszę mieć możliwość sprawdzenia zawartości nagłówka po otrzymaniu przez serwer w celu ograniczenia dostępu do żądanego pliku.Wysyłaj nagłówki z żądaniem AVPlayer w iOS
Odpowiedz
Będziesz musiał zażądać danych samodzielnie za pośrednictwem ogólnego mechanizmu połączenia HTTP, takiego jak NSURLConnection
. Jeśli nagłówki w NSHTTPURLResponse
„s zdać egzamin, to należy zapisać go do NSCachesDirectory
i zdać się adres URL do tego zasobu do AVPlayer
tak:
NSData *data = //your downloaded data.
NSString *filePath = //generate random path under NSCachesDirectory
[data writeToFile:filePath atomically:YES];
AVPlayer *player = [AVPlayer playerWithURL:[NSURL fileURLWithPath:filePath]];
//...
pełny kod mógłby wyglądać następująco
#pragma Mark Sound Stuff
- (void)playSound:(NSString *)filePath
{
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:filePath]];
[playerItem addObserver:self forKeyPath:@"status" options:0 context:0];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
self.audioPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem];
[self.audioPlayer play];
}
- (void)initSoundPrelisten
{
//NSLog(@"begin: %s", __FUNCTION__);
self.activityIndicator.hidden = NO;
[self.activityIndicator startAnimating];
// verification delegate : register
dataProtocol = [[StoreConnection alloc] init];
[dataProtocol setDelegate:self];
[dataProtocol requestDataFromServer:[NSString stringWithFormat:@"sound/%@/audio/sample", [self.sound objectForKey:@"globalId"]]];
}
- (void)dataSuccessful:(BOOL)success successData:(NSMutableData *)data;
{
NSLog(@"%s", __FUNCTION__);
if (success) {
//NSLog(@"sound data: %@", data);
NSString *cacheDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [cacheDirectory stringByAppendingPathComponent:@"sample.mp3"];
//NSLog(@"filePath: %@", filePath);
[data writeToFile:filePath atomically:YES];
[self playSound:filePath];
} else
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Store Error" message:[NSString stringWithFormat:@"An Error occured while trying to download sound. Please try again"] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
alertView.tag = 1;
[alertView show];
}
}
Możesz użyć opcji inicjowania AVURLAssetHTTPHeaderFieldsKey
z AVURLAsset
, aby zmodyfikować nagłówki żądań.
Na przykład:
NSMutableDictionary * headers = [NSMutableDictionary dictionary];
[headers setObject:@"Your UA" forKey:@"User-Agent"];
AVURLAsset * asset = [AVURLAsset URLAssetWithURL:URL options:@{@"AVURLAssetHTTPHeaderFieldsKey" : headers}];
AVPlayerItem * item = [AVPlayerItem playerItemWithAsset:asset];
self.player = [[AVPlayer alloc] initWithPlayerItem:item];
Uwaga: znalazłem ten kluczyk źródeł WebKit, ale jest to klucz prywatny opcja, więc aplikacja może odrzucić przez AppStore jeśli to wykorzystać.
To jest dokładnie to, co robię. Czy ktoś może zweryfikować, czy aplikacja zostanie odrzucona przez Apple w związku z użyciem tego klucza? – mixtly87
@ mixtly87 czy wystąpił problem z przesłaniem aplikacji do sklepu AppStore za pomocą tego klucza? –
@JavierGonzalez Brak problemów. – mixtly87
Rozważ użycie AVURLAsset
. Dla AVURLAsset
można skonfigurować delegata resourceLoader. Wewnątrz metody delegatów możesz ręcznie wysłać żądanie, określając niezbędne nagłówki.
Zaleta tego podejścia polega na tym, że masz pełną kontrolę nad ładowaniem danych.
Musisz użyć własnego schematu URL w celu uczynienia tej pracy Solution (http i https nie wywoła metodę delegata!):
-(void) play {
NSURL * url = [URL URLWithString:@"mycustomscheme://tungsten.aaplimg.com/VOD/bipbop_adv_fmp4_example/master.m3u8"];
AVURLAsset * asset = [AVURLAsset URLAssetWithURL: options:nil];
[asset.resourceLoader setDelegate:self queue:dispatch_queue_create("TGLiveStreamController loader", nil)];
AVPlayerItem * playerItem = [AVPlayerItem playerItemWithAsset:asset];
// Use player item ...
...
}
#pragma mark - AVAssetResourceLoaderDelegate
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
dispatch_async(resourceLoader.delegateQueue, ^{
NSURL * url = [URL URLWithString:@"https://tungsten.aaplimg.com/VOD/bipbop_adv_fmp4_example/master.m3u8"];
NSMutableURLRequest *request = [loadingRequest.request mutableCopy];
request.URL = url;
// Add header
[request setValue:@"Foo" forHTTPHeaderField:@"Bar"];
NSURLResponse *response = nil;
NSError *firstError = nil;
// Issue request
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&firstError];
[loadingRequest.dataRequest respondWithData:data];
if (firstError) {
[loadingRequest finishLoadingWithError:firstError];
} else {
[loadingRequest finishLoading];
}
});
return YES;
}
Pełny przykład kodu jest dostępny na https://developer.apple.com/library/content/samplecode/sc1791/Introduction/Intro.html
To podejście zadziała, ale w moim doświadczeniu musisz przejąć na własność dostarczanie kawałków, itp. Do AVPlayera. Jedynym sposobem, w jaki mogłem to zrobić dla list odtwarzania ORAZ porcji żądań i odpowiedzi było uruchomienie odwrotnego proxy na urządzeniu. –
Spędziłem tygodnie szukając sposobu, aby zrobić to oficjalnie dla streamingu wideo HLS. Dla każdego, kto szuka podejścia, które będzie działać zarówno dla żądań, jak i odpowiedzi dla list odtwarzania i żądań kawałków, jedynym sposobem, jaki udało mi się znaleźć, było przekazanie żądania odtwarzania przez odwrotne proxy, dzięki czemu można przechwycić żądanie. , dodaj nagłówki, wyślij je do prawdziwego serwera, a następnie wyodrębnij nagłówki z odpowiedzi przed zwróceniem jej do odtwarzacza AVPlayer.
Zrobiłem prosty przykład projekt (z dużą ilością komentarzy i dokumentacją) tutaj: https://github.com/kevinjameshunt/AVPlayer-HTTP-Headers-Example
- 1. Problemy z odtwarzaniem muzyki w iOS AVPlayer
- 2. Zatrzymywanie AVPlayer na iOS
- 3. Czy można wysyłać niestandardowe nagłówki z żądaniem XHR ("Ajax")?
- 4. Wysyłaj dodatkowe nagłówki http za pomocą Express.JS
- 5. iOS - AVPlayer używający zamkniętych komend
- 6. iOS AVPlayer Play/Pause problem
- 7. iOS: Wstępne ładowanie wideo AVPlayer
- 8. Jak ustawić bufor AVPlayer pusty w ios
- 9. iOS 7 AVPlayer AVPlayerItem trwania niepoprawny w iOS 7
- 10. CORS post z żądaniem preflight
- 11. AVPlayer replaceCurrentItemWithPlayerItem nie działa na iOS 4.3.3+
- 12. iOS AVPlayer replaceCurrentItemWithPlayerItem: brak bloku UI Wątek
- 13. Metoda opcji HTTP z żądaniem JavaScriptu
- 14. Ionic 2/Angular 2/CORS: nagłówki HTTP nie są wysyłane z żądaniem
- 15. Przeciek pamięci w iOS, AVPlayer nigdy nie jest wycofywany
- 16. Pobierz postęp w pliku Node.js z żądaniem
- 17. Odmowa dostępu z żądaniem $ http w Angular i IE8
- 18. Wysyłaj żądanie XHR z rozszerzenia Chrome przy użyciu plików cookie.
- 19. AVPlayer z kontrolkami odtwarzania avplayerviewcontroller
- 20. Set-Cookie na przeglądarce z żądaniem Ajax za pośrednictwem CORS
- 21. Wysyłaj dane binarne z Androida w JavaScript
- 22. Wysyłanie informacji uwierzytelniania z żądaniem siatkówki
- 23. Klasyczny błąd ASP z żądaniem XMLHTTP
- 24. odtwarzanie AVPlayer nie jest aktywny podczas AVAssetExportSession jak iOS 10
- 25. Materiał kątowe nieskończone przewijanie z żądaniem $ http
- 26. PHP - Wysyłaj ciasteczko z file_get_contents
- 27. Backbone.js: wielokrotne usuwanie z jednym żądaniem
- 28. Wyłączyć odtwarzanie dźwięku w AVPlayer?
- 29. AVPlayer nie odtwarza wideo z adresu URL w iOS9
- 30. Jak zatrzymać wideo w AVPlayer?
+1 za całkowicie prawidłową odpowiedź. Aby rozwiązać ten problem z innej strony; nie masz bezpośredniego sposobu na zakłócanie komunikacji HTTP z "AVPlayer". – Till
Inną opcją, ale NAPRAWDĘ skomplikowaną, byłoby użycie na urządzeniu proxy - wersja robocza: zbuduj klienta, który żąda danych przez HTTP (na twoim urządzeniu), zbuduj serwer, który oferuje te dane przez HTTP (na twoim urządzeniu), pozwól AVPlayer połączyć się z lokalnym serwerem za pośrednictwem HTTP. Jak wspomniano, bardzo skomplikowane, ale czasami jedyną opcją - np. jeśli próbujesz odtwarzać treści z YouTube natywnie w swojej aplikacji. – Till
dzięki za to! działa idealnie! przegłosowane! – rockstarberlin