ファイル (カメラ ストリームではない) から読み込まれたビデオのフレームを処理しようとしています。
そのために、ビデオをロードしました (現在、バンドルにあるテスト mp4 ですが、これを外部 URL にする予定です)。
AVFoundation に関する多くのドキュメントとチュートリアルを読み、さまざまな提案を見つけましたが、どれもうまくいきませんでした。私が望んでいたのは、フレームが変更されたときにデリゲート メソッドまたは通知を見つけることでしたが、これらは実際には存在しないと思います (おそらく、フレーム ストリームを処理するには遅すぎるため)。
これが私がこれまでに持っているものです。ビデオ ストリームから画像がレンダリングされるたびに [self doImageProcess:] セレクターを実行する必要があります。これはどのように行うことができますか?
(これが正しく機能したら、完全に機能するコードを投稿します)
#import <AVFoundation/AVFoundation.h>
@implementation VTViewController
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
// load mp4
NSURL *theURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"video" ofType:@"mp4"]];
AVAsset *avAsset = [AVAsset assetWithURL:theURL];
AVPlayerItem *avPlayerItem =[[AVPlayerItem alloc] initWithAsset:avAsset];
avPlayer = [[AVPlayer alloc] initWithPlayerItem:avPlayerItem];
CMTime interval = CMTimeMake(33, 1000); // 30fps
id playbackObserver = [avPlayer addPeriodicTimeObserverForInterval:interval queue:nil usingBlock: ^(CMTime time) {
// get image
[self doImageProcess:nil];
}];
img1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 480, 320)];
[self.view addSubview:img1];
avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:avPlayer];
[avPlayerLayer setFrame:CGRectMake(0, 0, 480, 320)];//self.view.frame];
[self.view.layer addSublayer:avPlayerLayer];
[avPlayer seekToTime:kCMTimeZero];
[avPlayer play];
}
- (void)doImageProcess:(UIImage *)theImage {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, 1.0, 1.0);
[avPlayerLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[arrImages addObject:img];
[img1 removeFromSuperview];
img1 = nil;
img1 = [[UIImageView alloc] initWithImage:img];
[self.view addSubview:img1];
if ([arrImages count] > 4)
[arrImages removeObjectAtIndex:0];
}