Iphone 使用AvasseTrader从远程资源读取(流)
我的主要目标是从服务器流式传输视频,并在流式传输时逐帧剪切视频(以便OpenGL可以使用它)。为此,我使用了在互联网上随处可见的代码(我记得它来自苹果的GLVideoFrame示例代码): 但是我总是在Iphone 使用AvasseTrader从远程资源读取(流),iphone,objective-c,ios,video-streaming,avfoundation,Iphone,Objective C,Ios,Video Streaming,Avfoundation,我的主要目标是从服务器流式传输视频,并在流式传输时逐帧剪切视频(以便OpenGL可以使用它)。为此,我使用了在互联网上随处可见的代码(我记得它来自苹果的GLVideoFrame示例代码): 但是我总是在[[Avassetrader alloc]initWithAsset:error://上得到这个异常 NSInvalidArgumentException -- *** -[AVAssetReader initWithAsset:error:] Cannot initialize an insta
[[Avassetrader alloc]initWithAsset:error://上得到这个异常
NSInvalidArgumentException -- *** -[AVAssetReader initWithAsset:error:] Cannot initialize an instance of AVAssetReader with an asset at non-local URL 'http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8'
所以我的两个问题是:
异常是否真的告诉我,avassetrader
必须有一个本地URL?它可以用于流媒体吗(就像其他AVFoundation
类一样)
如果AVFoundation
方法不起作用,还有什么其他建议可以同时对视频流和帧进行分割
非常感谢您的帮助。与所使用的文件或协议的种类相比,AVFoundation似乎并不能区分本地文件和非本地文件。使用mp4/mov与通过m3u8使用HTTP实时流媒体协议之间有着非常明显的区别,但使用本地或远程mp4的区别有点模糊
要扩展上述内容,请执行以下操作:
a) 如果您的“远程”资产是一个M3U8(也就是说,您正在使用HTTP“实时”流媒体),那么没有任何机会。无论M3U8是在本地文件系统中还是在远程服务器上,由于多种原因,Avassetrader和所有与AVAsset相关的功能都无法工作<代码>但是,AVPlayer、AVPlayerItem等可以正常工作。
b) 如果是MP4/MOV,则需要进一步调查<代码>本地MP4/MOV的工作完美无瑕。在远程MP4/MOV的情况下,我能够创建(或从AVPlayerItem、AVPlayer或AVAssetTracks中检索)一个AVURLAsset,有时我可以使用它成功初始化Avassetrader(我也将在“有时”上展开,很快)。但是,在远程MP4的情况下,copyNextSampleBuffer始终返回nil。由于在调用copyNextSampleBuffer之前有几件事是有效的,因此我不能100%确定:
i) 在所有其他步骤成功后,copyNextSampleBuffer不适用于远程mp4,这是预期/预期的功能
ii)远程MP4的“其他步骤”似乎完全起作用,这是苹果实施的一个意外,当我们点击copyNextSampleBuffer时,这种不兼容性就凸显了出来…………这些“其他步骤”是什么,我将很快详细介绍
iii)尝试为远程MP4调用copyNextSampleBuffer时出错
所以@Paula你可以试着用远程MOV/MP4做进一步的调查
以下是我尝试从视频中捕获帧的方法供参考:
(a)
直接从视频URL创建AVURLAsset
使用[asset Tracks SwithMediaType:AVMediaTypeVideo]检索视频曲目
使用视频曲目作为源,准备AvasseTraderTrack输出
使用AVURLAsset创建AvasseTrader
将AVAssetReaderTrackOutput添加到AVAssetReader并开始踩踏
使用copyNextSampleBuffer检索图像
(b)
从视频URL创建AVPlayerItem,然后从中创建AVPlayer(或直接从URL创建AVPlayer)
检索AVPlayer的“资产”属性,并使用“LoadValuesAsSynchronousLyForkeys:”加载其“曲目”
分离AVMediaTypeVideo类型的曲目(或在加载曲目后在资源上调用tracksWithMediaType:即可),并使用视频曲目创建AvasseTraderTrackOutput
使用AVPlayer的“资源”、“startReading”创建AvasseTrader,然后使用copyNextSampleBuffer检索图像
(c)
直接从视频URL创建AVPlayerItem+AVPlayer或AVPlayer
KVO AVPlayerItem的“tracks”属性,加载曲目后,分离AVMediaTypeVideo类型的AVAssetTracks
从AVPlayerItem/AVPlayer/AVAssetTrack的“资产”属性检索AVAsset
其余步骤与方法(b)类似
(d)
直接从视频URL创建AVPlayerItem+AVPlayer或AVPlayer
KVO AVPlayerItem的“tracks”属性,加载曲目后,将AVMediaTypeVideo类型的曲目分开
创建AVMutableComposition,并初始化AVMediaTypeVideo类型的关联AVMutableCompositionTrack
将先前检索到的视频曲目中的相应CMTimeRange插入此AVMutableCompositionTrack
与(b)和(c)类似,现在创建AvasseTrader和AvasseTraderTrackOutput,但不同之处在于使用AVMutableComposition作为初始化AvasseTrader的基础AVAsset,使用AVMutableCompositionTrack作为AvasseTraderTrackOutput的基础AVAssetTrack
“startReading”并使用copyNextSampleBuffer从AvasseTrader获取帧
附言:我在这里尝试了方法(d)来回避这样一个事实,即直接从AVPlayerItem或AVPlayer检索的AVAsset没有运行。因此,我想从我手中已有的Avassetracks中创建一个新的AVAsset。诚然,这本书很粗糙,而且可能毫无意义(如果不是原始的AVAsset,那么最终还能从哪里检索到曲目信息呢!),但无论如何,这本书还是值得一试。
以下是不同类型文件的结果摘要:
1) 本地MOV/MP4-所有4种方法都能完美工作
2) 远程MOV/MP4–在进近(b)到(d)中正确检索资产和轨迹,并且Avassetrader也已初始化,但copyNextSampleBuffer始终返回零。中科院
NSInvalidArgumentException -- *** -[AVAssetReader initWithAsset:error:] Cannot initialize an instance of AVAssetReader with an asset at non-local URL 'http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8'
AVURLAsset* soundTrackAsset = [[AVURLAsset alloc]initWithURL:[NSURL URLWithString:@"http://www.yoururl.com/yourfile.mp3"] options:nil];
AVMutableCompositionTrack *compositionAudioSoundTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioSoundTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
ofTrack:[[soundTrackAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
atTime:kCMTimeZero error:nil];