在iOS中发送包含AVPlayer请求的标头

使用AVPlayer时,是否可以将带有http请求的头文件发送到audio文件? 我需要能够检查服务器收到的头部内容,以限制对被请求的文件的访问。

您将需要通过通用的HTTP连接机制(如NSURLConnection请求数据。 如果NSHTTPURLResponse的头文件通过了你的testing,那么你应该把它保存到NSCachesDirectory ,并将这个资源的URL传递给AVPlayer如下所示:

 NSData *data = //your downloaded data. NSString *filePath = //generate random path under NSCachesDirectory [data writeToFile:filePath atomically:YES]; AVPlayer *player = [AVPlayer playerWithURL:[NSURL fileURLWithPath:filePath]]; //... 

您可以使用AVURLAssetHTTPHeaderFieldsKey的init选项的AVURLAsset来修改请求标头。

例如:

 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]; 

注意:我在WebKit的源代码中find了这个密钥,但这是一个私有的选项密钥,所以如果你使用这个密钥,你的应用可能会被AppStore拒绝。

我花了几个星期的时间寻找一种方法来正式为HLSvideostream。 对于任何寻找可以同时处理播放列表和大块请求请求和响应的方法的人来说,唯一能find的方法是通过反向代理传递播放请求,通过反向代理来拦截请求,添加标题,将其发送到真实的服务器,然后从响应中提取标题,然后将其返回到AVPlayer。

我做了一个简单的示例项目(有很多评论和文档): https : //github.com/kevinjameshunt/AVPlayer-HTTP-Headers-Example

考虑使用AVURLAsset 。 对于AVURLAsset你可以设置一个resourceLoader委托。 在委托方法内部,您可以手动发出一个请求来指定必要的标题。

这种方法的好处是您可以完全控制数据加载。

您必须使用自定义urlscheme才能使此解决scheme工作(http和https不会触发委托方法!):

 -(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; } 

完整的代码示例可在https://developer.apple.com/library/content/samplecode/sc1791/Introduction/Intro.html

完整的代码可能看起来像这样

  #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]; } }