我正在使用AVFoundation框架进行直播播放。现在我有一个如下的播放列表
#EXT-X-VERSION:4
#EXT-X-ALLOW-CACHE:NO
#EXT-X-MEDIA-SEQUENCE:8148007
#EXT-X-TARGETDURATION:6
#EXT-X-PROGRAM-DATE-TIME:1972-04-14T08:51:01.497Z
我认为AVPlayer会请求获取此播放列表。我可以在AVFoundation中使用类来提取EXT-X-TARGETDURATION和EXT-X-PROGRAM-DATE-TIME。如果没有,还有其他方式吗?感谢
答案 0 :(得分:2)
#EXT-X-PROGRAM-DATE-TIME
可通过AVPlayerItem
的{{1}}媒体资源获取。它不会直接报告标签的日期,而是报告当前播放位置之前的最后一个标签的日期,以及此后的任何播放间隔。
currentDate
无法直接使用。您必须自己加载播放列表,或者在加载过程中插入自己。我在#EXT-X-TARGETDURATION
和AVAssetResourceLoader
取得了成功。您可以将URL方案重写为加载程序无法识别的内容(除http或https以外的任何内容),并代表播放器执行加载。
答案 1 :(得分:1)
I don't think AVFoundation provides access to all of those tags. However when I need to debug the streams, I use a custom NSURLProtocol to intercept all traffic. I think sometimes it's better to see the raw playlist and the HTTP response because AVPlayer does not give good error message(e.g. "The operation cannot be completed")
A good tutorial on NSURLProtocol can be found here: https://www.raywenderlich.com/59982/nsurlprotocol-tutorial
First let the url loading system know you can handle HLS request by calling [NSURLProtocol registerClass:/* your class */]
and override +(BOOL)canInitWithRequest:
+(BOOL)canInitWithRequest:(NSURLRequest *)request {
BOOL handled = [[NSURLProtocol propertyForKey:@"handled" inRequest:request] boolValue];
return [request.URL.pathExtension isEqualToString:@"m3u8"] && !handled;
}
Then override -(void)startLoading
in your custom URLProtocol
-(void)startLoading {
newRequest = [self.request mutableCopy];
[NSURLProtocol setProperty:@YES forKey:@"handled" inRequest:newRequest];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:newRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
/* Inspect response body(playlist) and error */
NSString *responseBody = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
/* Return data and control to AVPlayer*/
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[self.client URLProtocol:self didLoadData:data];
[self.client URLProtocolDidFinishLoading:self];
}];
[task resume];
}