m3u8 文件 AVAssetImageGenerator 错误

m3u8 file AVAssetImageGenerator error

我正在使用 AVPlayer 播放 .m3u8 文件。 使用 AVAssetImageGenerator 使用以下代码从中提取图像:

AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:mp.contentURL options:nil];
AVAssetImageGenerator *generate1 = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generate1.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 2);
CGImageRef oneRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err];
img = [[UIImage alloc] initWithCGImage:oneRef];

它总是给我错误:

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x7fb4e30cbfa0 {NSUnderlyingError=0x7fb4e0e28530 "The operation couldn’t be completed. (OSStatus error -12782.)", NSLocalizedFailureReason=An unknown error occurred (-12782), NSLocalizedDescription=The operation could not be completed}

它适用于 mp4、mov 和所有主要视频扩展 URL 但不适用于 m3u8。有什么想法吗??

你的问题是意料之中的。 .m3u8 文件不是实际的资产文件,而是更类似于播放列表。它们用于 HTTP 实时流式传输,并根据可用带宽为 "Segments" 提供位置。

这里是 .m3u8 文件的示例 (Apple's sample .m3u8 file)

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000
gear1/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111
gear2/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444
gear3/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=737777
gear4/prog_index.m3u8

遗憾的是,您无法创建 AVAsset 或 AVURLAsset 来表示 HTTP 直播流中的媒体。参考:Apple's reference example of Asset Loading/playing

您将无法使用 AVAssetImageGenerator 获取实时流的静态图像。相反,您可以使用

AVPlayerItemVideoOutput

使用 AVPlayerItemVideoOutput,您可以使用以下方法为给定的 .m3u8 流获取适合在指定时间显示的图像:- (CVPixelBufferRef)copyPixelBufferForItemTime:(CMTime)itemTime itemTimeForDisplay:(CMTime *)outItemTimeForDisplay然后,您可以将返回的 CVPixelBufferRef 转换为图像(或其他)用于展示。

我们的发现是,如果您播放具有 "I-Frame only playlist" 的 HLS 流,例如流“https://tungsten.aaplimg.com/VOD/bipbop_adv_example_v2/master.m3u8”(只有 I-frame 播放列表),AVAssetImageGenerator 可以生成所请求的一张一张的图。

但请注意 "it is only fine on iOS8.X and iOS9.X",但在 iOS10.X 失败。

我已向 Apple Bug Reporter 提交错误报告。