是否有可能使用AVPlayer时发送一个HTTP请求头的音频文件? 我需要能够检查标头的内容,以限制被请求访问文件服务器接收的时候。
Answer 1:
你需要通过一个普通的HTTP连接机制,如对自己请求数据NSURLConnection
。 如果NSHTTPURLResponse
的头通过测试,那么你应该将其保存到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]];
//...
Answer 2:
您可以使用AVURLAssetHTTPHeaderFieldsKey
的AVURLAsset
的init选项来修改请求头。
例如:
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的来源这个关键,但是这是一个私人的选择键,因此,如果您使用这个你的应用程序可以通过AppStore的拒绝。
Answer 3:
我花了几周时间寻找一种方式来为HLS视频流做正式。 为寻找一种方法,将用于播放列表和块体请求请求和响应工作,我能找到工作的唯一方法是通过将回放请求通过反向代理服务器,以使您可以拦截请求,添加标题,将其发送到真实服务器,然后将其返回到AVPlayer之前提取的响应头。
我做了一个简单的例子项目(带有大量的注释和文档)位置: https://github.com/kevinjameshunt/AVPlayer-HTTP-Headers-Example
Answer 4:
考虑使用AVURLAsset
。 对于AVURLAsset
可以设置个资源委托。 里面的委托方法,你可以手动发出的请求指定必要的标头。
这种方法的好处是,你必须对数据加载一个完整的控制。
你必须为了使这个解决方案工作中使用自定义URL方案(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
Answer 5:
答斯威夫特,AVURLAssetHTTPHeaderFieldsKey选项将工作就像一个魅力。
let headers: HTTPHeaders = [
"custome_header": "custome value"
]
let asset = AVURLAsset(url: URL, options: ["AVURLAssetHTTPHeaderFieldsKey": headers])
let playerItem = AVPlayerItem(asset: asset)
player = AVPlayer(playerItem: item)
Answer 6:
完整的代码看起来是这样的
#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];
}
}