Ale*_*der 8 avfoundation ios avplayer ios7
我正在实施一个AVAssetResourceLoaderDelegate,而且我在行动方面遇到了一些麻烦.我的目标是拦截AVPlayer发出的任何请求,自己发出请求,将数据写入文件,然后AVPlayer用文件数据响应.
我看到的问题:我可以拦截第一个请求,它只需要两个字节,然后响应它.在那之后,我没有得到任何更多请求打我的AVAssetResourceLoaderDelegate.
当我拦截第一个AVAssetResourceLoadingRequest从AVPlayer它看起来像这样:
<AVAssetResourceLoadingRequest: 0x17ff9e40,
URL request = <NSMutableURLRequest: 0x17f445a0> { URL: fakeHttp://blah.com/blah/blah.mp3 },
request ID = 1,
content information request = <AVAssetResourceLoadingContentInformationRequest: 0x17ff9f30,
content type = "(null)",
content length = 0,
byte range access supported = NO,
disk caching permitted = NO>,
data request = <AVAssetResourceLoadingDataRequest: 0x17e0d220,
requested offset = 0,
requested length = 2,
current offset = 0>>
Run Code Online (Sandbox Code Playgroud)
如您所见,这只是对前两个字节数据的请求.我正在fakeHttp使用URL中的协议,将其替换为just http,并自己发出请求.
然后,这里是我有一些数据后如何响应请求:
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
//Make the remote URL request here if needed, omitted
CFStringRef contentType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)([self.response MIMEType]), NULL);
loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
loadingRequest.contentInformationRequest.contentType = CFBridgingRelease(contentType);
loadingRequest.contentInformationRequest.contentLength = [self.response expectedContentLength];
//Where responseData is the appropriate NSData to respond with
[loadingRequest.dataRequest respondWithData:responseData];
[loadingRequest finishLoading];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
我已经逐步完成了这一点,并验证了所有内容contentInformationRequest都已正确填写,并且我发送的数据是具有适当长度的NSData(在本例中为两个字节).
没有更多的请求被发送给我的代表,并且播放器不播放(大概是因为它只有两个字节的数据,并且还没有再请求).
有没有人有这方面的经验指出我可能做错事的地方?我正在运行iOS 7.
编辑: 在我打电话之后,这是我完成的请求的样子finishedLoading:
<AVAssetResourceLoadingRequest: 0x16785680,
URL request = <NSMutableURLRequest: 0x166f4e90> { URL: fakeHttp://blah.com/blah/blah.mp3 },
request ID = 1,
content information request = <AVAssetResourceLoadingContentInformationRequest: 0x1788ee20,
content type = "public.mp3",
content length = 7695463,
byte range access supported = YES,
disk caching permitted = NO>,
data request = <AVAssetResourceLoadingDataRequest: 0x1788ee60,
requested offset = 0,
requested length = 2,
current offset = 2>>
Run Code Online (Sandbox Code Playgroud)
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
{
loadingRequest.contentInformationRequest.contentType = @"public.aac-audio";
loadingRequest.contentInformationRequest.contentLength = [self.fileData length];
loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
NSData *requestedData = [self.fileData subdataWithRange:NSMakeRange((NSUInteger)loadingRequest.dataRequest.requestedOffset,
(NSUInteger)loadingRequest.dataRequest.requestedLength)];
[loadingRequest.dataRequest respondWithData:requestedData];
[loadingRequest finishLoading];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
这个实现对我有用.它总是要求前两个字节,然后是整个数据.如果你没有得到另一个回调,则表示你所做的第一个回复出现了问题.我想问题是你使用的是MIME内容类型而不是UTI.
如果有人好奇的话,回过头来回答我自己的问题.
问题归结为线程化.虽然它没有在任何地方明确记录,AVAssetResourceLoaderDelegate但有一些奇怪的东西与线程.
本质上,我的问题是我在主线程上创建AVPlayerItem和AVAssetResourceLoaderDelegate,但在后台线程上响应委托调用(因为它们是网络调用的结果).显然,AVAssetResourceLoader完全忽略了与预期不同的线程中出现的响应.
我通过AVPlayerItem在同一个线程上执行所有操作(包括创建)来解决这个问题.
| 归档时间: |
|
| 查看次数: |
4777 次 |
| 最近记录: |