m3u8文件AVAssetImageGenerator错误

17

我正在使用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 "操作无法完成" UserInfo=0x7fb4e30cbfa0 {NSUnderlyingError=0x7fb4e0e28530 "操作无法完成。 (OSStatus错误-12782。)",NSLocalizedFailureReason=发生未知错误(-12782),NSLocalizedDescription=操作无法完成}

它适用于mp4、mov和所有主要视频扩展名的URL,但不适用于m3u8。有任何想法吗?


mp 不是空的吗?你能分享资产吗? - Daij-Djan
还需要一点点你的代码... - Daij-Djan
1
请参见https://dev59.com/7Ynca4cB1Zd3GeqP9E7o。 - aergistal
已添加代码 @Daij-Djan - objectivecdeveloper
@objectivecdeveloper,这个问题你有什么进展吗?我现在也遇到了同样的需求,卡住了。 - dobleUber
你无法使用AVAssetImageGenerator获取直播流的静态图像。相反,你可以使用AVPlayerItemVideoOutput。通过AVPlayerItemVideoOutput,你可以使用以下方法获取适合在给定.m3u8流中指定时间显示的图像:
  • (CVPixelBufferRef)copyPixelBufferForItemTime:(CMTime)itemTime itemTimeForDisplay:(CMTime *)outItemTimeForDisplay
然后,你可以将返回的CVPixelBufferRef转换为图像(或其他形式)进行显示。
- objectivecdeveloper
3个回答

10

你遇到的问题是可以预料的。.m3u8文件并不是实际的资产文件,相反,它们更像是一个播放列表。它们用于HTTP Live Streaming,并根据可用带宽提供“分段”位置。

这里有一个.m3u8文件的示例(苹果的样本.m3u8文件

#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 Live流媒体中的媒体。 参考:苹果公司有关资源加载/播放的参考示例


3
同意,但如果我需要截图怎么办?你知道其他的方法吗? - objectivecdeveloper

7

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

AVPlayerItemVideoOutput

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


1
这总是返回 nil。你需要做些什么才能让它工作? - Shaked Sayag
@ShakedSayag 我知道这对你可能没有帮助,但为了后人着想,看起来在开始播放之前需要附加输出。此外,可以在此处找到代码示例: https://dev59.com/2FkS5IYBdhLWcg3ws4ck#39553034 - Elliot Schrock

0
我们的发现是,如果您播放一个具有“仅I帧播放列表”的HLS流,例如流“https://tungsten.aaplimg.com/VOD/bipbop_adv_example_v2/master.m3u8”(具有仅I帧播放列表),AVAssetImageGenerator可以逐个生成所请求的图像。
但请注意,“仅适用于iOS8.X和iOS9.X”,在iOS10.X上失败。
我已向Apple Bug Reporter提交了错误报告。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接