AVFoundation のAVAssetReader
クラスを使用して、ビデオ フレームを OpenGL ES テクスチャにアップロードすることができました。ただし、リモート メディアを指すと一緒に使用すると失敗するという点で注意が必要です。AVURLAsset
この失敗は十分に文書化されておらず、欠点を回避する方法があるかどうか疑問に思っています.
1 に答える
iOS 6 でリリースされたいくつかの API を使用して、プロセスを簡単にすることができました。まったく使用せずAVAssetReader
、代わりに というクラスに依存していAVPlayerItemVideoOutput
ます。このクラスのインスタンスはAVPlayerItem
、新しい-addOutput:
メソッドを介して任意のインスタンスに追加できます。
とは異なりAVAssetReader
、このクラスはAVPlayerItem
、リモートによってサポートされているに対して正常に機能し、(の厳しい制限メソッドの代わりに) をAVURLAsset
介した非線形再生をサポートする、より洗練された再生インターフェイスを可能にするという利点もあります。-copyPixelBufferForItemTime:itemTimeForDisplay:
AVAssetReader
-copyNextSampleBuffer
サンプルコード
// Initialize the AVFoundation state
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:someUrl options:nil];
[asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler:^{
NSError* error = nil;
AVKeyValueStatus status = [asset statusOfValueForKey:@"tracks" error:&error];
if (status == AVKeyValueStatusLoaded)
{
NSDictionary* settings = @{ (id)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] };
AVPlayerItemVideoOutput* output = [[[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:settings] autorelease];
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addOutput:[self playerItemOutput]];
AVPlayer* player = [AVPlayer playerWithPlayerItem:playerItem];
// Assume some instance variable exist here. You'll need them to control the
// playback of the video (via the AVPlayer), and to copy sample buffers (via the AVPlayerItemVideoOutput).
[self setPlayer:player];
[self setPlayerItem:playerItem];
[self setOutput:output];
}
else
{
NSLog(@"%@ Failed to load the tracks.", self);
}
}];
// Now at any later point in time, you can get a pixel buffer
// that corresponds to the current AVPlayer state like this:
CVPixelBufferRef buffer = [[self output] copyPixelBufferForItemTime:[[self playerItem] currentTime] itemTimeForDisplay:nil];
バッファーを取得したら、必要に応じて OpenGL にアップロードできます。CVOpenGLESTextureCacheCreateTextureFromImage()
すべての新しいデバイスでハードウェア アクセラレーションが得られるため、恐ろしく文書化された関数をお勧めしますglTexSubImage2D()
。例については、 Apple のGLCameraRippleとRosyWriterのデモを参照してください。