1

ファイル (カメラ ストリームではない) から読み込まれたビデオのフレームを処理しようとしています。

そのために、ビデオをロードしました (現在、バンドルにあるテスト 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];

}
4

1 に答える 1

1

addPeriodicTimeObserverForInterval:queue:usingBlock:方法AVPlayerが役立つ場合があります。再生の特定の時間間隔でコードのブロックを実行できます。

于 2013-10-03T20:25:39.397 に答える