如何从播放列表

时间:2016-04-14 09:59:37

标签: ios objective-c swift avplayer hls

我正在使用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。如果没有,还有其他方式吗?感谢

2 个答案:

答案 0 :(得分:2)

#EXT-X-PROGRAM-DATE-TIME可通过AVPlayerItem的{​​{1}}媒体资源获取。它不会直接报告标签的日期,而是报告当前播放位置之前的最后一个标签的日期,以及此后的任何播放间隔。

currentDate无法直接使用。您必须自己加载播放列表,或者在加载过程中插入自己。我在#EXT-X-TARGETDURATIONAVAssetResourceLoader取得了成功。您可以将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];
}